Webhook Automation
Skill433 starsChanged 10 months agoMITView on GitHub
Build and manage webhook-based integrations for real-time event processing and API connections
- Reads credentials
In this repository137 other files it gives its agents.
- .cursor/rules/project-rules.mdcCursor rule
- academic-searchSkill
- ads-copywriterSkill
- ai-agent-builderSkill
- airtable-automationSkill
- ai-slidesSkill
- Amazon SellerSkill
- Apple Shortcuts IntegrationSkill
- Applicant ScreeningSkill
- Asana AutomationSkill
- batch-convertSkill
- batch-processorSkill
- Brand Guidelines GeneratorSkill
- Browser AutomationSkill
- calendar-automationSkill
- Changelog GeneratorSkill
- chart-designerSkill
- Chat with PDFSkill
- ClickUp AutomationSkill
- company-researchSkill
- competitive-analysisSkill
- Content Research WriterSkill
- contract-reviewSkill
- contract-templateSkill
- cover-letterSkill
- crm-automationSkill
- crypto-reportSkill
- customer-successSkill
- cv-builderSkill
- data-analysisSkill
- Database SyncSkill
- data-extractorSkill
- data-pipelineSkill
- dcf-valuationSkill
- deep-researchSkill
- devops-automationSkill
- dev-slidesSkill
- diagram-creatorSkill
- discord-botSkill
- doc-parserSkill
- doc-pipelineSkill
- DocuSign AutomationSkill
- docx-manipulationSkill
- Email ClassifierSkill
- email-drafterSkill
- email-marketingSkill
- ETL PipelineSkill
- excel-automationSkill
- expense-reportSkill
- Expense TrackerSkill
- Facebook/Meta AdsSkill
- File OrganizerSkill
- financial-modelingSkill
- form-builderSkill
- gmail-workflowsSkill
- google-ads-managerSkill
- Home Assistant AutomationSkill
- hr-automationSkill
- html-slidesSkill
- html-to-pptSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 494
Verify Signatures: Always validate webhook authenticity
- Distinctive: line 497
Dead Letters: Don't lose failed events
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Webhook Automation
Comprehensive skill for building webhook-based integrations and real-time event processing.
Core Concepts
Webhook Architecture
WEBHOOK FLOW:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Source │────▶│ Webhook │────▶│ Handler │
│ System │ │ Endpoint │ │ Logic │
└─────────────┘ └─────────────┘ └──────┬──────┘
│
┌──────────────────────────┼───────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Action │ │ Action │ │ Action │
│ A │ │ B │ │ C │
└──────────┘ └──────────┘ └──────────┘Webhook Types
webhook_types:
incoming:
description: "Receive events from external services"
use_cases:
- Payment notifications (Stripe, PayPal)
- Form submissions
- CRM updates
- CI/CD events
outgoing:
description: "Send events to external services"
use_cases:
- Notify external systems
- Trigger workflows
- Sync data
- Alert integrationsWebhook Endpoint Setup
Basic Endpoint
webhook_endpoint:
url: "https://api.example.com/webhooks/incoming"
method: POST
authentication:
type: signature
header: "X-Signature-256"
algorithm: "HMAC-SHA256"
secret: "${WEBHOOK_SECRET}"
validation:
required_headers:
- "Content-Type"
- "X-Request-ID"
content_types:
- "application/json"
- "application/x-www-form-urlencoded"
response:
success:
status: 200
body: { "received": true }
error:
status: 400
body: { "error": "Invalid payload" }Signature Verification
// Verify webhook signature
function verifySignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = 'sha256=' + hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(digest),
Buffer.from(signature)
);
}
// Usage
app.post('/webhook', (req, res) => {
const signature = req.headers['x-signature-256'];
const payload = JSON.stringify(req.body);
if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process webhook...
processWebhook(req.body);
res.status(200).json({ received: true });
});Event Processing
Event Router
event_router:
routes:
- event_type: "payment.succeeded"
handler: processPayment
actions:
- update_order_status
- send_confirmation_email
- notify_fulfillment
- event_type: "customer.created"
handler: processNewCustomer
actions:
- create_crm_contact
- send_welcome_email
- assign_to_sales
- event_type: "subscription.cancelled"
handler: processChurn
actions:
- update_subscription_status
- trigger_retention_flow
- notify_customer_success
- event_type: "*"
handler: logUnhandled
actions:
- log_to_monitoringPayload Transformation
transformations:
- name: stripe_to_internal
source: stripe_webhook
target: internal_order
mapping:
id: "data.object.id"
amount: "data.object.amount / 100" # Cents to dollars
currency: "data.object.currency | uppercase"
customer_email: "data.object.receipt_email"
created_at: "data.object.created | timestamp"
metadata: "data.object.metadata"
- name: github_to_slack
source: github_webhook
target: slack_message
mapping:
text: |
*{{action | capitalize}} {{repository.name}}*
{{#if pull_request}}
PR: {{pull_request.title}}
By: {{pull_request.user.login}}
{{/if}}
channel: "{{repository.name}}-notifications"Common Integrations
Stripe Webhooks
stripe_webhooks:
endpoint_secret: "${STRIPE_WEBHOOK_SECRET}"
events:
- type: "checkout.session.completed"
handler: |
async function(event) {
const session = event.data.object;
await fulfillOrder(session);
await sendReceipt(session.customer_email);
}
- type: "invoice.payment_failed"
handler: |
async function(event) {
const invoice = event.data.object;
await notifyCustomer(invoice);
await createDunningTask(invoice);
}
- type: "customer.subscription.updated"
handler: |
async function(event) {
const subscription = event.data.object;
await syncSubscriptionStatus(subscription);
}GitHub Webhooks
github_webhooks:
secret: "${GITHUB_WEBHOOK_SECRET}"
events:
- type: "push"
branches: ["main", "develop"]
handler: |
async function(event) {
await triggerCI(event.repository, event.ref);
await notifyTeam(event.commits);
}
- type: "pull_request"
actions: ["opened", "synchronize"]
handler: |
async function(event) {
await runTests(event.pull_request);
await requestReview(event.pull_request);
}
- type: "issues"
actions: ["opened"]
handler: |
async function(event) {
await triageIssue(event.issue);
await assignOwner(event.issue);
}Slack Webhooks
slack_webhooks:
incoming:
# Receive slash commands and interactions
signing_secret: "${SLACK_SIGNING_SECRET}"
events:
- type: "slash_command"
command: "/deploy"
handler: handleDeployCommand
- type: "interactive_message"
callback_id: "approval_*"
handler: handleApproval
outgoing:
# Send messages to Slack
webhook_url: "${SLACK_WEBHOOK_URL}"
templates:
alert:
blocks:
- type: section
text: "🚨 *Alert:* {{message}}"
- type: context
elements:
- type: mrkdwn
text: "Source: {{source}} | Time: {{timestamp}}"Error Handling
Retry Strategy
retry_config:
enabled: true
policy:
max_attempts: 5
initial_delay: 1000 # ms
max_delay: 60000 # ms
backoff_multiplier: 2
retry_on:
status_codes: [408, 429, 500, 502, 503, 504]
exceptions: ["ECONNRESET", "ETIMEDOUT"]
dead_letter:
enabled: true
destination: "failed_webhooks_queue"
retention_days: 7Error Logging
error_handling:
logging:
level: error
include:
- request_id
- event_type
- payload_hash
- error_message
- stack_trace
- retry_count
alerting:
on_failure:
- type: slack
channel: "#webhook-alerts"
threshold: 5 # failures per minute
on_dead_letter:
- type: pagerduty
severity: warningWebhook Testing
Test Payload Generator
test_payloads:
stripe_payment:
type: "checkout.session.completed"
data:
object:
id: "cs_test_123"
amount_total: 2000
currency: "usd"
customer_email: "test@example.com"
payment_status: "paid"
github_push:
ref: "refs/heads/main"
repository:
name: "my-repo"
full_name: "org/my-repo"
commits:
- id: "abc123"
message: "Test commit"
author:
name: "Test User"Webhook Debugging
debugging:
tools:
- name: "Request Bin"
url: "https://requestbin.com"
use: "Capture and inspect payloads"
- name: "ngrok"
command: "ngrok http 3000"
use: "Expose local server"
- name: "Webhook.site"
url: "https://webhook.site"
use: "Quick webhook testing"
logging:
enabled: true
log_payloads: true
log_headers: true
mask_secrets: trueSecurity Best Practices
Security Checklist
security:
authentication:
- Verify webhook signatures
- Use HTTPS only
- Rotate secrets regularly
validation:
- Validate payload schema
- Check timestamp freshness
- Verify source IP if possible
processing:
- Idempotent handlers
- Rate limiting
- Timeout protection
storage:
- Encrypt secrets at rest
- Audit logging
- No sensitive data in URLsIP Allowlisting
ip_allowlist:
stripe:
- "3.18.12.63"
- "3.130.192.231"
# ... more IPs
github:
- "192.30.252.0/22"
- "185.199.108.0/22"
# ... more ranges
slack:
- "54.159.240.0/22"
# ... more rangesMonitoring
Metrics Dashboard
WEBHOOK METRICS - LAST 24 HOURS
═══════════════════════════════════════
Received: 12,456
Processed: 12,398 (99.5%)
Failed: 58 (0.5%)
Retried: 123
BY SOURCE:
Stripe ████████████░░░░ 5,230
GitHub ██████████░░░░░░ 4,120
Slack ████░░░░░░░░░░░░ 1,850
Other ███░░░░░░░░░░░░░ 1,256
LATENCY (p99):
Processing: 245ms
Response: 52ms
ERROR BREAKDOWN:
Timeout: 25
Invalid Sig: 18
Parse Error: 10
Rate Limited: 5Best Practices
- Respond Quickly: Return 200 immediately, process async
- Idempotency: Handle duplicate events gracefully
- Verify Signatures: Always validate webhook authenticity
- Log Everything: Maintain audit trail
- Retry Logic: Implement exponential backoff
- Dead Letters: Don't lose failed events
- Rate Limiting: Protect against flood attacks
- Monitoring: Alert on failures and latency
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

