| title | Webhooks |
|---|---|
| description | Set up real-time notifications and integrate AetherFlow with external systems using webhooks |
Receive real-time notifications about workflow events and integrate AetherFlow with external systems.
Webhooks deliver instant notifications when workflow events occur, enabling real-time integrations.Set up webhook endpoints to receive AetherFlow event notifications.
Set up an HTTPS endpoint in your application to receive webhook payloads. Register your endpoint URL in the AetherFlow dashboard. Generate and configure a webhook secret for payload verification. Send test events to verify your endpoint receives and processes webhooks.Subscribe to specific events that trigger webhook notifications.
- `workflow.created` - Fired when a new workflow is created - `workflow.updated` - Fired when workflow configuration changes - `workflow.deleted` - Fired when a workflow is deleted - `workflow.executed` - Fired when a workflow execution starts - `workflow.completed` - Fired when a workflow completes successfully - `workflow.failed` - Fired when a workflow execution fails - `integration.connected` - Fired when an integration is successfully connected - `integration.disconnected` - Fired when an integration connection is lost - `integration.error` - Fired when an integration encounters an error - `user.invited` - Fired when a team member is invited - `user.joined` - Fired when a user joins the workspace - `billing.updated` - Fired when billing information changesUnderstand the format of webhook payloads and how to process them.
```json { "event": "workflow.completed", "id": "evt_1234567890", "timestamp": "2024-01-15T10:30:00Z", "data": { "workflow": { "id": "wf_abc123", "name": "Email Processor", "status": "completed", "execution_time": 2500, "executed_at": "2024-01-15T10:29:57Z" }, "steps": [ { "id": "step_1", "name": "Process Email", "status": "completed", "duration": 1200 }, { "id": "step_2", "name": "Send Slack Notification", "status": "completed", "duration": 1300 } ], "custom_data": { "email_subject": "Important Update", "priority": "high" } } } ``` ```json { "event": "workflow.failed", "id": "evt_1234567891", "timestamp": "2024-01-15T10:35:00Z", "data": { "workflow": { "id": "wf_def456", "name": "Data Sync", "status": "failed", "error_message": "Integration timeout", "failed_at": "2024-01-15T10:34:45Z" }, "error_details": { "step": "step_3", "integration": "salesforce", "error_code": "TIMEOUT", "retry_count": 3 } } } ```Secure your webhook endpoints and verify payload authenticity.
Always verify webhook signatures to ensure payloads are genuine and haven't been tampered with. ```javascript const crypto = require('crypto');function verifySignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload, 'utf8') .digest('hex');
return crypto.timingSafeEqual( Buffer.from(signature, 'hex'), Buffer.from(expectedSignature, 'hex') ); }
// Usage in Express.js app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-aetherflow-signature']; const secret = process.env.WEBHOOK_SECRET;
if (!verifySignature(req.body, signature, secret)) { return res.status(401).send('Invalid signature'); }
// Process webhook payload const payload = JSON.parse(req.body); // ... handle event });
```python
import hmac
import hashlib
import json
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
expected_signature = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature)
# Usage in Flask
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-AetherFlow-Signature')
secret = os.environ.get('WEBHOOK_SECRET')
if not verify_signature(request.data, signature, secret):
return 'Invalid signature', 401
payload = request.get_json()
# ... handle event
return 'OK', 200
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
)
func verifySignature(payload []byte, signature string, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(payload)
expectedMAC := mac.Sum(nil)
expectedSignature := hex.EncodeToString(expectedMAC)
return hmac.Equal([]byte(signature), []byte(expectedSignature))
}
func webhookHandler(w http.ResponseWriter, r *http.Request) {
signature := r.Header.Get("X-AetherFlow-Signature")
secret := os.Getenv("WEBHOOK_SECRET")
payload, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Bad request", 400)
return
}
if !verifySignature(payload, signature, secret) {
http.Error(w, "Invalid signature", 401)
return
}
// Process webhook payload
// ... handle event
fmt.Fprint(w, "OK")
}Process different types of webhook events in your application.
```javascript function processWebhookEvent(eventType, data) { switch (eventType) { case 'workflow.completed': // Update internal records updateWorkflowStatus(data.workflow.id, 'completed'); // Send notifications notifyTeam(data.workflow.name + ' completed successfully'); break;case 'workflow.failed':
// Log error details
logWorkflowError(data.workflow.id, data.error_details);
// Trigger retry or alert
if (data.error_details.retry_count < 3) {
retryWorkflow(data.workflow.id);
} else {
alertDevopsTeam(data.workflow.name + ' failed permanently');
}
break;
case 'integration.disconnected':
// Handle integration issues
disableWorkflowsUsingIntegration(data.integration.id);
sendIntegrationAlert(data.integration.name);
break;
default:
console.log('Unhandled event type:', eventType);
} }
```python
def process_webhook_event(event_type: str, data: dict):
if event_type == 'workflow.completed':
# Update internal records
update_workflow_status(data['workflow']['id'], 'completed')
# Send notifications
notify_team(f"{data['workflow']['name']} completed successfully")
elif event_type == 'workflow.failed':
# Log error details
log_workflow_error(data['workflow']['id'], data['error_details'])
# Trigger retry or alert
if data['error_details']['retry_count'] < 3:
retry_workflow(data['workflow']['id'])
else:
alert_devops_team(f"{data['workflow']['name']} failed permanently")
elif event_type == 'integration.disconnected':
# Handle integration issues
disable_workflows_using_integration(data['integration']['id'])
send_integration_alert(data['integration']['name'])
else:
print(f'Unhandled event type: {event_type}')
Handle webhook delivery failures and implement retry mechanisms.
Implement idempotent webhook handlers to safely process duplicate deliveries. Use event IDs to prevent processing duplicate webhook deliveries. AetherFlow automatically retries failed webhook deliveries up to 3 times. Respond within 10 seconds to avoid delivery retries. Return appropriate HTTP status codes for different error conditions. ```javascript const processedEvents = new Set();function handleWebhook(req, res) { const eventId = req.body.id;
// Check if we've already processed this event if (processedEvents.has(eventId)) { return res.status(200).send('Already processed'); }
try { // Process the webhook processWebhookEvent(req.body.event, req.body.data);
// Mark as processed
processedEvents.add(eventId);
// Clean up old events (keep last 1000)
if (processedEvents.size > 1000) {
const oldestEvent = processedEvents.values().next().value;
processedEvents.delete(oldestEvent);
}
res.status(200).send('Processed');
} catch (error) { console.error('Webhook processing error:', error); res.status(500).send('Processing failed'); } }
```python
processed_events = set()
def handle_webhook():
event_id = request.json['id']
# Check if we've already processed this event
if event_id in processed_events:
return 'Already processed', 200
try:
# Process the webhook
process_webhook_event(request.json['event'], request.json['data'])
# Mark as processed
processed_events.add(event_id)
# Clean up old events (keep last 1000)
if len(processed_events) > 1000:
oldest_event = next(iter(processed_events))
processed_events.remove(oldest_event)
return 'Processed', 200
except Exception as e:
print(f'Webhook processing error: {e}')
return 'Processing failed', 500
Test your webhook integrations before going live.
Use the AetherFlow dashboard to send test webhook events to your endpoint. Use tools like ngrok or localtunnel to expose local development servers. Create unit tests for webhook handlers and payload processing. ```bash curl -X POST http://your-endpoint.com/webhook \ -H "Content-Type: application/json" \ -H "X-AetherFlow-Signature: test_signature" \ -d '{ "event": "workflow.completed", "id": "test_event_123", "timestamp": "2024-01-15T10:30:00Z", "data": { "workflow": { "id": "test_workflow", "name": "Test Workflow", "status": "completed" } } }' ```Manage and monitor your webhook configurations.
Configure retry policies, timeout settings, and event filters. Track webhook delivery success rates and response times. Enable detailed logging for troubleshooting webhook issues.Optimize your webhook implementation for reliability and performance.
Process webhooks asynchronously and respond quickly. Implement comprehensive error handling and logging. Always verify signatures and use HTTPS endpoints. Monitor webhook delivery and processing metrics. Handle webhook payload versioning gracefully. Implement rate limiting to handle high-volume events. ```mermaid sequenceDiagram participant A as AetherFlow participant W as Webhook Endpoint participant Q as Queue participant P as ProcessorA->>W: POST webhook payload
W->>W: Verify signature
W->>Q: Queue for processing
W->>A: 200 OK (immediate response)
Q->>P: Dequeue for processing
P->>P: Process event
P->>P: Update application state
</Expandable>
Webhooks provide real-time integration capabilities, enabling your applications to respond instantly to AetherFlow events.