3 Triggers
x edited this page 2026-02-26 23:11:50 +00:00

Triggers

Triggers allow you to automatically execute actions when specific events occur in a collection. Triggers can make HTTP requests to external services when records are created, updated, or deleted.

Understanding Triggers

Triggers are configured at the collection level and automatically fire when:

  • A new record is created
  • An existing record is updated
  • A record is deleted

Triggers send HTTP requests (webhooks) to configured URLs with event details.

Configuring Triggers

Creating a Collection with Triggers

await adminClient.settings.collections.create({
  name: "notifications",
  type: "base",
  fields: [
    { name: "title", type: "text", required: true },
    { name: "message", type: "text" },
    {
      name: "status",
      type: "select",
      options: { values: ["active", "inactive"] },
    },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "https://api.example.com/webhook",
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Webhook-Source": "vski",
        },
      },
      {
        action: "update",
        url: "https://api.example.com/webhook",
        method: "PATCH",
      },
      {
        action: "delete",
        url: "https://api.example.com/webhook",
        method: "DELETE",
      },
    ],
  },
});

Trigger Types

Create Trigger

Fires when a new record is created:

{
  action: "create",
  url: "https://api.example.com/new-record",
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer your-token",
  },
}

Update Trigger

Fires when a record is updated:

{
  action: "update",
  url: "https://api.example.com/updated-record",
  method: "PATCH",
}

Delete Trigger

Fires when a record is deleted:

{
  action: "delete",
  url: "https://api.example.com/deleted-record",
  method: "DELETE",
}

Trigger Payload

When a trigger fires, it sends a JSON payload to the configured URL:

{
  "database": "default",
  "collection": "notifications",
  "id": "record-id-123",
  "action": "create",
  "timestamp": "2024-01-01T00:00:00Z",
  "record": {
    "id": "record-id-123",
    "title": "New Notification",
    "message": "Hello World",
    "status": "active",
    "created": "2024-01-01T00:00:00Z",
    "updated": "2024-01-01T00:00:00Z"
  }
}

Practical Examples

Slack Notifications

await adminClient.settings.collections.create({
  name: "alerts",
  type: "base",
  fields: [
    {
      name: "severity",
      type: "select",
      options: { values: ["low", "medium", "high", "critical"] },
    },
    { name: "message", type: "text", required: true },
    { name: "source", type: "text" },
  ],
  options: JSON.stringify({
    triggers: [
      {
        action: "create",
        url: "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
      },
    ],
  }),
});

The Slack webhook would receive:

{
  "text": "New Alert: Critical - Server down"
}

Email Notifications

await adminClient.settings.collections.create({
  name: "contact_submissions",
  type: "base",
  fields: [
    { name: "name", type: "text", required: true },
    { name: "email", type: "email", required: true },
    { name: "message", type: "text", required: true },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "https://email-service.com/send",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${EMAIL_API_KEY}`,
          "Content-Type": "application/json",
        },
      },
    ],
  },
});

Audit Logging

await adminClient.settings.collections.create({
  name: "users",
  type: "auth",
  fields: [
    { name: "email", type: "email", required: true },
    { name: "password", type: "text", required: true },
    { name: "name", type: "text" },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "https://audit-log.example.com/entry",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${AUDIT_TOKEN}`,
        },
      },
      {
        action: "update",
        url: "https://audit-log.example.com/entry",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${AUDIT_TOKEN}`,
        },
      },
      {
        action: "delete",
        url: "https://audit-log.example.com/entry",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${AUDIT_TOKEN}`,
        },
      },
    ],
  },
});

Third-Party Integration

// Integration with CRM
await adminClient.settings.collections.create({
  name: "leads",
  type: "base",
  fields: [
    { name: "name", type: "text", required: true },
    { name: "email", type: "email", required: true },
    { name: "company", type: "text" },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "https://crm.example.com/api/leads",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${CRM_API_KEY}`,
          "Content-Type": "application/json",
        },
      },
    ],
  },
});

// Integration with Analytics
await adminClient.settings.collections.create({
  name: "events",
  type: "base",
  fields: [
    { name: "eventName", type: "text", required: true },
    { name: "userId", type: "text" },
    { name: "properties", type: "json" },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "https://analytics.example.com/track",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${ANALYTICS_KEY}`,
        },
      },
    ],
  },
});

Workflow Triggers

