feat(n8n-webhook): add approval-gated notification executor
This commit is contained in:
@@ -69,3 +69,12 @@
|
|||||||
- local HTTP URL `http://192.168.153.113:18808/healthz` → success
|
- local HTTP URL `http://192.168.153.113:18808/healthz` → success
|
||||||
- `https://example.com` with `skip_ssl_certificate_validation: true` → success
|
- `https://example.com` with `skip_ssl_certificate_validation: true` → success
|
||||||
- Cleanup: resolved the temporary verification approval items so `approvalQueue` ended empty after testing.
|
- Cleanup: resolved the temporary verification approval items so `approvalQueue` ended empty after testing.
|
||||||
|
- State check before attempting deeper executor work: the live n8n instance currently exposes only four credentials via the public API — `Discord Bot Auth`, `Telegram Bot (OpenClaw)`, `OpenClaw Webhook Header`, and `Header Auth account`. No Gmail/Google Calendar credentials were present, so provider-backed email/calendar execution was intentionally not faked.
|
||||||
|
- Implemented the first true approval-gated executor that matches currently available creds:
|
||||||
|
- new action `send_notification_draft`
|
||||||
|
- queues a pending notification in `approvalQueue`
|
||||||
|
- when approved via `approval_queue_resolve`, it executes the existing `notify` path and sends through Telegram + Discord
|
||||||
|
- Verified live end-to-end on 2026-03-12:
|
||||||
|
- `send_notification_draft` returned `200` and produced pending id `approval-mmnr8pyq-tjxiqkps`
|
||||||
|
- approving that item via `approval_queue_resolve` returned `executed: true` and `executed_action: "notify"`
|
||||||
|
- `approval_queue_list` showed `pending_count: 0` afterward and recorded the execution metadata in history
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ Keep the integration narrow: let OpenClaw decide what to do, and let n8n execute
|
|||||||
- sample payloads:
|
- sample payloads:
|
||||||
- `assets/test-append-log.json`
|
- `assets/test-append-log.json`
|
||||||
- `assets/test-notify.json`
|
- `assets/test-notify.json`
|
||||||
|
- `assets/test-send-notification-draft.json`
|
||||||
|
|
||||||
## Quick usage
|
## Quick usage
|
||||||
|
|
||||||
@@ -101,6 +102,7 @@ Use the included workflow asset when you want a ready-made local router for:
|
|||||||
- `append_log` → append small records into workflow static data (`actionLog`, latest 200)
|
- `append_log` → append small records into workflow static data (`actionLog`, latest 200)
|
||||||
- `get_logs` → read the most recent retained records from `actionLog`
|
- `get_logs` → read the most recent retained records from `actionLog`
|
||||||
- `notify` → send through the current Telegram + Discord notification paths
|
- `notify` → send through the current Telegram + Discord notification paths
|
||||||
|
- `send_notification_draft` → queue approval-gated notifications that execute on approve through Telegram + Discord
|
||||||
- `send_email_draft` → queue approval-gated email drafts in workflow static data
|
- `send_email_draft` → queue approval-gated email drafts in workflow static data
|
||||||
- `create_calendar_event` → queue approval-gated calendar proposals in workflow static data
|
- `create_calendar_event` → queue approval-gated calendar proposals in workflow static data
|
||||||
- `approval_queue_add` / `approval_queue_list` / `approval_queue_resolve` → manage pending approvals and recent history
|
- `approval_queue_add` / `approval_queue_list` / `approval_queue_resolve` → manage pending approvals and recent history
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"action": "send_notification_draft",
|
||||||
|
"request_id": "test-notify-draft-001",
|
||||||
|
"args": {
|
||||||
|
"title": "Draft notification",
|
||||||
|
"message": "This is a queued notification draft for approval."
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ It implements a real local OpenClaw → n8n router.
|
|||||||
- `append_log`
|
- `append_log`
|
||||||
- `get_logs`
|
- `get_logs`
|
||||||
- `notify`
|
- `notify`
|
||||||
|
- `send_notification_draft`
|
||||||
- `send_email_draft`
|
- `send_email_draft`
|
||||||
- `create_calendar_event`
|
- `create_calendar_event`
|
||||||
- `approval_queue_add`
|
- `approval_queue_add`
|
||||||
@@ -40,6 +41,13 @@ Example stored record:
|
|||||||
{"ts":"2026-03-12T07:00:00Z","source":"openclaw-action","request_id":"abc","text":"backup complete"}
|
{"ts":"2026-03-12T07:00:00Z","source":"openclaw-action","request_id":"abc","text":"backup complete"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `send_notification_draft`
|
||||||
|
|
||||||
|
- queues an approval-gated notification proposal into workflow static data under key:
|
||||||
|
- `approvalQueue`
|
||||||
|
- when resolved with `decision=approve`, it executes the existing `notify` path and sends through Telegram + Discord
|
||||||
|
- uses only the already-configured notification credentials in the live n8n instance
|
||||||
|
|
||||||
### `send_email_draft` and `create_calendar_event`
|
### `send_email_draft` and `create_calendar_event`
|
||||||
|
|
||||||
- queue approval-gated proposals into workflow static data under key:
|
- queue approval-gated proposals into workflow static data under key:
|
||||||
@@ -129,6 +137,7 @@ After import, set this manually in n8n:
|
|||||||
|
|
||||||
- `assets/test-append-log.json`
|
- `assets/test-append-log.json`
|
||||||
- `assets/test-notify.json`
|
- `assets/test-notify.json`
|
||||||
|
- `assets/test-send-notification-draft.json`
|
||||||
- `assets/test-send-email-draft.json`
|
- `assets/test-send-email-draft.json`
|
||||||
- `assets/test-create-calendar-event.json`
|
- `assets/test-create-calendar-event.json`
|
||||||
- `assets/test-fetch-and-normalize-url.json`
|
- `assets/test-fetch-and-normalize-url.json`
|
||||||
@@ -142,6 +151,7 @@ export N8N_WEBHOOK_SECRET='YOUR_SECRET_HERE'
|
|||||||
scripts/call-action.sh append_log --args '{"text":"backup complete"}' --pretty
|
scripts/call-action.sh append_log --args '{"text":"backup complete"}' --pretty
|
||||||
scripts/call-action.sh get_logs --args '{"limit":5}' --pretty
|
scripts/call-action.sh get_logs --args '{"limit":5}' --pretty
|
||||||
scripts/call-action.sh notify --args '{"title":"Workflow finished","message":"n8n router test"}' --pretty
|
scripts/call-action.sh notify --args '{"title":"Workflow finished","message":"n8n router test"}' --pretty
|
||||||
|
scripts/call-action.sh send_notification_draft --args-file assets/test-send-notification-draft.json --pretty
|
||||||
scripts/call-action.sh send_email_draft --args-file assets/test-send-email-draft.json --pretty
|
scripts/call-action.sh send_email_draft --args-file assets/test-send-email-draft.json --pretty
|
||||||
scripts/call-action.sh create_calendar_event --args-file assets/test-create-calendar-event.json --pretty
|
scripts/call-action.sh create_calendar_event --args-file assets/test-create-calendar-event.json --pretty
|
||||||
scripts/call-action.sh fetch_and_normalize_url --args '{"url":"http://192.168.153.113:18808/healthz"}' --pretty
|
scripts/call-action.sh fetch_and_normalize_url --args '{"url":"http://192.168.153.113:18808/healthz"}' --pretty
|
||||||
@@ -152,6 +162,21 @@ scripts/call-action.sh inbound_event_filter --args-file assets/test-inbound-even
|
|||||||
|
|
||||||
## Expected success examples
|
## Expected success examples
|
||||||
|
|
||||||
|
### send_notification_draft
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ok": true,
|
||||||
|
"request_id": "test-notify-draft-001",
|
||||||
|
"result": {
|
||||||
|
"action": "send_notification_draft",
|
||||||
|
"status": "queued_for_approval",
|
||||||
|
"pending_id": "approval-abc123",
|
||||||
|
"approval_status": "pending"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### send_email_draft
|
### send_email_draft
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|||||||
@@ -113,6 +113,24 @@ Request:
|
|||||||
Purpose:
|
Purpose:
|
||||||
- send the message through the currently configured Telegram + Discord notification targets
|
- send the message through the currently configured Telegram + Discord notification targets
|
||||||
|
|
||||||
|
### `send_notification_draft`
|
||||||
|
|
||||||
|
Request:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "send_notification_draft",
|
||||||
|
"args": {
|
||||||
|
"title": "optional title",
|
||||||
|
"message": "Please review this notification before send"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
- queue a notification for approval
|
||||||
|
- when the pending item is later approved through `approval_queue_resolve`, it executes the existing `notify` path and fans out through Telegram + Discord
|
||||||
|
|
||||||
### `send_email_draft`
|
### `send_email_draft`
|
||||||
|
|
||||||
Request:
|
Request:
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ EXPECTED_TYPES = {
|
|||||||
SAMPLE_FILES = [
|
SAMPLE_FILES = [
|
||||||
'test-append-log.json',
|
'test-append-log.json',
|
||||||
'test-notify.json',
|
'test-notify.json',
|
||||||
|
'test-send-notification-draft.json',
|
||||||
'test-send-email-draft.json',
|
'test-send-email-draft.json',
|
||||||
'test-create-calendar-event.json',
|
'test-create-calendar-event.json',
|
||||||
'test-fetch-and-normalize-url.json',
|
'test-fetch-and-normalize-url.json',
|
||||||
@@ -35,6 +36,7 @@ ROUTER_SNIPPETS = [
|
|||||||
'append_log',
|
'append_log',
|
||||||
'get_logs',
|
'get_logs',
|
||||||
'notify',
|
'notify',
|
||||||
|
'send_notification_draft',
|
||||||
'send_email_draft',
|
'send_email_draft',
|
||||||
'create_calendar_event',
|
'create_calendar_event',
|
||||||
'approval_queue_add',
|
'approval_queue_add',
|
||||||
|
|||||||
Reference in New Issue
Block a user