如何使用 Azure Bot Channels Registration + Botbuilder SDK 捕获 Facebook messaging_optins?
How to catch Facebook messaging_optins with Azure Bot Channels Registration + Botbuilder SDK?
我有一个聊天机器人 运行,使用 Node.JS Microsoft Bot Framework 构建,并作为 Web 应用程序部署到 Azure 服务器,以 Bot Channels Registration 资源作为前端端点。
此 Bot Channels Registration 连接到 Facebook Messenger(通过 FB App)——意思是,Facebook App 的 webhook 指向 https://facebook.botframework.com/api/v1/bots/<BOT_CHANNELS_REGISTRATION_RESOURCE_NAME>
。
这一切都适用于正常的聊天功能。
但是,我现在想将 opt-in checkbox 添加到我拥有的单独网页中。此复选框通过 ping FB 来工作,然后将非常具体的有效负载发送到已配置的 bot webhook。
{
"recipient":{
"id":"<PAGE_ID>"
},
"timestamp":<UNIX_TIMESTAMP>,
"optin":{
"ref":"<PASS_THROUGH_PARAM>",
"user_ref":"<UNIQUE_REF_PARAM>"
}
}
我的问题是:
Bot Channels Registration 如何接收和处理上述负载?它会自动将其转发到我在 Bot Channels Registration 设置中配置的 Messaging Endpoint 吗?或者它会卡住,永远无法访问我的实际机器人 Web 应用程序吗?
最后,如果它 确实 到达我的正常消息端点,我如何使用我的 botbuilder.ChatConnector()
侦听器处理特定负载?鉴于我的网络应用程序代码看起来像(本质上)
var restify = require('restify');
var builder = require('botbuilder');
var dialogues = require('./dialogues');
var chatbot = function (config) {
var bot = {};
chatbot.listen = function () {
var stateStorage = new builder.MemoryBotStorage();
var connector = new builder.ChatConnector({
appId: process.env.APP_ID,
appPassword: process.env.APP_PASSWORD
});
bot = new builder.UniversalBot(connector, function (session) {
session.beginDialog(dialogues.base(bot).name);
}).set('storage', stateStorage);
return connector.listen();
};
return chatbot;
}
var server = restify.createServer();
// Listen for messages from users
server.post('/api/messages', chatbot.listen());
server.listen(process.env.port, function () {
console.log('%s listening to %s', server.name, server.url);
});
谢谢!
编辑: 我已经想出了如何在我的消息传递端点内处理上述有效负载 - 通过向我的服务器添加一个 server.pre()
处理程序,例如
server.pre(function (req, res, next) {
if (req.body && req.body.optin_payload_specific_field){
// handle opt-in payload
} else {
return next();
}
});
但是,通过额外的日志行,选择加入的有效负载似乎甚至没有到达此端点。它似乎在 Bot Channels Registration 中停止了。目前正在寻找解决该主要障碍的方法。
因此,根据@JJ_Wailes 调查,这似乎不是受支持的功能(实际上,这是当前的功能请求)。有关详细信息,请参阅他对原始 post 的评论。
但是,对于那些感兴趣的人,我确实找到了一个半解决方法来捕获 checkbox_plugin 生成的 user_ref
标识符:
1) 从您的外部站点,按照文档 here 中的步骤将初始 user_ref 发送到 FB。然后,FB 将向您的机器人发出标注,但根据上述内容,该标注会被机器人频道注册部分阻止,因此将被忽略。
2) 从同一个外部站点,使用 user_ref
向用户发送消息(只需使用普通的 requests
库)。成功发送意味着 user_ref
已通过第 1 步调用在 FB 中正确注册 - 失败意味着您需要重复第 1 步(或使用其他错误处理流程)。
3) 之后,下次用户在 FB 中回复您的机器人时(只要您不向他们发送任何其他消息),您的机器人将收到的消息将包含此作为有效载荷:
{ ...
channelData:
{ ...
prior_message:
{ source: 'checkbox_plugin',
identifier: <user_ref> }
}
}
所以我目前在我的 bot.use()
中添加了一个检查,如果该部分出现在传入消息有效负载 (session.message.sourceEvent.prior_message
) 中并且源是 "checkbox_plugin",我将相应的 user_ref 存储在 session.userData
中,然后可以从那里开始工作。
我 喜欢 看到这个功能被添加到受支持的 Azure 机器人堆栈中,但与此同时希望这能帮助其他遇到这个(公认的小众)障碍的人。
我有一个聊天机器人 运行,使用 Node.JS Microsoft Bot Framework 构建,并作为 Web 应用程序部署到 Azure 服务器,以 Bot Channels Registration 资源作为前端端点。
此 Bot Channels Registration 连接到 Facebook Messenger(通过 FB App)——意思是,Facebook App 的 webhook 指向 https://facebook.botframework.com/api/v1/bots/<BOT_CHANNELS_REGISTRATION_RESOURCE_NAME>
。
这一切都适用于正常的聊天功能。
但是,我现在想将 opt-in checkbox 添加到我拥有的单独网页中。此复选框通过 ping FB 来工作,然后将非常具体的有效负载发送到已配置的 bot webhook。
{
"recipient":{
"id":"<PAGE_ID>"
},
"timestamp":<UNIX_TIMESTAMP>,
"optin":{
"ref":"<PASS_THROUGH_PARAM>",
"user_ref":"<UNIQUE_REF_PARAM>"
}
}
我的问题是:
Bot Channels Registration 如何接收和处理上述负载?它会自动将其转发到我在 Bot Channels Registration 设置中配置的 Messaging Endpoint 吗?或者它会卡住,永远无法访问我的实际机器人 Web 应用程序吗?
最后,如果它 确实 到达我的正常消息端点,我如何使用我的 botbuilder.ChatConnector()
侦听器处理特定负载?鉴于我的网络应用程序代码看起来像(本质上)
var restify = require('restify');
var builder = require('botbuilder');
var dialogues = require('./dialogues');
var chatbot = function (config) {
var bot = {};
chatbot.listen = function () {
var stateStorage = new builder.MemoryBotStorage();
var connector = new builder.ChatConnector({
appId: process.env.APP_ID,
appPassword: process.env.APP_PASSWORD
});
bot = new builder.UniversalBot(connector, function (session) {
session.beginDialog(dialogues.base(bot).name);
}).set('storage', stateStorage);
return connector.listen();
};
return chatbot;
}
var server = restify.createServer();
// Listen for messages from users
server.post('/api/messages', chatbot.listen());
server.listen(process.env.port, function () {
console.log('%s listening to %s', server.name, server.url);
});
谢谢!
编辑: 我已经想出了如何在我的消息传递端点内处理上述有效负载 - 通过向我的服务器添加一个 server.pre()
处理程序,例如
server.pre(function (req, res, next) {
if (req.body && req.body.optin_payload_specific_field){
// handle opt-in payload
} else {
return next();
}
});
但是,通过额外的日志行,选择加入的有效负载似乎甚至没有到达此端点。它似乎在 Bot Channels Registration 中停止了。目前正在寻找解决该主要障碍的方法。
因此,根据@JJ_Wailes 调查,这似乎不是受支持的功能(实际上,这是当前的功能请求)。有关详细信息,请参阅他对原始 post 的评论。
但是,对于那些感兴趣的人,我确实找到了一个半解决方法来捕获 checkbox_plugin 生成的 user_ref
标识符:
1) 从您的外部站点,按照文档 here 中的步骤将初始 user_ref 发送到 FB。然后,FB 将向您的机器人发出标注,但根据上述内容,该标注会被机器人频道注册部分阻止,因此将被忽略。
2) 从同一个外部站点,使用 user_ref
向用户发送消息(只需使用普通的 requests
库)。成功发送意味着 user_ref
已通过第 1 步调用在 FB 中正确注册 - 失败意味着您需要重复第 1 步(或使用其他错误处理流程)。
3) 之后,下次用户在 FB 中回复您的机器人时(只要您不向他们发送任何其他消息),您的机器人将收到的消息将包含此作为有效载荷:
{ ...
channelData:
{ ...
prior_message:
{ source: 'checkbox_plugin',
identifier: <user_ref> }
}
}
所以我目前在我的 bot.use()
中添加了一个检查,如果该部分出现在传入消息有效负载 (session.message.sourceEvent.prior_message
) 中并且源是 "checkbox_plugin",我将相应的 user_ref 存储在 session.userData
中,然后可以从那里开始工作。
我 喜欢 看到这个功能被添加到受支持的 Azure 机器人堆栈中,但与此同时希望这能帮助其他遇到这个(公认的小众)障碍的人。