Dynamically generated web content shown in the context of Facebook Messenger

Using Facebook Messenger Webview with a Rasa chatbot

Mark Ryan
Mark Ryan
Feb 11, 2020 · 4 min read

I’ve described in a previous post why Facebook Messenger is a great front-end for Rasa chatbots. Rasa provides a decent interface to communicate with Facebook Messenger and hooking up Facebook Messenger as a front-end is relatively straightforward with help from ngrok.

Facebook Messenger provides a clean, streamlined interface for your chatbot. The downside is that as a developer you only get a small set of native controls and display options, including:

What if you need to give your users a richer experience than you can get with vanilla Facebook Messenger? You can take advantage of webview to display full-blown web pages in the context of a Messenger session.

Webview is powerful, but it takes several steps to get the round trip working from Rasa through Facebook Messenger to webview. This article reviews a simple example that shows how you can exploit webview in a Rasa chatbot with Facebook Messenger. You can find the code associated with this example in this repo.

To demonstrate the steps required to take advantage of webview with a Rasa chatbot, we’ll create a very simple “province flag” chatbot that follows this flow:

  • Ask the user which province they want to see. The chatbot accepts variations on one of two responses from the user: Ontario or Quebec.
  • Once the user provides a response, the chatbot shows a button with the province’s name.
  • When the user clicks on the button, webview opens showing a web page with the flag of the province and a brief description.
Flow of the chatbot from the user’s perspective

This is a very simple user experience, but there’s a lot happening behind the scenes, as shown in the following diagram:

Flow of the chatbot behind the scenes

The Rasa model uses a Python custom action file that:

  • Reads in a config file that contains the details that will be shown in webview (province name, link to flag image, description of flag)
config file containing details that will be shown in webview
  • Reads the slot that contains the province, builds a URL string from the contents of the config file associated with this province, and sends a payload to Facebook Messenger to create a button that will launch a webview.
Snippet of actions.py

Ngrok, specifically Pro or Business package, is central to the whole solution:

  • First, ngrok makes the port that Rasa is listening on accessible to Facebook Messenger (as described in this article).
  • Second, ngrok provides a fixed https URL associated with the localhost port used by the Flask server. This is essential — the button to launch webview won’t work unless it is associated with an https URL.

I tried various schemes to get Flask to serve an https URL, but the only thing that worked was getting a paid ngrok license. The paid ngrok license solved several problems by allowing me to have two active ngrok sessions (one for Rasa to Facebook Messenger, and one for Flask) and to have Flask serve the https URL demanded by Facebook Messenger.

The Flask module contains simple code that reads the parameters from the URL that was built in the custom action and uses them to generate the parameters needed in the web page that is displayed in webview:

Snippet of flask_test.py

Finally, the web page itself contains simple HTML that uses the parameters to show the province’s name, flag, and flag description:

Snippet of home.html

This article has described a simple example of how you can take advantage of the flexibility of webview to augment the user experience of a Rasa chatbot in Facebook Messenger. The end-to-end example uses parameter values read in by the Python custom action to ultimately generate a dynamic web page served by Flask with formatted text and graphics displayed in webview, all without leaving the context of Facebook Messenger. The solution depends on ngrok to provide two tunnels to localhost (one for Rasa to Facebook Messenger communication, and one for Flask to serve the web page as https).

You can find all the code described in this article in this repo. Note that you will need to update the following two files:

  • credentials.yml — use your own Facebook app details for the values listed below, as described here:
facebook:
verify: <your verify token>
secret: <your secret>
page-access-token: <your page access token>
  • custom_action_config.yml — update wv_url to the URL for your own web page — as mentioned above this needs to be https or Facebook Messenger won’t allow it to be displayed in webview.
general:
wv_url: <your https-enabled URL for Flask>

The Startup

Get smarter at building your thing. Join The Startup’s +799K followers.

Mark Ryan

Written by

Mark Ryan

Data Science manager at Intact Insurance. Opinions expressed are my own.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +799K followers.

Mark Ryan

Written by

Mark Ryan

Data Science manager at Intact Insurance. Opinions expressed are my own.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +799K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store