AutomationFlowsGeneral › [future] Action-runner

[future] Action-runner

[FUTURE] action-runner. Scheduled trigger; 9 nodes.

Cron / scheduled trigger★★★★☆ complexity9 nodes
General Trigger: Cron / scheduled Nodes: 9 Complexity: ★★★★☆ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "_status": "future",
  "_note": "Deferred to future milestone. Do not import into n8n.",
  "id": "action-runner",
  "name": "[FUTURE] action-runner",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 5
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "position": [
        240,
        200
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "queue-action",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-trigger",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        460
      ]
    },
    {
      "parameters": {
        "workflowId": "hmac-verify",
        "options": {},
        "workflowInputs": {
          "value": {
            "headers": "={{ $json.headers }}",
            "body": "={{ $json.body }}",
            "rawBody": "={{ $json.body ? JSON.stringify($json.body) : '' }}"
          }
        }
      },
      "id": "hmac-check",
      "name": "HMAC Verify",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1,
      "position": [
        460,
        460
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "6f821a10-44ed-493e-863a-ee49b6717029",
              "leftValue": "={{ $json.verified }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "if-verified",
      "name": "Is Verified?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        680,
        460
      ]
    },
    {
      "parameters": {
        "jsCode": "// T049: Enqueue action into Workflow Static Data queue\n// Adds entries from the verified webhook request body to the action queue\n\nconst body = $input.all()[0].json.body;\nconst staticData = $getWorkflowStaticData('global');\n\nif (!staticData.queue) {\n  staticData.queue = [];\n}\n\nconst entry = {\n  id: `action_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,\n  action_type: body.action_type,\n  target_urn: body.target_urn,\n  text: body.text || null,\n  scheduled_at: body.scheduled_at || new Date().toISOString(),\n  status: 'pending'\n};\n\nstaticData.queue.push(entry);\n\nreturn [{\n  json: {\n    status: 'queued',\n    entry: entry,\n    queue_length: staticData.queue.length\n  }\n}];"
      },
      "id": "enqueue-action",
      "name": "Enqueue Action",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        400
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "respond-success",
      "name": "Respond Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1120,
        400
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ error: 'Unauthorized', details: $json.error }) }}",
        "options": {
          "responseCode": 401
        }
      },
      "id": "respond-401",
      "name": "Reject 401",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        900,
        580
      ]
    },
    {
      "parameters": {
        "jsCode": "// T049: Read queue from Static Data, filter for items that are due\n\nconst staticData = $getWorkflowStaticData('global');\n\nif (!staticData.queue) {\n  staticData.queue = [];\n}\n\nconst now = new Date();\nconst dueItems = staticData.queue.filter(item => {\n  if (item.status !== 'pending') return false;\n  const scheduledAt = new Date(item.scheduled_at);\n  return scheduledAt <= now;\n});\n\nif (dueItems.length === 0) {\n  return [{ json: { status: 'idle', message: 'No due items in queue', queue_length: staticData.queue.length } }];\n}\n\n// Return due items for processing\nreturn dueItems.map(item => ({ json: item }));"
      },
      "id": "read-queue",
      "name": "Read Queue",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        200
      ]
    },
    {
      "parameters": {
        "jsCode": "// T049: Execute due action by calling the appropriate workflow webhook\n// and update the queue entry status in Static Data\n\nconst item = $input.all()[0].json;\n\n// Skip if this is an idle status message (no due items)\nif (item.status === 'idle') {\n  return [{ json: item }];\n}\n\nconst staticData = $getWorkflowStaticData('global');\n\nlet endpoint = '';\nlet payload = {};\n\nswitch (item.action_type) {\n  case 'like':\n    endpoint = 'http://localhost:5678/webhook/linkedin-like';\n    payload = { action: 'like', target_urn: item.target_urn };\n    break;\n  case 'comment':\n    endpoint = 'http://localhost:5678/webhook/linkedin-comment';\n    payload = { action: 'comment', draft_id: item.id, target_urn: item.target_urn, text: item.text };\n    break;\n  default:\n    // Mark as failed for unknown action types\n    const idx = staticData.queue.findIndex(q => q.id === item.id);\n    if (idx >= 0) {\n      staticData.queue[idx].status = 'failed';\n      staticData.queue[idx].error = `Unknown action_type: ${item.action_type}`;\n    }\n    return [{ json: { status: 'failed', id: item.id, error: `Unknown action_type: ${item.action_type}` } }];\n}\n\n// Mark as executed in the queue\nconst queueIdx = staticData.queue.findIndex(q => q.id === item.id);\nif (queueIdx >= 0) {\n  staticData.queue[queueIdx].status = 'executed';\n  staticData.queue[queueIdx].executed_at = new Date().toISOString();\n}\n\n// Prune completed items older than 24 hours\nconst oneDayAgo = new Date(Date.now() - 86400000).toISOString();\nstaticData.queue = staticData.queue.filter(q =>\n  q.status === 'pending' || (q.executed_at && q.executed_at > oneDayAgo)\n);\n\nreturn [{\n  json: {\n    status: 'executed',\n    id: item.id,\n    action_type: item.action_type,\n    target_urn: item.target_urn,\n    endpoint: endpoint\n  }\n}];"
      },
      "id": "process-queue",
      "name": "Process Queue",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        680,
        200
      ]
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Read Queue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Queue": {
      "main": [
        [
          {
            "node": "Process Queue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "HMAC Verify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HMAC Verify": {
      "main": [
        [
          {
            "node": "Is Verified?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Verified?": {
      "main": [
        [
          {
            "node": "Enqueue Action",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reject 401",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enqueue Action": {
      "main": [
        [
          {
            "node": "Respond Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "meta": {
    "notes": "T049: Action runner with dual trigger. Schedule (every 5 min) processes due queue items by calling linkedin-like or linkedin-comment webhooks. Webhook trigger allows OpenClaw to enqueue new actions with HMAC verification. Queue is managed via Workflow Static Data."
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

[FUTURE] action-runner. Scheduled trigger; 9 nodes.

Source: https://github.com/traylorre/openclaw-mac/blob/d5ef2bd70e230b1877d7165d35c2e27947b269e0/workflows/action-runner.json — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

General

This template is an interactive playground designed to help you master the most useful keyboard shortcuts in n8n and supercharge your building speed. Forget boring lists—this workflow gives you hands-

General

Workflow 2469. Uses moveBinaryData, googleDrive, itemLists, n8n. Scheduled trigger; 33 nodes.

Move Binary Data, Google Drive, Item Lists +1
General

Perfect for content publishing with organic scheduling patterns, social media automation, API systems that need to avoid rate limiting, or any automation requiring randomised timing control across mul

n8n, Read Write File, Stop And Error +1
General

Complete backup solution that saves both workflows and credentials to local/server disk with optional FTP upload for off-site redundancy.

Read Write File, Email Send, Execute Command +3
General

todoist automate. Uses todoist, executionData. Scheduled trigger; 27 nodes.

Todoist, Execution Data