Skip to main content

Trigger Nodes

Trigger nodes are the starting point of every n8n workflow. They define when and how a workflow begins execution. Understanding the different trigger types is essential for building effective automation.

Trigger Types Overview

Webhook Triggers

Instant execution when external service calls your URL

Polling Triggers

Periodic checks for new data or changes

Schedule Triggers

Time-based execution on a schedule

Webhook Triggers

Webhook triggers create HTTP endpoints that external services can call to start your workflow instantly. They are event-driven and execute immediately when triggered.

How Webhooks Work

Architecture:
External Service → HTTP POST → Webhook URL → Workflow Execution
Key Concepts:
  • Test URL - Used during workflow development
  • Production URL - Used when workflow is active
  • Webhook Methods - Lifecycle management (create, check, delete)
  • Authentication - Built-in security options
When to Use:
  • Real-time event processing
  • Third-party service integrations
  • Form submissions
  • API endpoints
  • IoT device events

Service-Specific Webhook Triggers

Many integrations provide dedicated webhook triggers with automatic registration:
Webhook Events:
  • Push events
  • Pull requests
  • Issues
  • Releases
  • Branch/tag creation
Automatic Setup:
  • Creates webhook in GitHub automatically
  • Handles secret validation
  • Cleans up on workflow deactivation
Configuration:
{
  "owner": "myorg",
  "repository": "myrepo",
  "events": ["push", "pull_request"]
}
Implementation Note: Uses webhookMethods for lifecycle management:
  • checkExists() - Verify webhook
  • create() - Register webhook
  • delete() - Remove webhook
Event Types:
  • New messages
  • Reactions added
  • User mentions
  • Channel updates
  • File shared
Setup Requirements:
  1. Create Slack App
  2. Enable Event Subscriptions
  3. Add webhook URL
  4. Subscribe to bot events
Configuration:
{
  "event": "message",
  "channel": "#general",
  "resolve": "user"  // Resolve user IDs to objects
}
Webhook Events:
  • Payment succeeded
  • Customer created
  • Subscription updated
  • Invoice paid
  • Charge refunded
Automatic Registration:
  • Creates endpoint in Stripe
  • Validates webhook signatures
  • Handles event types
Configuration:
{
  "events": [
    "payment_intent.succeeded",
    "customer.subscription.created"
  ]
}
Event Types:
  • Channel messages
  • Team updates
  • Meeting scheduled
Implementation:
webhookMethods = {
  default: {
    async checkExists(this: IHookFunctions) {
      // Check if webhook exists
    },
    async create(this: IHookFunctions) {
      // Create subscription
    },
    async delete(this: IHookFunctions) {
      // Delete subscription
    },
  },
};
Webhook Topics:
  • Order created
  • Order updated
  • Product created
  • Customer created
Auto-configuration:
  • Registers webhook via WooCommerce API
  • Sets delivery URL
  • Configures topic and secret

Webhook Node Implementation

The core Webhook node provides maximum flexibility:
webhook(this: IWebhookFunctions) {
  const req = this.getRequestObject();
  const resp = this.getResponseObject();
  const mode = this.getMode() === 'manual' ? 'test' : 'production';
  
  // Process incoming data
  const body = req.body;
  const headers = req.headers;
  const query = req.query;
  
  // Return data to workflow
  return {
    workflowData: [
      this.helpers.returnJsonArray(body)
    ]
  };
}

Polling Triggers

Polling triggers periodically check external services for new data or changes. They execute at regular intervals and trigger workflows when new items are detected.

How Polling Works

Execution Flow:
Schedule Check → API Request → Compare with Last State → Trigger if Changed
State Management:
async poll(this: IPollFunctions) {
  const pollData = this.getWorkflowStaticData('node');
  const lastCheck = pollData.lastItemDate || new Date(0);
  
  // Fetch new items
  const newItems = await fetchNewItems(lastCheck);
  
  if (newItems.length > 0) {
    // Update state
    pollData.lastItemDate = newItems[0].date;
    
    // Return new items
    return [this.helpers.returnJsonArray(newItems)];
  }
  
  return null;  // No new items
}
Key Concepts:
  • Uses polling: true in node description
  • Implements poll() function
  • Stores state in workflow static data
  • Returns null when no new data

