
This topic describes how to set up bot handover using Facebook Messenger bot handover protocol. In this method, the conversation state is managed by Facebook. For information on setting up bot handover using Zendesk Message bot handover protocol, see Setting up bot handover using Zendesk Message handover protocol.
To set up bot handover, follow these procedures:
Linking your page
To get started, add Facebook Messenger as a channel to capture conversations on your Facebook page in Zendesk Message. For more information, see Adding and managing channels and Setting up your Facebook channel.
Once you've added Facebook Messenger as a channel to capture conversations on your Facebook page, you can use bots with bot handover to handle messages when you're offline.
Creating your echo bot server
Next, create your echo bot server:
- Follow the Quick Start Tutorial provided by Facebook and create your first bot in nodejs.
You only need to complete up to step 5 of the "Build the Bot" tutorial to proceed with setting up bot handover. Later in this topic, you will build bot handover functions on top of this echo bot.
- When you built the bot, make a note of the Facebook App's page access token. You'll need this information later to set up the bot handover.
At this point, you should have a working bot server, a Facebook page, and a Facebook App representing your bot server subscribed to your Facebook page.
Setting up app roles
To set up App Roles on your Facebook page:
- Open your Facebook page in a browser window and navigate to Settings > Messenger Platform.
- Scroll to the Subscribed Apps section.
- Set your Facebook bot as the Primary Receiver.
- Set the Zendesk Messenger App as the Secondary Receiver.
The primary receiver can receive messaging events, secondary receivers only receives standby events.
At this point, you should be able to see a success message on the Facebook > Integrations page of the Zendesk Message dashboard. Also, you should be able to receive messages in your bot.
Even though the Zendesk Message dashboard displays a success message, the setup is not complete. You need to configure your bot server to send pass thread requests.
Sending the pass thread request on user message
- You have your Facebook App's page access token. This is the token you created in the Facebook Quick Start Tutorial. See Creating your echo bot server.
- You've set up your Facebook App roles. See Setting up app roles.
- You have the Zendesk Messenger App ID that appears in the Subscribed Apps section of your Facebook Settings > Messenger Platform page.
To change your bot server code to send and handle thread requests:
Now that the Zendesk Message is set as the secondary receiver and your bot is the primary receiver, by default messages will be handled by your bot and no user messages will be shown in the Zendesk Message dashboard. To make a page visitor's message appear in Zendesk Message, you need to send the pass_thread_control request to the Facebook server to hand the conversation to the Zendesk Message app.
- Change the message handler to call sendPassThread when the user message matched the key phrase you defined for bot handover. Otherwise, send an echo message. Use the following code sample as a model.
Note: To view this sample with syntax highlighted, see Appendix: Code samples at the end of this article.
... app.post('/webhook', (req, res) => { const body = req.body; if (body.object === "page") { body.entry.forEach(entry => { if (entry.messaging) { const event = entry.messaging && entry.messaging[0]; if (event.message) { handleMessage(event.sender.id, event.message); } } }); res.status(200).send('EVENT_RECEIVED'); } else { res.sendStatus(404); } }); ... function handleMessage(senderId, message) { let response; if (message.text) { if (message.text.trim() === "chat with agent") { sendPassThread(senderId); } else { sendEcho(senderId, `[bot] ${message.text}`); } } } function sendEcho(message) { request( { uri: "https://graph.facebook.com/v2.6/me/messages", qs: { access_token: ACCESS_TOKEN }, method: "POST", json: { recipient: { id: senderId }, message: { text } } }, (err, res, body) => { if (err || body.error) { log("UNABLE TO SEND", err || body.error); } else { log("RESPONSE SENT"); } } ); }
- Implement the sendPassThread. Use the following code sample as a model. For more information, see the Facebook Pass Thread Control API Reference.
Note: To view this sample with syntax highlighted, see Appendix: Code samples at the end of this article.
function sendPassThread(senderId) { request( { uri: "https://graph.facebook.com/v2.6/me/pass_thread_control", qs: { access_token: ACCESS_TOKEN }, // access token of your app (bot server) to your page method: "POST", json: { recipient: { id: senderId }, target_app_id: MESSAGE_APP_ID // you can retrieve this in your page setting after linking zendesk message - 200646160103180 } }, (err, res, body) => { if (err || body.error) { console.log("UNABLE TO SEND PASS THREAD REQUEST", err || body.error); } else { console.log("PASSED THREAD TO MESSAGE DASHBOARD BOT"); } } ); }
- When am agent marks a conversation as done, Facebook will send a passThread webhook to your bot server. To listen to the pass_thread_event, use this code sample as a model:
Note: To view this sample with syntax highlighted, see Appendix: Code samples at the end of this article.
... app.post('/', (req, res) => { const body = req.body; if (body.object === "page") { body.entry.forEach(entry => { if (entry.messaging) { const event = entry.messaging && entry.messaging[0]; ... if (event.pass_thread_control) { handlePassThread(event.sender.id, event.pass_thread_control); } ... } }); res.status(200).send('EVENT_RECEIVED'); } else { res.sendStatus(404); } }); ... function handlePassThread(senderId, passThreadMessage) { console.log("PASS THREAD EVENT:", passThreadMessage); }
For more information, see these Facebook API documents:You can also use postbacks to send the pass thread when the user clicks a message button or selects a menu command. For more information, see these Facebook documents:
Verifying the bot handover
- When a user starts a conversation, you see your bot echo and no message appears in the Zendesk Message dashboard.
- When a user sends a chat with agent phrase (or another phrase you defined) and then sends a subsequent message, you see the subsequent message in the Zendesk Message dashboard.
- When an agent marks the conversation as done, you receive a passThread event in your bot server's console. For example:
PASS THREAD EVENT: {new_owner_app_id: 128624987631714, metadata: null }
From there, if the user sends another message, the transaction should behave like the first scenario, where the user starts the conversation and interacts with the bot.
If all three cases work as intended, you have successfully implemented Facebook-managed bot handover with Zendesk Message.
Appendix: Code samples
This section contains the code samples mentioned above with syntax highlighted.
Code sample to call the sendPassThread
... app.post('/webhook', (req, res) => { const body = req.body; if (body.object === "page") { body.entry.forEach(entry => { if (entry.messaging) { const event = entry.messaging && entry.messaging[0]; if (event.message) { handleMessage(event.sender.id, event.message); } } }); res.status(200).send('EVENT_RECEIVED'); } else { res.sendStatus(404); } }); ... function handleMessage(senderId, message) { let response; if (message.text) { if (message.text.trim() === "chat with agent") { sendPassThread(senderId); } else { sendEcho(senderId, `[bot] ${message.text}`); } } } function sendEcho(message) { request( { uri: "https://graph.facebook.com/v2.6/me/messages", qs: { access_token: ACCESS_TOKEN }, method: "POST", json: { recipient: { id: senderId }, message: { text } } }, (err, res, body) => { if (err || body.error) { log("UNABLE TO SEND", err || body.error); } else { log("RESPONSE SENT"); } } ); }
Code sample to implement the sendPass Thread
function sendPassThread(senderId) { request( { uri: "https://graph.facebook.com/v2.6/me/pass_thread_control", qs: { access_token: ACCESS_TOKEN }, // access token of your app (bot server) to your page method: "POST", json: { recipient: { id: senderId }, target_app_id: MESSAGE_APP_ID // you can retrieve this in your page setting after linking zendesk message - 200646160103180 } }, (err, res, body) => { if (err || body.error) { console.log("UNABLE TO SEND PASS THREAD REQUEST", err || body.error); } else { console.log("PASSED THREAD TO MESSAGE DASHBOARD BOT"); } } ); }
Code sample to listen to the pass_thread_event
... app.post('/', (req, res) => { const body = req.body; if (body.object === "page") { body.entry.forEach(entry => { if (entry.messaging) { const event = entry.messaging && entry.messaging[0]; ... if (event.pass_thread_control) { handlePassThread(event.sender.id, event.pass_thread_control); } ... } }); res.status(200).send('EVENT_RECEIVED'); } else { res.sendStatus(404); } }); ... function handlePassThread(senderId, passThreadMessage) { console.log("PASS THREAD EVENT:", passThreadMessage); }
2 Comments
Does this only work for Zendesk chat? Or can i get this to work with Zendesk support as well?
Hey Oliver,
Thanks for reaching out! Unfortunately this is specific to Zendesk Chat at this time. We'll be sure to update our customers if an update is available for Support in the future.
Cheers!
Please sign in to leave a comment.