Workflows and Webhooks
Adonis EOS provides two complementary systems for event-driven automation: Workflows (code-first) and Webhooks (database-first).
Workflows vs Webhooks
Feature | Workflows | Webhooks |
|---|---|---|
Definition | TypeScript files in | Database records (Admin UI) |
Logic | Full power of TypeScript (transforms, logic) | Direct JSON relay of event data |
Audience | Developers | Site Administrators |
Use Cases | Slack bots, n8n, complex automation | Simple Zapier/webhook integrations |
1. Workflows (Code-First)
Workflows are file-based definitions used for robust, logic-heavy automation.
Creating a Workflow
Create a new file in app/workflows/ (e.g., app/workflows/slack_notifier.ts):
import type { WorkflowDefinition } from '#types/workflow_types'
const SlackNotifierWorkflow: WorkflowDefinition = {
id: 'slack-notifier',
name: 'Slack Notifier',
description: 'Sends a Slack notification when a post is published',
type: 'webhook',
enabled: true,
webhook: {
url: process.env.SLACK_WEBHOOK_URL || '',
method: 'POST',
timeout: 10000,
retryOnFailure: true,
retryAttempts: 3,
},
triggers: [{ trigger: 'post.published', enabled: true }],
transformPayload: (payload: any) => ({
text: `New post published: ${payload.post?.title || 'Untitled'}`,
}),
}
export default SlackNotifierWorkflow
Supported Triggers
Post Events:
post.created,post.updated,post.published,post.approved,post.review.save,post.ai-review.save, etc.Form Events:
form.submitSystem Events:
agent.completed,workflow.completed,manual
2. Webhooks (Database-First)
Webhooks are configured via the Admin UI (Settings > Webhooks) and are ideal for simple relaying of CMS events to external services.
Configuration
Each webhook supports:
Events: Subscribed events (e.g.,
post.published,media.uploaded)Secret: Per-webhook signing secret for signature verification.
Headers: Custom HTTP headers.
Retries: Configurable retry count with exponential backoff.
Payload & Verification
Webhooks are sent as POST requests with a JSON body and an X-Webhook-Signature header.
// Verification Example (Node.js)
import crypto from 'node:crypto'
export function verify(reqBody, signature, secret) {
const expected = crypto.createHmac('sha256', secret).update(reqBody).digest('hex')
return signature === `sha256=${expected}`
}
3. Security (SOC2 Compliance)
Outbound integrations are high-risk. Follow these best practices:
Use HTTPS for all destination URLs.
Set Signing Secrets: Always verify signatures on the receiving end.
Avoid Private Networks: Do not point webhooks to localhost or internal IP ranges (SSRF protection).
Log Deliveries: Review
webhook_deliveriesin the database for auditing and debugging.