【问题标题】:Sending multiple reply messages on single postback in Facebook Messenger Bots在 Facebook Messenger Bots 中的单个回发中发送多条回复消息
【发布时间】:2018-05-09 01:17:57
【问题描述】:

我想在 Messenger 上为单个用户触发的回发发送多个回复。我一直在关注 Messenger 的 developer documentation 并且真的找不到如何做到这一点。

我的代码结构与他们在网站上提供的教程非常相似,我有一个“handlePostback”函数,用于识别收到的回发并将其与一组预定义的有效负载进行比较以查找'response' JSON 对象。此响应将提供给“callSendAPI”,它将此 JSON 对象转换为将消息发送回 Messenger API 的基本格式。

function handlePostback(sender_psid,receivedPostback)
{ if(payload== 'defined_payload') {
  response = {
  text: 'Some text'
  };
callSendAPI(sender_psid,response);
}

function callSendAPI(sender_psid,response) {
let body = {
recipient: {
id= sender_psid
},
message: response
};
// Followed by code for POST request to the webhook
}

这是基本结构,现在我想发送多条消息作为对一个回发的回复。我做了一些挖掘,我发现解决方案可能是创建一个 message [] 数组。但是我该怎么做呢?因为我的“响应”是通过该函数生成的,消息结构应该是这样的(我认为):

let body = {
 recipient: {
 id=sender_psid
 },
 messages: [ {
  response1
  },
  {
  response2
  }
 ]
};

我希望我能解释我的问题,如果我能提供更多细节,请告诉我!

【问题讨论】:

    标签: json node.js facebook facebook-messenger-bot facebook-chatbot


    【解决方案1】:

    好问题。如果您不熟悉 Node.js,那么实现它的方法不是很明显,并且 Facebook 的 Send API 文档中没有很好地记录这一点。

    首先,您可能已经观察到,使用数组发送多条消息的方法行不通。 Facebook 有一个解决方案,可以通过一个请求发送多达 100 个 API 调用,但我认为这在您的情况下是不需要的。如果您想了解更多信息,请查看Batched Request Documentation,您会发现实现与您的不同。

    一种可行的解决方案是多次调用callSendAPI 函数。 但此解决方案有一个主要缺点:您将无法控制发送消息的实际顺序。例如,如果您想发送两条单独的消息,您不能保证哪个会先发送给用户

    要解决此问题,您需要以某种方式链接您的callSendAPI 函数,以保证下一个callSendAPI 调用将仅在第一条消息已发送后发生。您可以在 NodeJS 中通过使用回调或承诺来做到这一点。如果您对其中任何一个都不熟悉,可以阅读 this 了解回调,阅读 this 了解承诺。

    您需要修改callSendAPI 函数,尤其是向Facebook 发送POST 请求的部分。我将使用 promises 和模块 node-fetch 为您的问题提供解决方案。

    const fetch = require('node-fetch');
    
    function handlePostback(sender_psid,receivedPostback){ 
      if (payload == 'defined_payload') {
        response = {
          text: 'Some text'
        };
        response2 = //... Another response
        response3 = //... Another response
      callSendAPI(sender_psid,response).then(() => {
        return callSendAPI(sender_psid, response2).then(() => {
          return callSendAPI(sender_psid, response3); // You can add as many calls as you want
          });
       });
      }
    }
    
    function callSendAPI(sender_psid,response) {
      let body = {
        recipient: {
          id= sender_psid
        },
        message: response
      };
      const qs = 'access_token=' + encodeURIComponent(FB_PAGE_TOKEN); // Here you'll need to add your PAGE TOKEN from Facebook
      return fetch('https://graph.facebook.com/me/messages?' + qs, {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(body),
      });
    }

    【讨论】:

    • 嗨,当我实现上述方法时,我得到“TypeError:无法读取未定义的属性'then'”。响应 2 永远不会出现,响应 1 会三次发送给用户。
    • 如果我没有看到您的代码,我无法确切知道出了什么问题。不过我很乐意提供帮助:)
    • 您好,我已在答案中添加了以下代码。让我知道这是否足以让您回答。
    【解决方案2】:

    我发现下面的链接对于整理在单个回发中实现多个响应的方式很有用。

    https://codingislove.com/build-facebook-chat-bot-javascript/

    就像你说的,数组应该可以工作。创建一个包含多个响应消息的数组变量

    var multipleResponse = {
       messages: [{
          response1
       },
       {
          response2
       }]
    };
    

    并将数组变量推送到您的函数

    function callSendAPI(sender_psid,response) {
    
        let body = {
             recipient: {
                id= sender_psid
             },
             message: []
        };
        // Followed by code for POST request to the webhook
    }
    

    最后将数组推送到你的函数数组

    body.message.push(multipleResponse.messages);
    

    【讨论】:

    【解决方案3】:

    @Christos Panagiotakopoulos。我没有得到使用 then 链接的 mainMenuResponse。相反,我得到了三次响应。 处理回传函数 =>

    // Handles messaging_postbacks events
    function handlePostback(sender_psid, received_postback) {
      let response;
    
      // Get the payload for the postback
      let payload = received_postback.payload;
    
      // Set the response based on the postback payload
      if (payload === 'fashionTip') {
        response = { "text": getFashionTip() } // calls a function which gives a fashion-tip
    
      // Send the message to acknowledge the postback
      callSendAPI(sender_psid, response).then(() => {
        return callSendAPI(sender_psid, mainMenuResponse)
      });
    

    callSendAPI 函数 =>

    // Sends response messages via the Send API
    function callSendAPI(sender_psid, response) {
      // construct the message body
      let request_body = {
        "recipient": {
          "id": sender_psid
        },
        "message": response
      }
    
      // Send the HTTP request to the messenger platform
      request({
        "uri": "https://graph.facebook.com/v2.6/me/messages",
        "qs": {"access_token": PAGE_ACCESS_TOKEN},
        "method": "POST",
        "json": request_body
      }, (err, res, body) => {
        if (!err) {
          console.log("Message sent!");
        } else {
          console.error("Unable to send mesage:" + err);
        }
      });
    }
    

    【讨论】:

    • 与我使用“node-fetch”执行 POST 请求的示例相反,您使用的是“request”。两者的区别在于“node-fetch”返回一个promise,而“request”使用回调并返回void。您需要使用与承诺兼容的功能来执行请求,或承诺“请求”功能。如果您想保留相同的 api,我建议转换为“node-fetch”或使用“request-promise-native”包。
    • 谢谢您,先生,能够使用 node-fetch。虽然无法使 request-promise-native 为它工作。非常感谢。
    【解决方案4】:

    不要修改callSendAPI 函数。在您的handlePostback 函数中多次调用callSendAPI

    callsendAPI(sender_psid,response1);
    callsendAPI(sender_psid,response2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      • 2016-10-26
      • 2017-06-04
      • 2016-08-06
      相关资源
      最近更新 更多