// Trigger workflow when order is created
await adminClient.settings.collections.create({
  name: "orders",
  type: "base",
  fields: [
    { name: "customerId", type: "text", required: true },
    { name: "items", type: "json", required: true },
    { name: "total", type: "number", required: true },
    {
      name: "status",
      type: "select",
      options: { values: ["pending", "processing", "shipped", "delivered"] },
    },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "http://localhost:3000/api/workflows/runs",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${WORKFLOW_API_KEY}`,
          "Content-Type": "application/json",
        },
      },
    ],
  },
});

Data Synchronization

// Sync to external database
await adminClient.settings.collections.create({
  name: "products",
  type: "base",
  fields: [
    { name: "sku", type: "text", required: true },
    { name: "name", type: "text", required: true },
    { name: "price", type: "number", required: true },
    { name: "stock", type: "number" },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "https://external-db.example.com/sync",
        method: "POST",
        headers: {
          "Authorization": `Bearer ${SYNC_KEY}`,
        },
      },
      {
        action: "update",
        url: "https://external-db.example.com/sync",
        method: "PATCH",
        headers: {
          "Authorization": `Bearer ${SYNC_KEY}`,
        },
      },
      {
        action: "delete",
        url: "https://external-db.example.com/sync",
        method: "DELETE",
        headers: {
          "Authorization": `Bearer ${SYNC_KEY}`,
        },
      },
    ],
  },
});

Trigger Configuration

Configuration Options

{
  action: "create" | "update" | "delete",  // Event type
  url: string,                             // Target URL
  method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",  // HTTP method
  headers?: Record<string, string>,          // Custom headers
  body?: string,                           // Custom body (optional)
}

Multiple Triggers

You can define multiple triggers for different events:

options: {
  triggers: [
    {
      action: "create",
      url: "https://api.example.com/new",
      method: "POST",
    },
    {
      action: "update",
      url: "https://api.example.com/updated",
      method: "PATCH",
    },
    {
      action: "delete",
      url: "https://api.example.com/deleted",
      method: "DELETE",
    },
  ],
},

Same Event, Multiple Triggers

You can also have multiple triggers for the same event:

options: {
  triggers: [
    {
      action: "create",
      url: "https://slack.example.com/webhook",
      method: "POST",
    },
    {
      action: "create",
      url: "https://email.example.com/send",
      method: "POST",
    },
    {
      action: "create",
      url: "https://analytics.example.com/track",
      method: "POST",
    },
  ],
},

Updating Collection Triggers

To modify triggers, update the collection:

const collection = await adminClient.settings.collections.getOne(
  "collection-id",
);

// Parse existing options
const options = JSON.parse(collection.options || "{}");

// Add or modify triggers
options.triggers = [
  ...options.triggers,
  {
    action: "create",
    url: "https://new-url.com/webhook",
    method: "POST",
  },
];

// Update collection
await adminClient.settings.collections.update("collection-id", {
  options: JSON.stringify(options),
});

Webhook Logs

View webhook execution logs:

const logs = await client.webhookLogs.list({
  collection: "notifications",
  status: "success",
  page: 1,
  perPage: 50,
});

logs.forEach((log) => {
  console.log(`URL: ${log.url}`);
  console.log(`Status: ${log.status}`);
  console.log(`HTTP Status: ${log.http_status}`);
  console.log(`Tries: ${log.tries}`);
  console.log(`Response: ${log.response_body}`);
  console.log(`Error: ${log.error_msg}`);
});

Trigger Execution Flow

Event occurs in collection
  ↓
Trigger is matched
  ↓
HTTP request is queued
  ↓
Request is sent to target URL
  ↓
Response is received
  ↓
Log entry is created
  ↓
(If failed) Retry mechanism kicks in

Error Handling

Failed Triggers

When a trigger fails (non-2xx response):

  1. Error is logged
  2. Retry counter is incremented
  3. Trigger will retry on next attempt

Viewing Failed Triggers

const failedLogs = await client.webhookLogs.list({
  status: "failed",
});

failedLogs.forEach((log) => {
  console.error(`Failed: ${log.url}`);
  console.error(`Error: ${log.error_msg}`);
  console.error(`Tries: ${log.tries}`);
});

Security Best Practices

  1. Use HTTPS - Always use HTTPS URLs for triggers
  2. Secure tokens - Store API tokens securely (environment variables)
  3. Verify signatures - Implement webhook signature verification on receiving end
  4. Rate limiting - Implement rate limiting on webhook endpoints
  5. Validate payloads - Always validate incoming webhook data
  6. Use authentication - Include authentication headers in triggers
  7. Monitor logs - Regularly check webhook logs for failures
  8. Test endpoints - Verify webhook endpoints are working before production
  9. Handle duplicates - Make webhook handlers idempotent
  10. Timeout handling - Set appropriate timeouts for webhook requests

Trigger vs Cron Jobs

Feature Triggers Cron Jobs
When On record events On schedule
Use Cases Real-time notifications, data sync Periodic tasks, reports
Latency Near real-time Based on schedule
Reliability Depends on endpoint Built-in retry
API Collection options client.cron

Use triggers for:

  • Immediate notifications
  • Real-time data synchronization
  • Event-driven workflows
  • Third-party integrations

Use cron jobs for:

  • Scheduled tasks
  • Periodic reports
  • Maintenance operations
  • Batch processing

Testing Triggers

Manual Trigger Test

Create a test record to trigger the webhook:

// Create test record
const testRecord = await client.collection("notifications").create({
  title: "Test Notification",
  message: "This is a test",
  status: "active",
});

// Check logs
const logs = await client.webhookLogs.list({
  collection: "notifications",
  page: 1,
  perPage: 10,
});

console.log(logs);

Using Testing Tools

Use webhook testing services like:

// Create collection with test webhook URL
await adminClient.settings.collections.create({
  name: "test_collection",
  type: "base",
  fields: [
    { name: "data", type: "text", required: true },
  ],
  options: {
    triggers: [
      {
        action: "create",
        url: "https://webhook.site/your-unique-id",
        method: "POST",
      },
    ],
  },
});

// Create test record
await client.collection("test_collection").create({
  data: "Test data",
});

// Check webhook.site to see the payload

API Endpoints

Method Endpoint Description
POST /api/collections Create collection with triggers
PATCH /api/collections/:id Update collection triggers
GET /api/webhooks/logs List webhook execution logs

Best Practices

  1. Keep endpoints fast - Webhook endpoints should respond quickly
  2. Return success codes - Always return 2xx status codes on success
  3. Handle failures gracefully - Don't throw unhandled errors
  4. Log everything - Keep detailed logs for debugging
  5. Monitor regularly - Check webhook logs for issues
  6. Use idempotency - Handle duplicate webhook deliveries
  7. Implement timeouts - Don't let webhook handlers hang
  8. Validate input - Always validate webhook payloads
  9. Test thoroughly - Test triggers before production
  10. Document triggers - Keep track of all configured triggers