219 lines
8.1 KiB
JSON
219 lines
8.1 KiB
JSON
{
|
|
"name": "openclaw-action",
|
|
"nodes": [
|
|
{
|
|
"id": "webhook-openclaw-action",
|
|
"name": "Webhook",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2.1,
|
|
"position": [
|
|
-700,
|
|
40
|
|
],
|
|
"parameters": {
|
|
"httpMethod": "POST",
|
|
"path": "openclaw-action",
|
|
"authentication": "none",
|
|
"responseMode": "responseNode",
|
|
"options": {}
|
|
}
|
|
},
|
|
{
|
|
"id": "route-action",
|
|
"name": "route-action",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-420,
|
|
40
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForEachItem",
|
|
"language": "javaScript",
|
|
"jsCode": "const body = $json.body ?? {};\nconst action = body.action ?? '';\nconst args = body.args ?? {};\nconst requestId = body.request_id ?? '';\nconst now = new Date().toISOString();\nconst workflowStaticData = $getWorkflowStaticData('global');\nconst maxLogEntries = 200;\n\nlet route = 'respond';\nlet statusCode = 400;\nlet responseBody = {\n ok: false,\n request_id: requestId,\n error: { code: 'unknown_action', message: 'action is not supported' },\n};\nlet notifyText = '';\n\nif (action === 'append_log') {\n if (typeof args.text === 'string' && args.text.length > 0) {\n statusCode = 200;\n const record = {\n ts: now,\n source: 'openclaw-action',\n request_id: requestId,\n text: args.text,\n meta: typeof args.meta === 'object' && args.meta !== null ? args.meta : undefined,\n };\n const actionLog = Array.isArray(workflowStaticData.actionLog) ? workflowStaticData.actionLog : [];\n actionLog.push(record);\n if (actionLog.length > maxLogEntries) {\n actionLog.splice(0, actionLog.length - maxLogEntries);\n }\n workflowStaticData.actionLog = actionLog;\n responseBody = {\n ok: true,\n request_id: requestId,\n result: {\n action: 'append_log',\n status: 'logged',\n preview: { text: args.text },\n sink: {\n type: 'workflow-static-data',\n key: 'actionLog',\n retained_entries: maxLogEntries,\n },\n },\n };\n } else {\n responseBody = {\n ok: false,\n request_id: requestId,\n error: { code: 'invalid_request', message: 'required args are missing' },\n };\n }\n} else if (action === 'get_logs') {\n const actionLog = Array.isArray(workflowStaticData.actionLog) ? workflowStaticData.actionLog : [];\n const rawLimit = Number.isFinite(Number(args.limit)) ? Number(args.limit) : 20;\n const limit = Math.max(1, Math.min(50, Math.trunc(rawLimit) || 20));\n const entries = actionLog.slice(-limit).reverse();\n statusCode = 200;\n responseBody = {\n ok: true,\n request_id: requestId,\n result: {\n action: 'get_logs',\n status: 'ok',\n count: entries.length,\n total_retained: actionLog.length,\n retained_entries: maxLogEntries,\n entries,\n },\n };\n} else if (action === 'notify') {\n if (typeof args.message === 'string' && args.message.length > 0) {\n route = 'notify';\n statusCode = 200;\n const title = typeof args.title === 'string' ? args.title : '';\n notifyText = title ? `🔔 ${title}\\n${args.message}` : `🔔 ${args.message}`;\n responseBody = {\n ok: true,\n request_id: requestId,\n result: {\n action: 'notify',\n status: 'sent',\n preview: { title, message: args.message },\n targets: ['telegram', 'discord'],\n },\n };\n } else {\n responseBody = {\n ok: false,\n request_id: requestId,\n error: { code: 'invalid_request', message: 'required args are missing' },\n };\n }\n}\n\nreturn {\n json: {\n route,\n status_code: statusCode,\n response_body: responseBody,\n notify_text: notifyText,\n },\n};"
|
|
}
|
|
},
|
|
{
|
|
"id": "route-dispatch",
|
|
"name": "route-dispatch",
|
|
"type": "n8n-nodes-base.switch",
|
|
"typeVersion": 3.4,
|
|
"position": [
|
|
-120,
|
|
40
|
|
],
|
|
"parameters": {
|
|
"mode": "rules",
|
|
"rules": {
|
|
"values": [
|
|
{
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": true,
|
|
"typeValidation": "strict",
|
|
"version": 2
|
|
},
|
|
"conditions": [
|
|
{
|
|
"leftValue": "={{$json.route}}",
|
|
"rightValue": "notify",
|
|
"operator": {
|
|
"type": "string",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"renameOutput": true,
|
|
"outputKey": "notify"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"fallbackOutput": "extra",
|
|
"renameFallbackOutput": "respond"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "send-telegram-notification",
|
|
"name": "Send Telegram Notification",
|
|
"type": "n8n-nodes-base.telegram",
|
|
"typeVersion": 1.2,
|
|
"position": [
|
|
160,
|
|
40
|
|
],
|
|
"parameters": {
|
|
"chatId": "8367012007",
|
|
"text": "={{$json.notify_text}}",
|
|
"additionalFields": {}
|
|
},
|
|
"credentials": {
|
|
"telegramApi": {
|
|
"id": "aox4dyIWVSRdcH5z",
|
|
"name": "Telegram Bot (OpenClaw)"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "send-discord-notification",
|
|
"name": "Send Discord Notification",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
460,
|
|
40
|
|
],
|
|
"parameters": {
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"method": "POST",
|
|
"url": "https://discord.com/api/v10/channels/425781661268049931/messages",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { content: $node[\"route-action\"].json[\"notify_text\"] } }}",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "UgPqYcoCNNIgr55m",
|
|
"name": "Discord Bot Auth"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "respond-openclaw-action",
|
|
"name": "Respond to Webhook",
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
|
"typeVersion": 1.5,
|
|
"position": [
|
|
760,
|
|
40
|
|
],
|
|
"parameters": {
|
|
"respondWith": "json",
|
|
"responseBody": "={{$node[\"route-action\"].json[\"response_body\"]}}",
|
|
"options": {
|
|
"responseCode": "={{$node[\"route-action\"].json[\"status_code\"]}}"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"connections": {
|
|
"Webhook": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "route-action",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"route-action": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "route-dispatch",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"route-dispatch": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Send Telegram Notification",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Respond to Webhook",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Send Telegram Notification": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Send Discord Notification",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Send Discord Notification": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Respond to Webhook",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"settings": {
|
|
"executionOrder": "v1"
|
|
},
|
|
"staticData": null,
|
|
"meta": {
|
|
"templateCredsSetupCompleted": false,
|
|
"note": "After import, set Webhook authentication to Header Auth and bind a local credential using x-openclaw-secret. This asset ships append_log + get_logs via workflow static data plus Telegram/Discord notify fan-out."
|
|
},
|
|
"active": false,
|
|
"versionId": "openclaw-action-v6"
|
|
}
|