如何使用Azure Bot Channels Registration + Botbuilder SDK来捕捉Facebook messages_optins?

时间:2018-07-12 19:36:43

标签: node.js facebook azure botframework facebook-messenger

我已经建立并运行了一个聊天机器人,它是使用Node.JS Microsoft Bot Framework构建的,并已作为Web应用程序部署到Azure服务器,并且使用Bot Channels Registration资源作为前端端点。

此Bot频道注册已通过FB App连接到Facebook Messenger,这意味着Facebook App的网络挂钩指向https://facebook.botframework.com/api/v1/bots/<BOT_CHANNELS_REGISTRATION_RESOURCE_NAME>

对于正常的聊天功能,这一切都很好。

但是,我现在想将opt-in checkbox添加到一个单独的网页中。此复选框通过对FB进行ping操作,然后将一个非常特定的有效负载发送到已配置的bot webhook。

{
  "recipient":{
    "id":"<PAGE_ID>"
  },
  "timestamp":<UNIX_TIMESTAMP>,
  "optin":{
    "ref":"<PASS_THROUGH_PARAM>",
    "user_ref":"<UNIQUE_REF_PARAM>"
  }
}

我的问题是这个:

机器人通道注册如何接收和处理上述有效载荷?它会自动将其转发到我在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中停止。目前正在寻找解决这一主要障碍的方法。

1 个答案:

答案 0 :(得分:2)

因此,根据@JJ_Wailes调查,似乎这不是受支持的功能(实际上,这是当前的功能请求)。有关更多详细信息,请参阅他对原始帖子的评论。

但是,对于那些感兴趣的人,我确实找到了一种半解决方法来捕获由checkbox_plugin生成的user_ref标识符:

1)从您的外部站点,按照文档here中的步骤将初始user_ref发送到FB。然后,FB会向您的漫游器进行标注,但是根据上述说明,该标注会被Bot Channels Registration部分阻止,因此将被忽略。

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