0
votes

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.
1
I've tried quite a few variations but just can't get this to work. The variations I've tried are: await turnContext.PostAsync(); await turnContext.postBack(); await turnContext.sendActivity.postBack(); postBack(); ActionTypes.postBack();Sean
I can help, but want to make sure we're on the same page. Why use a "postBack"? What exactly are you trying to achieve? Are you just trying to more-or-less send a "hidden" message to your bot? What user interaction do you want to trigger this?mdrichardson
Thank you! I’m using a postBack as I’m detecting a postBack Payload from Facebook Messenger and then want to forward that on to my bot as text so it can be responded to by my QnA. Does that make sense?Sean
Can you walk me through the steps you're trying to achieve? Something like, user clicks button > button calls bot with postback event > bot responds with QnA response? I'm just not clear on what's "detecting the postBack Payload". If the bot already detects it, you don't need to forward anything else to the bot. Might be easiest if you edit your question with the additional details.mdrichardson
Np. The real key to this is less about the code I posted and more about using the two samples in combination to get what you want. As it seems you're new, I can't recommend enough learning how to debug (I post how to with a bot at the end of this answer). It will especially help you with reading things that come in from the activity object and making sure you get the right properties/values.mdrichardson

1 Answers

1
votes

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.');
    }
}