如何使用 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 机器人堆栈中,但与此同时希望这能帮助其他遇到这个(公认的小众)障碍的人。