Common Polling Triggers

Implementation:
polling: true

async poll(this: IPollFunctions) {
  const pollData = this.getWorkflowStaticData('node');
  const feedUrl = this.getNodeParameter('feedUrl') as string;
  
  const lastDate = pollData.lastItemDate || new Date(0);
  const parser = new Parser();
  const feed = await parser.parseURL(feedUrl);
  
  // Filter new items
  const newItems = feed.items.filter(item => 
    new Date(item.isoDate) > new Date(lastDate)
  );
  
  if (newItems.length > 0) {
    pollData.lastItemDate = newItems[0].isoDate;
    return [this.helpers.returnJsonArray(newItems)];
  }
  
  return null;
}
Use Cases:
  • Blog updates
  • News feeds
  • Podcast episodes
  • Content aggregation
Trigger Events:
  • Row added
  • Row updated
  • Row added or updated
Implementation:
polling: true

async poll(this: IPollFunctions) {
  const documentId = this.getNodeParameter('documentId', '', { extractValue: true });
  const sheetName = this.getNodeParameter('sheetName', '', { extractValue: true });
  const event = this.getNodeParameter('event');
  
  const pollData = this.getWorkflowStaticData('node');
  
  // Get current sheet revision
  const currentRevision = await getRevisionFile(documentId);
  const lastRevision = pollData.lastRevision;
  
  if (lastRevision !== currentRevision) {
    // Compare changes
    const changes = compareRevisions(lastRevision, currentRevision);
    pollData.lastRevision = currentRevision;
    
    return [this.helpers.returnJsonArray(changes)];
  }
  
  return null;
}
Features:
  • Revision-based detection
  • Row-level change tracking
  • Handles updates and additions
Configuration:
{
  "event": "messageReceived",
  "filters": {
    "from": "notifications@service.com",
    "subject": "Alert:",
    "includeAttachments": true
  },
  "labelIds": ["INBOX"]
}
State Management:
  • Tracks last message ID
  • Handles pagination
  • Processes attachments
Use Cases:
  • Email automation
  • Attachment processing
  • Notification routing
SOQL Query Polling:
SELECT Id, Name, Email, CreatedDate
FROM Lead
WHERE CreatedDate > :lastCheck
ORDER BY CreatedDate DESC
Implementation:
async poll(this: IPollFunctions) {
  const pollData = this.getWorkflowStaticData('node');
  const lastCheck = pollData.lastCheck || new Date(Date.now() - 24 * 60 * 60 * 1000);
  
  const query = `SELECT * FROM Lead WHERE CreatedDate > ${lastCheck.toISOString()}`;
  const results = await salesforceApi.query(query);
  
  if (results.records.length > 0) {
    pollData.lastCheck = new Date();
    return [this.helpers.returnJsonArray(results.records)];
  }
  
  return null;
}
Polling Configuration:
{
  "base": "appXXXXXXXXXXXXXX",
  "table": "Tasks",
  "triggerField": "Last Modified",
  "pollInterval": 300000  // 5 minutes
}
Features:
  • Field-based change detection
  • View-specific polling
  • Formula field support
Database Polling:
async poll(this: IPollFunctions) {
  const databaseId = this.getNodeParameter('databaseId');
  const pollData = this.getWorkflowStaticData('node');
  
  // Query database with last_edited_time filter
  const response = await notion.databases.query({
    database_id: databaseId,
    filter: {
      timestamp: 'last_edited_time',
      last_edited_time: {
        after: pollData.lastEditedTime || new Date(0)
      }
    }
  });
  
  if (response.results.length > 0) {
    pollData.lastEditedTime = new Date();
    return [this.helpers.returnJsonArray(response.results)];
  }
  
  return null;
}

Schedule Triggers

Schedule triggers execute workflows based on time patterns - perfect for recurring tasks and maintenance operations.

Schedule Trigger Node

