AI-Powered Webhook Automation

Use an LLM to interpret incoming webhook events and trigger intelligent, context-aware responses.

What You'll Build

Standard webhook handlers use rigid if/else logic, transfer events go here, updates go there. In this tutorial you'll build an AI-powered webhook responder that interprets events with an LLM, decides the best response, and executes it autonomously. Think of it as giving your webhook pipeline a brain.

Step 1, Set Up the Webhook Server

bash
mkdir dual-ai-webhooks && cd dual-ai-webhooks
npm init -y
npm install express @anthropic-ai/sdk

Step 2, Define the AI Decision Engine

Create a function that takes a raw webhook event and returns an action plan:

javascript
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic();
async function decideAction(event) {
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250514',
max_tokens: 512,
system: \"You are an event handler for a token platform.
Given a webhook event, decide the appropriate response.
Return JSON with:
- "action": one of ["notify_owner", "update_property", "trigger_webhook", "log_only", "escalate"]
- "reason": why you chose this action
- "params": any parameters needed to execute the action
Rules:
- Transfers over 100 tokens: escalate to admin
- Property changes on premium templates: notify the owner
- Failed actions: log and retry once
- Suspicious patterns (>10 transfers/minute): escalate immediately\",
messages: [{
role: 'user',
content: JSON.stringify(event, null, 2)
}]
});
return JSON.parse(response.content[0].text);
}

Step 3, Build Action Executors

Implement handlers for each action the AI can decide on:

javascript
const actionExecutors = {
async notify_owner({ object_id, message }) {
const obj = await dualFetch(\"/objects/\" + object_id + "\");
await dualFetch('/notifications/send', {
method: 'POST',
body: JSON.stringify({
recipient: obj.owner,
title: 'Token Activity Alert',
body: message
})
});
},
async update_property({ object_id, properties }) {
await dualFetch(\"/objects/\" + object_id + "\", {
method: 'PATCH',
body: JSON.stringify({ properties })
});
},
async escalate({ event, reason }) {
await dualFetch('/notifications/send', {
method: 'POST',
body: JSON.stringify({
recipient: process.env.ADMIN_WALLET,
title: 'ESCALATION: ' + reason,
body: JSON.stringify(event)
})
});
},
async log_only({ event, reason }) {
console.log('[AI Decision]', reason, event.event_type);
}
};

Step 4, Wire It Together

javascript
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhooks/ai', async (req, res) => {
const event = req.body;
res.status(200).json({ received: true }); // ACK immediately
try {
const decision = await decideAction(event);
console.log(\"[AI] \" + event.event_type + " → \" + decision.action + ": \" + decision.reason + "\");
const executor = actionExecutors[decision.action];
if (executor) {
await executor({ ...decision.params, event });
}
} catch (err) {
console.error('AI decision failed:', err.message);
// Fall back to logging
await actionExecutors.log_only({
event, reason: 'AI decision error, logged for review'
});
}
});
app.listen(3000, () => console.log('AI webhook responder on :3000'));

Step 5, Register the Webhook

bash
curl -X POST https://api-testnet.dual.network/webhooks \\
-H "Authorization: Bearer $DUAL_TOKEN" \\
-H "Content-Type: application/json" \\
-d '{
"webhook": {
"url": "https://your-server.com/webhooks/ai",
"events": ["object.transferred", "object.updated", "action.failed"],
"active": true
}
}'

Latency Tip: Always ACK the webhook immediately (200 OK) before running the AI decision. Dual expects a response within 5 seconds. Process the event asynchronously after acknowledging receipt.

Companion Repo: Get the full working source code for this tutorial at github.com/orgs/DualOrg/dual-ai-webhooks, clone it, add your API keys, and run it locally in minutes.

What's Next?

Add semantic search to your token library with Semantic Search over Token Metadata.