Messenger Customer Chat Plugin

Building a seamless chat experience across web and mobile surfaces while maintaining context can be challenging. The customer chat plugin was built to solve that and enable you to create a single user experience regardless of communication medium. This plugin integrates your Messenger experience directly into your website and allows you to:

  • Maintain context: The plugin automatically loads recent chat history between the person and your business, meaning recent interactions with your business on messenger.com, in the Messenger app, or in the customer chat plugin on your website will be visible.

  • Use Messenger Platform features on your website chat window: Customers can interact with your business anytime with the same personalized, rich-media experience they get in Messenger.

  • Easily follow up: You can continue the conversation with people even after they have left your webpage. You don’t need to capture their information to follow up, just use the same conversation in Messenger.

This tutorial provides you with an in-depth review on how to setup and customize the customer chat plugin.

Scope

In this post we cover:

  • Using the setup tool to generate code for the plugin, including whitelisting domains
  • Customizing the plugin
  • Adding the plugin to a web page
  • How to toggle the persistent menu
  • Setting up a custom string parameters for conversations
  • Managing conversations
  • Detecting conversations

What you need

Prerequisites

  • Facebook Page created: Used as the identity of your bot.
  • Facebook for Developers account: Required to create new apps, which are the core of any Facebook integration.
  • Webhook setup: The Messenger Platform sends events to your webhook to notify your bot when a variety of interactions or events happen, including when a person sends a message.
  • Facebook app setup: contains the settings for your Messenger bot, including access tokens.
  • Build a bot for Messenger. You can do so using the Quick Start guide.

Messenger Features

  • A webpage to host the plugin.
  • Customer Chat Plugin: Allows you to embed Messenger into your webpage.
  • Webhook: The Messenger Platform sends events to your webhook to notify your bot when interactions or events happen.
  • Persistent Menu: Allows you to have an ‘always-on’ user interface element inside Messenger conversations.

Repository with working code

You can find the final code for the tutorial here.

Step-by-step

STEP 1: Generate the code for plugin

Under Page Settings > Messenger Platform > Customer chat plugin there is a setup wizard that generates the JavaScript and HTML code you will need to include the plugin on your web page. The setup wizard also allows you to specify the language, greeting text, response times, theme colors, and whitelisted domains for the plugin.

For security reasons, you will need to whitelist the domain that runs the customer chat plugin. The whitelisting step is included in the setup wizard, but if you prefer to set it up on your own, then use one of the following options:

whitelisting

Whitelisting in Page Settings

Go to Page Settings > Messenger Platform and enter the fully-qualified domain name that you want to whitelist in the ‘White-listed domains’ field.

Whitelisting via the Messenger Profile API

You can also whitelist domains programmatically by updating the whitelisted_domains property in your bot’s Messenger Profile by sending a POST request to the Messenger Profile API:

curl -X POST "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>"
     -H 'Content-Type: application/json'
     -d '{
        "whitelisted_domains": [
          "http://domain.com"
        ]
      }'
      

STEP 2: Available Customizations

To create an experience that matches a specific brand, you can customize the appearance and functionality of the plugin in a variety of ways.

  • logged_in_greeting/logged_out_greeting: You can set a different greeting for logged in and logged out users. This text gives you the ability to set the stage for your conversation with customers, so use the right tone and voice to match your brand and audience. Short is best (there is a maximum of 80 characters), and so is asking questions, or offering specific help. For example:”Do you need help finding something in our shop?””We have free shipping all week, ask us for details.””Ask us about today’s special offers.”
  • greeting_dialog_display: Set to show to always display the greeting text, or hide to always hide it. Set to fade to show the greeting briefly and then hide it.
  • greeting_dialog_delay: Sets the number of seconds between the plugin loading and displaying the greeting dialog. This attribute applies to the show and fade settings.
  • theme_color: You can change the color of some of the elements of the plugin to suit our brand. This changes the background of the initial chat button, the text bubbles, and any links within the plugin.

STEP 3: Add the plugin to your web page

Once you have completed configuring the plugin, copy the resulting code and paste it directly after the opening body tag on each page where you want the plugin to appear. For our example, we include the code in /public/chat.html:

<html>
<head>
    <title>Chat with us</title>
</head>
<body>
<script>
(function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id;
    js.src = 'https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js#xfbml=1&version=v2.12&autoLogAppEvents=1';
    fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<div class="fb-customerchat"
     page_id="<PAGE_ID>"
     logged_in_greeting="How can we help you shop today?"
     logged_out_greeting="How can we help you shop today?"
     theme_color="#5c9165">
</div>
</body>
</html>
      

To add the HTML yourself without using the setup tool, read this guide for a complete reference to the customization options.

STEP 4: Toggle the persistent menu

While the persistent menu in the plugin provides a consistent experience with the full Messenger Platform, it may not fit the flow of your website. To give you better control of the experience your users will have in the plugin, the Messenger Platform allows you to set whether the persistent menu is enabled in the customer chat plugin.

For this example we disable the plugin by sending the following request to the Messenger Profile API:

curl -X POST \
  'https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>'
  -H 'Content-Type: application/json'
  -d '{
  "persistent_menu":[
    {
      "locale":"default",
      "disabled_surfaces": ["CUSTOMER_CHAT_PLUGIN"],
      "composer_input_disabled": false,
      "call_to_actions":[…]
    }
  ]
}'
      

To re-enable the menu, send the same request without the "disabled_surfaces" property in the body of the request.

STEP 5: Set a Custom ref parameter for conversations

The customer chat plugin allows you to set a custom string parameter that can be used for a variety of purposes, such as passing your bot a customer ID that is unique to your web application when a customer starts a conversation. For this example, we use JavaScript to set the parameter to an arbitrary value, but in a production application you can set it to anything you want.