Schedule Types:
  • Simple Intervals - Seconds, minutes, hours, days, weeks, months
  • Specific Times - Daily at specific hour
  • Day of Week - Weekly schedules
  • Custom Cron - Advanced patterns
Features:
  • Multiple schedules per trigger
  • Timezone support
  • Between times constraints
  • Complex recurrence rules
Implementation:
async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {
  const triggerTimes = this.getNodeParameter('rule');
  
  const expressions = triggerTimes.interval.map(toCronExpression);
  
  const executeTrigger = () => {
    this.emit([this.helpers.returnJsonArray([{}])]);
  };
  
  expressions.forEach(expression => 
    this.helpers.registerCron({ expression }, executeTrigger)
  );
  
  return {
    manualTriggerFunction: async () => executeTrigger()
  };
}

Common Schedule Patterns

Daily at 2 AM:
{
  "rule": {
    "interval": [
      {
        "field": "days",
        "daysInterval": 1,
        "triggerAtHour": 2,
        "triggerAtMinute": 0
      }
    ]
  }
}
Use Case: Database backups, data exports, cleanup tasks
Weekly on Sunday at 11 PM:
{
  "rule": {
    "interval": [
      {
        "field": "weeks",
        "weeksInterval": 1,
        "triggerAtDay": [0],  // Sunday
        "triggerAtHour": 23,
        "triggerAtMinute": 0
      }
    ]
  }
}
Use Case: Weekly reports, analytics summaries, invoicing
Every 5 Minutes:
{
  "rule": {
    "interval": [
      {
        "field": "minutes",
        "minutesInterval": 5
      }
    ]
  }
}
Use Case: Service health checks, API monitoring, uptime tracking
First Monday of Every Month:
0 0 8 1-7 * 1
Use Case: Monthly cleanups, license checks, subscription renewals

Manual Triggers

Some triggers support manual execution for testing:

Manual Trigger Node

Purpose:
  • Canvas-based testing
  • Manual workflow execution
  • Development and debugging
Implementation:
async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {
  const executeTrigger = () => {
    this.emit([this.helpers.returnJsonArray([{ manual: true }])]);
  };
  
  return {
    manualTriggerFunction: async () => executeTrigger()
  };
}
Features:
  • Instant execution from canvas
  • No external dependencies
  • Sample data generation

Generic Trigger Interface

Some nodes implement custom trigger logic:
Generic Trigger Implementation:
async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {
  const protocol = this.getNodeParameter('protocol');
  const host = this.getNodeParameter('host');
  const port = this.getNodeParameter('port');
  const topics = this.getNodeParameter('topics');
  
  const client = mqtt.connect(`${protocol}://${host}:${port}`);
  
  client.on('connect', () => {
    topics.forEach(topic => client.subscribe(topic));
  });
  
  client.on('message', (topic, message) => {
    this.emit([this.helpers.returnJsonArray([{
      topic,
      message: message.toString()
    }])]);
  });
  
  async function closeFunction() {
    client.end();
  }
  
  return {
    closeFunction
  };
}
Use Cases:
  • Message queue subscriptions
  • WebSocket connections
  • Database change streams
  • Custom event listeners
Subscribe to Pub/Sub:
async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {
  const channels = this.getNodeParameter('channels');
  
  const subscriber = redis.createClient();
  await subscriber.connect();
  
  await subscriber.subscribe(channels, (message, channel) => {
    this.emit([this.helpers.returnJsonArray([{
      channel,
      message: JSON.parse(message)
    }])]);
  });
  
  return {
    closeFunction: async () => subscriber.quit()
  };
}

Choosing the Right Trigger

RequirementTrigger Type
Real-time events from external serviceWebhook
Check for new emails/messagesPolling
Run on a scheduleSchedule
Manual testingManual
Database change streamsGeneric (custom)
Message queueGeneric (custom)
Form submissionsWebhook
RSS/Feed monitoringPolling (RSS)
Time-based reportsSchedule
Service supports webhooksWebhook

Next Steps

Action Nodes

Learn about data processing and transformation nodes

Popular Nodes

Explore commonly used integrations

Build Workflows

Create your first automated workflow

Webhook Guide

Deep dive into webhook configuration