问题
I want to send multiple replies for a single user-triggered postback on Messenger. I've been following Messenger's developer documentation and couldn't really find how to do this.
My code structure is very similar to the tutorials they've given on the site, I have a 'handlePostback' function which identifies the received postback and compares it to a set of predefined payloads to find the 'response' JSON object. This response is given to 'callSendAPI' which puts this JSON object into the basic format of sending the message back to the 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
}
This being the basic structure, now I want to send multiple messages as a reply to one postback. I did some digging, and I found that the solution might be to create a message [] array. But how do I do this? Because my 'response' is being generated through that function, and the messages structure should look like this (I think):
let body = {
recipient: {
id=sender_psid
},
messages: [ {
response1
},
{
response2
}
]
};
I hope I could explain my question, please let me know if I can provide more details!
回答1:
Nice question. If you are not familiar with Node.js the way to do it is not too obvious and this is not documented well on Facebook's Send API Documentation.
Firstly, your approach of sending multiple messages, using an array, as you may have observed won't work. Facebook has a solution for sending up to 100 API Calls with one request but in my opinion this is not needed in your situation. If you want to find out more about it check out the Batched Request Documentation, you'll find out that the implementation is different than yours.
One solution that will work is to call the callSendAPI
function multiple times. But this solution has one major drawback: You won't be able to control the actual sequence of the messages sent. For example if you want to send two separate messages, you cannot guarantee which will be sent first to the user.
To solve this issue you need to chain your callSendAPI
functions in a way that guarantees that the next callSendAPI
call will happen only after the first message is already sent. You can do this in NodeJS by using either callbacks or promises. If you are not familiar with either of them, you can read this for callbacks and this for promises.
You'll need to modify your callSendAPI
function and especially the part that sends the POST request to Facebook. I will present a solution to your issue by using promises and the module 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),
});
}
回答2:
I found the below link useful to sort out the way to implement multiple responses on single post back.
https://codingislove.com/build-facebook-chat-bot-javascript/
Like you said, array should work. Create an array variable with multiple response messages
var multipleResponse = {
messages: [{
response1
},
{
response2
}]
};
And push the array variable to your function
function callSendAPI(sender_psid,response) {
let body = {
recipient: {
id= sender_psid
},
message: []
};
// Followed by code for POST request to the webhook
}
Finally push the array to your function array
body.message.push(multipleResponse.messages);
回答3:
@Christos Panagiotakopoulos. I am not getting my mainMenuResponse which is chained using then. Rather, i am getting response thrice. handlePostback function =>
// 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 function =>
// 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);
}
});
}
回答4:
Don't modify callSendAPI
function. In your handlePostback
function call callSendAPI
multiple times.
callsendAPI(sender_psid,response1);
callsendAPI(sender_psid,response2);
来源:https://stackoverflow.com/questions/47483190/sending-multiple-reply-messages-on-single-postback-in-facebook-messenger-bots