To do this, add the following to the existing script tag in chat.html:

window.onload = function () {
    document.getElementsByClassName("fb-customerchat")[0].setAttribute("ref", "12345");
}
      

Set the parameter to an empty value in the div tag; the JavaScript sets the value when the page finishes loading.

<div class="fb-customerchat"
     page_id="<PAGE_ID>"
     logged_in_greeting="How can we help you shop today?"
     logged_out_greeting="How can we help you shop today?"
     ref=""
     theme_color="#5c9165">
</div>
      

Handling the ref param

How you handle this parameter in the bot depends on whether a conversation is new and started in the plugin or an existing conversation that continues in the plugin.

Our application needs to handle these two new events. To do this, add the following to the bottom of the if statement in the handleEvent method of app.js:

…
else if (webhook_event.postback) {
  handlePostback(sender_psid, webhook_event.postback);
} else if (webhook_event.referral) {
  handleReferral(sender_psid, webhook_event.referral);
}
…
      

The referral object of the webhook event in both cases contains the URL the user came from, their source and the value you set the ref value to. For example:

referral:
   {
     ref: '12345',
     source: 'CUSTOMER_CHAT_PLUGIN',
     type: 'OPEN_THREAD',
     referer_uri: 'https://<SERVER_URL>/chat.html'
   }
      

For this example application, the handlePostback and handleReferral functions log the value to console, but this function is where you would handle saving the value, or reacting to it in some other way.

function handlePostback(sender_psid, received_postback) {
    console.log(`PSID: ${sender_psid}, postback: ${received_postback.ref}`);
}

function handleReferral(sender_psid, received_referral) {
    console.log(`PSID: ${sender_psid}, referral: ${received_referral.ref}`);
}
      

STEP 6: Manage conversations

Using the plugin on a web page, there are now have several potential sources for a conversation. In addition, different teams or people may manage each of these conversations in your company. As a result, it can be difficult to manage all of these conversations and ensure that they are each handled by the right person or team. This is where the handover protocol comes in.

We have written an extensive guide on the handover protocol, so this guide won’t repeat all of those details, but will provide a simplified step-by-step on how you can use handover protocol with the customer chat plugin.

Imagine a scenario where a customer starts a conversation in the customer chat plugin on your website, but it becomes clear that the customer needs help from a real person. To enable this, we’ll allow the customer to switch to customer support by sending the message ‘Customer Support’ to the bot. This will allow a real person to chat with the customer via the Page Inbox for your Page.

To do this, add the following to the stub handleMessage method to check for the message ‘Customer Support’:

if (received_message && received_message.text == 'Customer Support') {
    response = {
        "text": "A human support agent is now helping you with your inquiry."
    };
    callSendAPI(sender_psid, response);
    passThreadControl(sender_psid, page_inbox_app_id);
}
      

In the passThreadControl method, pass control to the Page Inbox, passing the sender_id and the target_app_id for your Page Inbox, which you can find under Page -> Settings -> Messenger Platform:

function passThreadControl(sender_psid, target_app_id) {
    console.log('PASSING THREAD CONTROL');
    let request_body = {
        recipient: {
            id: sender_psid
        },
        target_app_id: target_app_id
    };

    // Send the HTTP request to the Messenger Platform
    request({
        "uri": "https://graph.facebook.com/v2.6/me/pass_thread_control",
        "qs": {"access_token": access_token},
        "method": "POST",
        "json": request_body
    }, (err, res, body) => {
        if (!err) {
            console.log('message sent!')
        } else {
            console.error("Unable to send message:" + err);
        }
    });
}
      

When the service agent finishes, they click the ‘Mark as Done’ button at the top of the conversation to automatically trigger as pass_thread_control messaging_handovers webhook event to pass control back to the Primary Receiver. To handle this event, you need to do two things.

When the secondary receiver is in control, your bot needs to listen on the standby channel, and not the normal messaging channel. Add the following to the app.post('/webhook', (req, res) => {}); method:

// Secondary Receiver is in control - listen on standby channel
  if (webhook_events.standby) {

      // iterate webhook events from standby channel
      webhook_events.standby.forEach(event => {
          handleEvent(event.sender.id, event);
      });
  }
      

And add the following else if () after the if () in the handleEvent method:

else if (webhook_event.pass_thread_control) {
    handlePass(sender_psid, webhook_event.pass_thread_control);
}
      

Next, in the handlePassThreadControl method let the person know that they are back to talking with a bot:

let response = {
    "text": "An automated agent is now helping you with your inquiry."
};
callSendAPI(sender_psid, response);
      

STEP 7: Detecting conversations

Conversations in Messenger can now originate from multiple sources. In this step, you can detect if a message came from the plugin and change the message accordingly.

To detect if a message originated from the customer chat plugin, you can check for the presence of the customer_chat_plugin value in the source property of the message payload, and send a different message depending on if they arrived through the plugin or directly into Messenger.

To do this, add the following after the current if statement in handleMessage:

else if (received_message.text) {
        if ((received_message.tags) && (received_message.tags.source == 'customer_chat_plugin')) {
            response = {
                "text": `We hope you enjoyed our website, we see you would like help with:\n "${received_message.text}".`
            };
        } else {
            response = {
                "text": `We see you would like help with ${received_message.text}.`
            };
        }
        callSendAPI(sender_psid, response);
    }
      

Conclusion

In this post, we looked at how to install the customer chat plugin. We also looked at the admin functionality of the Page connected to your bot, adding the plugin to your webpage, customizing it, and integrating the plugin to the workflow of your bot and organization.

We hope you enjoy the new conversations you can now start with your customers from wherever they interact with you.