You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js/Express搭建Dialogflow Webhook遇错误及自定义Payload发送问题

解决Dialogflow Webhook "Invalid or unknown request type" 错误并实现自定义Payload发送

一、修复"Invalid or unknown request type"错误

1. 替换过时依赖

原dialogflow-fulfillment包已停止维护,迁移到官方新版@dialogflow/fulfillment,移除旧版actions-on-google(无需适配Google Assistant时)。更新后的package.json依赖:

"dependencies": {
    "@dialogflow/fulfillment": "^0.6.1",
    "axios": "^1.5.0",
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "express": "^4.18.2"
}

执行npm install更新依赖。

2. 配置CORS中间件

Dialogflow Messenger的请求属于跨域请求,必须添加CORS支持:

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const { WebhookClient } = require("@dialogflow/fulfillment");

const app = express();
// 生产环境建议限制特定域名,此处允许所有来源测试
app.use(cors());
app.use(bodyParser.json());

3. 验证Dialogflow控制台配置

在Dialogflow控制台Fulfillment页面:

  • 确认Webhook URL指向你的服务地址
  • 选择Webhook version为V2(旧版库不支持V3)
  • 勾选需要触发Webhook的目标意图(如webhookDemo)

4. 强制指定请求版本(可选)

若自动版本检测失败,手动指定v2版本初始化WebhookClient:

const agent = new WebhookClient({ 
  request: req, 
  response: res,
  version: 'v2'
});

二、实现Dialogflow Messenger自定义Payload发送

自定义Payload支持发送按钮、图片、卡片等富媒体消息,以下是常见示例:

1. 文本+自定义按钮示例

// 顶部导入Payload
const { WebhookClient, Payload } = require("@dialogflow/fulfillment");

function demo(agent) {
  // 基础文本回复
  agent.add("Message from webhook server");
  
  // Dialogflow Messenger自定义Payload
  const payload = {
    "richContent": [
      [
        {
          "type": "button",
          "icon": {
            "type": "chevron_right",
            "color": "#FF9800"
          },
          "text": "查看详情",
          "link": "https://example.com/details",
          "buttonText": "点击访问"
        }
      ]
    ]
  };
  
  agent.add(new Payload(agent.UNSPECIFIED, payload, { rawPayload: true, sendAsMessage: true }));
}

2. 图片卡片示例

function demo(agent) {
  const payload = {
    "richContent": [
      [
        {
          "type": "image",
          "rawUrl": "https://example.com/cover.jpg",
          "accessibilityText": "产品封面图"
        },
        {
          "type": "info",
          "title": "产品名称",
          "subtitle": "产品简介"
        }
      ]
    ]
  };
  agent.add(new Payload(agent.UNSPECIFIED, payload, { rawPayload: true }));
}

3. 直接构造响应(无WebhookClient)

若WebhookClient仍有问题,可直接返回符合v2格式的响应:

app.post("/", (req, res) => {
  const intentName = req.body.queryResult.intent.displayName;
  
  if (intentName === "webhookDemo") {
    const responseJson = {
      fulfillmentMessages: [
        {
          text: { text: ["Message from webhook server"] }
        },
        {
          payload: {
            "richContent": [
              [
                {
                  "type": "button",
                  "text": "自定义按钮",
                  "link": "https://example.com"
                }
              ]
            ]
          }
        }
      ]
    };
    res.json(responseJson);
  } else {
    res.json({ fulfillmentText: "默认回复" });
  }
});

完整修复后server.js示例

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const { WebhookClient, Payload } = require("@dialogflow/fulfillment");

const app = express();
app.use(cors());
app.use(bodyParser.json());

app.post("/", (req, res) => {
  const agent = new WebhookClient({ 
    request: req, 
    response: res,
    version: 'v2'
  });

  function demo(agent) {
    agent.add("Message from webhook server");
    
    const dfMessengerPayload = {
      "richContent": [
        [
          {
            "type": "button",
            "text": "查看详情",
            "link": "https://example.com/details",
            "buttonText": "点击访问"
          },
          {
            "type": "image",
            "rawUrl": "https://example.com/cover.jpg",
            "accessibilityText": "产品封面"
          }
        ]
      ]
    };
    
    agent.add(new Payload(agent.UNSPECIFIED, dfMessengerPayload, { rawPayload: true }));
  }

  let intentMap = new Map();
  intentMap.set("webhookDemo", demo);

  agent.handleRequest(intentMap);
});

const port = process.env.PORT || 8000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

内容的提问来源于stack exchange,提问作者reverse_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:35:55