8
n8n 中文网amn8n.com

自动化 Zalo OA 令牌管理,集成 OAuth 和 Webhook

中级

这是一个Engineering, DevOps, Multimodal AI领域的自动化工作流,包含 10 个节点。主要使用 Set, Code, Webhook, HttpRequest, ScheduleTrigger 等节点。 自动化 Zalo OA 令牌管理,集成 OAuth 和 Webhook

前置要求
  • HTTP Webhook 端点(n8n 会自动生成)
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "9a562c06a632241f66aadd52a495ad98e76b760ef5cfce9c319a4759c47cd94e"
  },
  "nodes": [
    {
      "id": "df8fb435-f49e-4dec-8ed5-0b5b536ceab3",
      "name": "存储到静态数据并传递令牌",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        0
      ],
      "parameters": {
        "jsCode": "const sd = $getWorkflowStaticData('global');\nconst r = $input.first().json || {};\nconst now = Date.now();\nsd.zalo = sd.zalo || {};\nif (r.access_token) sd.zalo.access_token = r.access_token;\nif (r.refresh_token) sd.zalo.refresh_token = r.refresh_token;\nconst exp = parseInt(r.expires_in, 10);\nif (!isNaN(exp)) sd.zalo.access_expires_at = now + exp * 1000;\nconst rExp = parseInt(r.refresh_token_expires_in, 10);\nif (!isNaN(rExp)) sd.zalo.refresh_expires_at = now + rExp * 1000;\n// IMPORTANT: return the refreshed token in the CURRENT ITEM\nreturn [{ json: {\n  source: \"refreshed\",\n  access_token: sd.zalo.access_token,\n  access_expires_at: sd.zalo.access_expires_at\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "5676141d-7a9e-4872-900a-48d7a7c59cc2",
      "name": "刷新令牌 (Zalo v4)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        64,
        0
      ],
      "parameters": {
        "url": "https://oauth.zaloapp.com/v4/oa/access_token",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "refresh_token",
              "value": "={{ $json.refresh_token }}"
            },
            {
              "name": "app_id",
              "value": "={{ $json.app_id }}"
            },
            {
              "name": "grant_type",
              "value": "refresh_token"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "secret_key",
              "value": "={{ $('Set Refresh Token and App ID').item.json.secret_key }}"
            }
          ]
        }
      },
      "typeVersion": 3
    },
    {
      "id": "65bbbd29-24ae-475d-80d2-674da63db2eb",
      "name": "调度触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -848,
        16
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 12
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "62cbb107-ef08-4b09-b061-ecb9ae02c626",
      "name": "执行_节点",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -848,
        -176
      ],
      "webhookId": "99397651-be96-4106-9017-3e62f0ddf03e",
      "parameters": {
        "path": "99397651-be96-4106-9017-3e62f0ddf03e",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "21029f3c-0080-4950-80f5-965cc4259239",
      "name": "清理 Zalo 静态数据",
      "type": "n8n-nodes-base.code",
      "position": [
        -608,
        -176
      ],
      "parameters": {
        "jsCode": "const sd = $getWorkflowStaticData('global');\ndelete sd['zalo'];\nreturn [{ json: { cleared: true } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d80a21bf-9e3a-4125-9657-38520907f78a",
      "name": "设置刷新令牌和应用 ID",
      "type": "n8n-nodes-base.set",
      "position": [
        -384,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "125b6083-9cac-4c88-b1c9-968cfe06a5d3",
              "name": "refresh_token",
              "type": "string",
              "value": "refresh_token_initial_refesh_token"
            },
            {
              "id": "d8e706c2-9609-4780-95d7-e3c5297a0cee",
              "name": "app_id",
              "type": "string",
              "value": "your_oa_app_id"
            },
            {
              "id": "8230a16f-3100-4fdb-9125-317f1c63fd23",
              "name": "secret_key",
              "type": "string",
              "value": "your_app_secret_key"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "37a79c0a-08c2-4a9b-9655-aa2e49c2f36c",
      "name": "加载到静态数据",
      "type": "n8n-nodes-base.code",
      "position": [
        -176,
        0
      ],
      "parameters": {
        "jsCode": "const sd = $getWorkflowStaticData('global');\nconst now = Date.now();\nconst bufferMs = 90 * 1000; // refresh 90s early\nsd.zalo =    sd.zalo || {};\nconsole.log('new code #### here this is',sd.zalo);\n// Seed refresh token on very first run\nif (!sd.zalo.refresh_token) {\n  sd.zalo.refresh_token =  $input.first().json.refresh_token;\n}\n\nconst hasAccess = !!sd.zalo.access_token;\nconst notExpired = !!sd.zalo.access_expires_at && (sd.zalo.access_expires_at - bufferMs) > now;\nconst needs_refresh = !(hasAccess && notExpired);\n\nreturn [{\n  json: {\n    needs_refresh,\n    access_token: sd.zalo.access_token || null,\n    access_expires_at: sd.zalo.access_expires_at || null,\n    refresh_token: sd.zalo.refresh_token || null,\n    app_id: $input.first().json.app_id\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "25f68c0d-9eef-43be-accc-60bae7d62065",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -848,
        240
      ],
      "webhookId": "5afc66e9-136e-4fb2-9263-9aaa1c1037ef",
      "parameters": {
        "path": "zalo-intergration-v1",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e96e8fdf-e031-4afc-b1ab-b6f1b9837158",
      "name": "加载访问令牌",
      "type": "n8n-nodes-base.code",
      "position": [
        -592,
        240
      ],
      "parameters": {
        "jsCode": "const sd = $getWorkflowStaticData('global');\nsd.zalo =    sd.zalo || {};\nreturn [{\n  json: {\n    access_token: sd.zalo.access_token || null,\n    access_expires_at: sd.zalo.access_expires_at || null,\n    refresh_token: sd.zalo.refresh_token || null,\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "43e752b8-ec85-4764-addb-71383e69217d",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1856,
        -848
      ],
      "parameters": {
        "width": 944,
        "height": 1712,
        "content": "# Zalo OA 令牌自动刷新 (n8n)"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Load Access Token",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute_Node": {
      "main": [
        [
          {
            "node": "Clean Zalo Static Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Set Refresh Token and App ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load to Static Data": {
      "main": [
        [
          {
            "node": "Refresh Token (Zalo v4)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean Zalo Static Data": {
      "main": [
        [
          {
            "node": "Set Refresh Token and App ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Refresh Token (Zalo v4)": {
      "main": [
        [
          {
            "node": "Store to SD & Pass token",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Refresh Token and App ID": {
      "main": [
        [
          {
            "node": "Load to Static Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 工程, 开发运维, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量10
分类3
节点类型6
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者
Le Nguyen

Le Nguyen

@leeseifer

Salesforce Architect with 10+ years of experience in CRM, integrations, and automation. Skilled in Apex, LWC, REST APIs, and full-stack dev (JavaScript, .NET). I build secure, scalable workflows in n8n—connecting Salesforce, Stripe, and more. Passionate about lead scoring, data sync, and secure field masking. Certified Application Architect with deep expertise in platform, integration, and data architecture.

外部链接
在 n8n.io 查看

分享此工作流