如何在Dialogflow ES的Fulfillment内联编辑器中给Telegram Bot发送内联键盘
问题:Dialogflow ES Fulfillment 发送Telegram内联键盘失败,提示无法读取'chat'属性
问题详情
我在使用Dialogflow ES Fulfillment内联编辑器开发Telegram Bot时,需要发送包含API数据的inline_keyboard。先尝试发送静态内联键盘,却出现结构错误,系统无法识别'chat'或'payload'属性。我搜索了各类帖子、视频、文档,甚至借助GPT都没能解决问题。期间试过node-telegram-bot-api、messaging-api-telegram、Telegraf等库,但发现这些库的标准集成方式和Fulfillment的令牌无法同时使用,最终报错提示无法读取undefined的'chat'属性。
代码片段
index.js(需替换令牌)
const functions = require('firebase-functions'); const { WebhookClient, Payload } = require('dialogflow-fulfillment'); // 尝试用第三方库的示例(冲突原因) // const TelegramBot = require('node-telegram-bot-api'); // const bot = new TelegramBot('YOUR_TELEGRAM_TOKEN', { polling: false }); exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => { const agent = new WebhookClient({ request, response }); function testInlineKeyboard(agent) { // 错误的尝试:直接调用第三方库方法,导致令牌冲突+chat属性未定义 // bot.sendMessage(agent.request.body.chat.id, '选择选项', { // reply_markup: { inline_keyboard: [[{text: '测试按钮', callback_data: 'test'}]] } // }); // 尝试构造Payload但结构错误 agent.add(new Payload('TELEGRAM', { text: '请选择', reply_markup: { inline_keyboard: [[{text: '测试按钮', callback_data: 'test'}]] } }, { rawPayload: true })); } let intentMap = new Map(); intentMap.set('TestInlineKeyboard', testInlineKeyboard); agent.handleRequest(intentMap); });
package.json
{ "name": "dialogflow-fulfillment", "version": "0.0.1", "description": "Dialogflow Fulfillment for Telegram Bot", "main": "index.js", "dependencies": { "dialogflow-fulfillment": "^0.6.1", "firebase-functions": "^3.20.0", // 尝试引入的第三方库 // "node-telegram-bot-api": "^0.61.0" } }
错误日志
TypeError: Cannot read properties of undefined (reading 'chat') at testInlineKeyboard (/workspace/index.js:14:35) at WebhookClient.handleRequest (/workspace/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:309:44) at exports.dialogflowFirebaseFulfillment.functions.https.onRequest (/workspace/index.js:24:9)
解决方案
1. 放弃第三方Telegram库,直接用Dialogflow Payload构造响应
Dialogflow已和Telegram完成集成,无需单独初始化Telegram Bot实例(会导致令牌冲突),直接通过Payload构造符合Telegram API格式的响应即可,关键是从Dialogflow传递的请求数据中获取chat_id:
function testInlineKeyboard(agent) { // 从原始请求中提取Telegram的chat信息 const telegramData = agent.request.body.originalDetectIntentRequest.payload.data; const chatId = telegramData.chat.id; // 构造内联键盘 const inlineKeyboard = { inline_keyboard: [ [{ text: '按钮1', callback_data: 'btn_1' }], [{ text: '按钮2', callback_data: 'btn_2' }] ] }; // 构造符合Telegram API要求的Payload const telegramPayload = new Payload('TELEGRAM', { method: 'sendMessage', chat_id: chatId, text: '请选择下方选项:', reply_markup: inlineKeyboard }, { rawPayload: true }); agent.add(telegramPayload); }
2. 确认请求数据结构
调试时可以打印agent.request.body,确认originalDetectIntentRequest.payload.data中包含完整的Telegram消息数据(包括chat对象):
console.log(JSON.stringify(agent.request.body, null, 2));
3. 检查Dialogflow集成配置
- 确保Telegram Bot已在Dialogflow ES的集成页面正确配置,令牌填写无误
- 确认Fulfillment的Webhook已启用,且Telegram的消息能正常触发Webhook
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

