Table of Contents
- Triggers
- Understanding Triggers
- Configuring Triggers
- Trigger Payload
- Practical Examples
- Slack Notifications
- Email Notifications
- Audit Logging
- Third-Party Integration
- Workflow Triggers
- Data Synchronization
- Trigger Configuration
- Updating Collection Triggers
- Webhook Logs
- Trigger Execution Flow
- Error Handling
- Security Best Practices
- Trigger vs Cron Jobs
- Testing Triggers
- API Endpoints
- Best Practices
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):
- Error is logged
- Retry counter is incremented
- 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
- Use HTTPS - Always use HTTPS URLs for triggers
- Secure tokens - Store API tokens securely (environment variables)
- Verify signatures - Implement webhook signature verification on receiving end
- Rate limiting - Implement rate limiting on webhook endpoints
- Validate payloads - Always validate incoming webhook data
- Use authentication - Include authentication headers in triggers
- Monitor logs - Regularly check webhook logs for failures
- Test endpoints - Verify webhook endpoints are working before production
- Handle duplicates - Make webhook handlers idempotent
- 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:
- https://webhook.site - Get a temporary webhook URL
- https://requestbin.com - Inspect HTTP requests
- ngrok - Expose local endpoints
// 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
- Keep endpoints fast - Webhook endpoints should respond quickly
- Return success codes - Always return 2xx status codes on success
- Handle failures gracefully - Don't throw unhandled errors
- Log everything - Keep detailed logs for debugging
- Monitor regularly - Check webhook logs for issues
- Use idempotency - Handle duplicate webhook deliveries
- Implement timeouts - Don't let webhook handlers hang
- Validate input - Always validate webhook payloads
- Test thoroughly - Test triggers before production
- Document triggers - Keep track of all configured triggers