I'm trying to figure out how to get Facebook Messenger to show follow-up prompts from QnA Maker using BotFramework v4 and Node.js.
I've managed to get the follow-up prompts showing in WebChat:
I managed this after following the great advice from Matt Stannett in this thread: How to implement cards in a QnA question which has follow up prompts and uses them in the cards
However, when it comes to getting them to appear in Facebook Messenger, I'm really struggling.
I was hoping it would be as straightforward as defining some channelData for Facebook Quick Replies in my onMessage code, as I just need Facebook to pass back a simple text payload. I thought I could do it in a similar way I got the prompts showing for Webchat, code below:
this.onMessage(async (context, next) => {
this.logger.log('Processing a Message Activity');
const qnaResults = await this.qnaMaker.getAnswers(context);
// Show choices if the Facebook Payload from ChannelData is not handled
if (!await this.processFacebookPayload(context, context.activity.channelData)) {
if (context.activity.channelId == 'facebook') {
if (qnaResults[0]) {
const { answer, context: { prompts }} = qnaResults[0];
let reply;
if (prompts.length) {
const quickReply = {
channelData: {
"messaging_type":"RESPONSE",
"message":{
"text":"test1", //answer,
"quick_replies":[
{
"content_type":"text",
"title":"test2",//prompts.map({ displayText }),
"payload":"test3",//prompts.map({ displayText })
}
]
}
}
}
reply = quickReply;
} else {
reply = answer;
}
await context.sendActivity(reply);
// If no answers were returned from QnA Maker, reply with help.
} else {
await context.sendActivity('I\'m sorry, I don\'t have an answer for that. Please ask me something else, such as: \n\n "What Is Mental Health?" \n\n "What Is NeuroDiversity" \n\n "Help"');
}
} else {
// If an answer was received from QnA Maker, send the answer back to the user.
if (qnaResults[0]) {
const { answer, context: { prompts }} = qnaResults[0];
let reply;
if (prompts.length) {
const card = {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": answer,
wrap: true
}
],
"actions": prompts.map(({ displayText }) => ({ type: "Action.Submit", title: displayText, data: displayText })),
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.1"
}
reply = { attachments: [CardFactory.adaptiveCard(card)] };
} else {
reply = answer;
}
await context.sendActivity(reply);
// If no answers were returned from QnA Maker, reply with help.
} else {
await context.sendActivity('I\'m sorry, I don\'t have an answer for that. Please ask me something else, such as: \n\n "What Is Mental Health?" \n\n "What Is NeuroDiversity" \n\n "Help"');
}
}
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
This isn't working though. What I do get is QnA replies for any questions I ask that don't have a follow-up prompt set in QnA Maker, so I know that the IF statement is correctly identifying Facebook as a channel and that an answer has follow-up prompts associated with it. I think I just haven't got the code right for the quick replies in Facebook.
Can anyone help?
Thanks in advance!
I've managed to get some generic Quick Replies working by modifying my quickReply channelData:
You can then create a variable to insert the follow-up prompt into the channel data:
Next you need to re-map the array to a new array in the correct format for quick replies:
This now displays the QnA follow-up prompt as a quick reply in Facebook Messenger if you update quickReply as follows:
The final thing to work out is how to re-format the payload back to the QnA into a format that it accepts. To do this you need to adjust your turnContext to a string in Activity.Text as follows and then call the QnA: