Sean
Sean

Reputation: 534

Using postBack to send bot text message using BotFramework v4 and Node.js

I am trying to send a postBack text message to my bot but I don't know the right syntax.

Here is my code:

if (postback.payload == "WHAT_IS_MENTAL_HEALTH") {
      await turnContext.sendActivity("TO-DO: Forward on 'What Is Mental Health?' to Bot Handler");
      ActionTypes.postBack("What Is Mental Health?");
}

I'm trying to forward on the text "What Is Mental Health?" to my bot so it will pull back the QnA Maker response for that question.

The steps for this are as follows:

  1. User clicks a button on a Facebook Messenger Generic Template Card (e.g. “What Is Mental Health?” Button)
  2. The button sends a postBack payload to the bot (e.g. “WHAT_IS_MENTAL_HEALTH”)
  3. I am detecting the postBack payload from Facebook Messenger (e.g if (postBack.payload == “WHAT_IS_MENTAL_HEALTH”))
  4. Once that particular postBack payload is detected I then want to send an additional postBack to my bot as text (e.g. “What Is Mental Health?”) so it can be interpreted by my QnA and respond with the correct answer which has been programmed into my QnA Knowledge Base.

Upvotes: 0

Views: 811

Answers (1)

mdrichardson
mdrichardson

Reputation: 7241

Facebook Events and the Bot Framework

When Facebook sends an event to your bot, it sends an Activity with an Event ActivityType. For some events, the event data is in the Activity.Value property. For other events, like a PostBack from a Quick Reply, the activity will be a Message and the data will be in Activity.ChannelData. For example, your bot might receive a postBack event as an activity like this:

{
    channelId: 'facebook',
    [...]
    type: 'message',
    channelData: {
        recipient: {...},
        sender: {...},
        message: {
            [...],
            quick_reply: {
                [...],
                payload: '<your payload>'
            }
        }
    }
}

Handling Facebook Events

This answer is going to pull heavily from the Facebook Events Sample. I highly recommend looking at that for additional help.

Capture Messages and Events

First, you want to capture the facebook messages and events with onMessage() and onEvent():

this.onMessage(async (turnContext) => {
    console.log('Processing a Message Activity.');

    // Show choices if the Facebook Payload from ChannelData is not handled
    if (!await this.processFacebookPayload(turnContext, turnContext.activity.channelData)) {
        if (turnContext.activity.channelId !== 'facebook') {
            await turnContext.sendActivity('This sample is intended to be used with a Facebook bot.');
        }
        await this.showChoices(turnContext);
    }
});

this.onEvent(async (turnContext) => {
    console.log('Processing an Event Activity.');

    // Analyze Facebook payload from EventActivity.Value
    await this.processFacebookPayload(turnContext, turnContext.activity.value);
});

Process the Messages/Events

Facebook can send many types of events. You may want to use an if or switch statement to handle each type:

async processFacebookPayload(turnContext, data) {
    // At this point we know we are on Facebook channel, and can consume the Facebook custom payload present in channelData.
    const facebookPayload = data;
    if (facebookPayload) {
        if (facebookPayload.postback) {
            // Postback
            await this.onFacebookPostback(turnContext, facebookPayload.postback);
            return true;
        } else if (facebookPayload.optin) {
            // Optin
            await this.onFacebookOptin(turnContext, facebookPayload.optin);
            return true;
        [...]
    }
    return false;
}

Specifically, Handle a PostBack

The sample just does:

async onFacebookPostback(turnContext, postback) {
    console.log('Postback message received.');
    // TODO: Your postBack handling logic here...

    // Answer the postback and show choices
    await turnContext.sendActivity('Are you sure?');
    await this.showChoices(turnContext);
}

As you want to route the question to QnA Maker, you might (using the QnA Maker Sample as guidance):

async onFacebookPostback(turnContext, postback) {
    // qnaMaker.getAnswers doesn't accept string input, so we need to adjust our turnContext
    //  to match what it expects, which is a string in Activity.Text
    turnContext.activity.text = postback.payload;
    const qnaResults = await this.qnaMaker.getAnswers(turnContext);

    // If an answer was received from QnA Maker, send the answer back to the user.
    if (qnaResults[0]) {
        await turnContext.sendActivity(qnaResults[0].answer);

    // If no answers were returned from QnA Maker, reply with help.
    } else {
        await turnContext.sendActivity('No QnA Maker answers were found.');
    }
}

Upvotes: 1

Related Questions