如何在Dialogflow的Node.js Webhook中按渠道返回不同响应?
Hey Pablo, let's get your webhook to serve channel-specific responses—here's how to tweak your Node.js code to make that happen!
The Core Issue
Your current code doesn't check which channel the user is coming from (Telegram, Facebook, Line, etc.). Dialogflow sends channel metadata in the originalRequest field of the incoming payload, so we just need to grab that and adjust our responses accordingly.
Updated Webhook Code
Here's the modified version of your code that handles different channels:
"use strict"; const express = require("express"); const bodyParser = require("body-parser"); const restService = express(); restService.use(bodyParser.urlencoded({ extended: true })); restService.use(bodyParser.json()); restService.post("/webhook", function(req, res) { // Grab the user's channel (fallback to 'default' if no data exists) const channel = req.body.originalRequest ? req.body.originalRequest.source : "default"; const tipo = req.body.result?.parameters?.tipo?.toLowerCase(); let speech, displayText; if (tipo) { const responseData = getChannelSpecificResponse(tipo, channel); speech = responseData.speech; displayText = responseData.displayText; } else { speech = "Ups... ha habido algún problema con nuestra comunicación, sorry!"; displayText = speech; } return res.json({ speech: speech, displayText: displayText, source: "webhook-echo-sample" }); }); let getChannelSpecificResponse = function(tipo, channel) { // First get the base Moodle URL based on the tipo let baseUrl; switch(tipo) { case "daw": baseUrl = "http://moodle.iesgrancapitan.org/course/index.php?categoryid=7"; break; case "asir": baseUrl = "http://moodle.iesgrancapitan.org/course/index.php?categoryid=4"; break; default: return { speech: "Vaya... Creo que algo fue mal", displayText: "Vaya... Creo que algo fue mal" }; } // Now customize the response for each channel switch(channel) { case "telegram": // Use Telegram's Markdown formatting for better readability return { speech: `Aquí tienes el enlace para *${tipo.toUpperCase()}*: [Ir a Moodle](${baseUrl})`, displayText: `Aquí tienes el enlace para ${tipo.toUpperCase()}: ${baseUrl}` }; case "facebook": // Keep it friendly for Facebook Messenger users return { speech: `¡Aquí está el recurso para ${tipo.toUpperCase()}! ${baseUrl}`, displayText: `¡Aquí está el recurso para ${tipo.toUpperCase()}! ${baseUrl}` }; case "line": // Line-friendly wording return { speech: `Para acceder a ${tipo.toUpperCase()}, usa este enlace: ${baseUrl}`, displayText: `Para acceder a ${tipo.toUpperCase()}, usa este enlace: ${baseUrl}` }; default: // Fallback for unrecognized channels or testing in Dialogflow console return { speech: baseUrl, displayText: baseUrl }; } }; restService.listen(process.env.PORT || 8000, function() { console.log("Server up and listening"); });
Key Changes Explained
- Channel Detection: We pull the channel from
req.body.originalRequest.source—Dialogflow automatically populates this with values like"telegram","facebook", or"line"depending on where the user is messaging from. - Channel-Specific Responses: The new
getChannelSpecificResponsefunction first grabs the base Moodle URL, then formats the message to fit each channel's style (e.g., Markdown for Telegram, casual tone for Facebook). - Fallback Handling: We added a
defaultcase for both thetipoandchannelswitches to handle unexpected inputs gracefully.
Bonus: Advanced Channel Customization
If you want to use channel-specific features (like Telegram's inline keyboards or Facebook's quick replies), you can add a payload field to your response JSON. For example, to send a formatted Telegram message:
return res.json({ speech: speech, displayText: displayText, source: "webhook-echo-sample", payload: { "telegram": { "text": `Aquí tienes el enlace para *${tipo.toUpperCase()}*: [Ir a Moodle](${baseUrl})`, "parse_mode": "Markdown" } } });
Just make sure your Dialogflow agent is properly integrated with each channel—this ensures the originalRequest data is sent to your webhook correctly.
内容的提问来源于stack exchange,提问作者Pablo León

