Create a Messenger Bot with a WordPress Backend

Bots are all the rage these days. They call us while we’re eating dinner, they merge our data for us, they take part in our elections, and they’re taking over Facebook Messenger. As a wannabe bot creator myself, I couldn’t resist the hype any longer, so I started tinkering with Facebook’s Messenger Platform to see what it would take to start chatting with my own code.

Introducing WPFBBotKit

Messenger Platform is essentially just a JSON API and like many APIs, I found that there’s quite a bit of boilerplate–the digital equivalent of handshakes and small-talk–required to get started. So rather than put you through all of that, I decided to create WPFBBotKit, a WordPress plugin that will get your WP-backed bot ready to chat as quickly as possible.

One major caveat before we get started: We will not be creating “smart” bots. While it’s definitely possible with NLP and Deep Learning, we’re just going to make a simple bot that will try to drive traffic to our website by giving users something to read.

Setting Up

To get started, we’ll need a WordPress site with SSL support since the Messenger platform requires an HTTPS URL for webhook endpoints. If you don’t already have a site that’s set up with SSL, the easiest way to get this up and running will be to just start working on a local dev site using something like MAMP and set up a tunnel with Ngrok or use Local by Flywheel which will start an Ngrok tunnel for you automatically.

Now you can install the WPFBBotKit plugin by downloading the zip from the repo. Activate the plugin and then head over to the plugin’s settings page by clicking WPFBBotKit under the WP-Admin Settings menu.

On the WPFBBotKit admin page you’ll see a Webhook URL and Verification String, as well as a textarea for your Page Access Token. Leave this page open, we’ll be using the information on this page in just a minute.

minimal settings screen

Next, we’ll need to create a Facebook App and a Facebook Page (you can also use an existing app and/or page if you have them). Your Facebook Page will become the persona of your bot, so when you send messages from your bot, its name will be the name of the page and its avatar will be the Page’s profile picture.

Your page will be the bot's profile

Your App is where you set up integrations, so head back to your app listing and click through to your newly created app, then click Add Products and select Set Up under Messenger.

App : Add Product : Messenger

On the Messenger Setup page, scroll down to Token Generation and click Select a Page and select your page. You may get a pop up window from Facebook asking you to authorize your app to manage your page – if you do, just follow the login screen and authorize the app. Next click on the Page Access Token box to copy the access token – then switch back to the WPFBBotKit settings screen in your WordPress site’s wp-admin and paste the access token into the Page Access Token textarea and click Save.

select your page and copy the access token

Back on the Messenger Setup page, you can now select Setup Webhooks and copy your Webhook URL from the WPFBBotKit Settings page into the Callback URL box (make sure to use https and replace the site’s url with the Ngrok url if you’re using a tunnel) and the Verification String into the Verify Token box. Check the boxes next to messages and messaging_postbacks under Subscription Fields and then click Verify and Save. You should see a working indicator and then the modal will disappear if everything went well. If there were any issues, you’ll see a red “X” in the url field and you can hover over it for more information.

Set up webhook

Finally, you can select your app from the dropdown next to “Select a page to subscribe your webhook to the page events” (still in the webhooks box, and click Subscribe.

Subscribe your page

Check out the Messenger Platform’s getting started guide for further information about getting your page, app, and webhook set up properly.

Booting Up Your Bot

If you’re following along, you’ll want to find somewhere to work, so either create a new plugin or a new file in your mu-plugins directory, or if you’re a complete rebel you can just start working in your theme’s functions.php file (you monster). WPFBBK exposes an action called wpfbbk_message_received which will fire whenever our bot receives a message, so let’s start off by hooking into that action.

add_action( 'wpfbbk_message_received', 'my_cool_bot' );
function my_cool_bot( $M ) {
    // message processing and response goes here
    exit( 0 );
}

So far this does nothing except to exit the script so that Facebook doesn’t resend the webhook request. Ideally, you would send all replies to a queue since Facebook only give you 20 seconds to return a 200/OK response code before they retry sending the message to you, but if you can’t do that I believe the next best thing is to limit the amount of replies you send and exit the program as quickly as possible.

The wpfbbk_message_received action will pass an instance of the WPFBBK_Messaging class which will contain read-only properties including $text, and $postback which will be populated if someone sends your bot a message or taps a postback button that your bot sends them. It also exposes a reply( $message ) method which will let you send a reply to the current message with manually formatted data as well as some helper methods such as reply_with_text( $text ), reply_with_image_url( $url ), and reply_with_buttons( $text, $buttons ). Let’s use reply_with_text and reply_with_image to send a response to any non-postback message we receive:

add_action( 'wpfbbk_message_received', 'my_cool_bot' );
function my_cool_bot( $M ) {
    if( ! $M->postback ) {
        $M->reply_with_text( 'Hi There!' );
        $M->reply_with_image_url( 'https://media.giphy.com/media/eHpWHuEUxHIre/giphy.gif' );
    }
    exit( 0 );
}

Now you can head over to Facebook Messenger and start a new chat with your bot – with any luck, it should go something like this:

Chatting with Bindey bot

Cool… Wait, why is this cool?

Sending replies to Facebook messages via our WordPress site is neat and all, but let’s see if we can provide people with a bit more than just a GIF. Since we’re running on WP, which was at one time a blogging platform, let’s see if we can give folks something to read. Instead of a GIF, we’ll send them a set of buttons which will let users tell our bot what they want to read. We can use WPFBBK_Messaging::reply_with_buttons() to send this, but check out the Postback Button documentation for more information about how to format the array describing your buttons. Here’s what I’m starting out with:

Here we’re passing reply_with_buttons() a bit of text as well an array of arrays that describe postback buttons. Each button has a type of postback as well as a title which is what will be displayed on the button and a payload which is what we’ll get back as their response if they click that button. Now I’ll replace the gif we’re sending to responses with this button response and test it in messenger:

Bindey sends me buttons

Now let’s handle those responses. First we’ll need to intercept the postback and set up responses for each option that we’ve provided. We’ll do this by tacking on an else block after the if that checked if there wasn’t a postback and then set up a switch statement:

Now we just need to add the #code for each case. Let’s start with the negative response: When the user clicks the I'm all caught up! button, we just want to send them a quick reply and a fun GIF for the road. We can use the Tenor GIF API on a limited basis without having our own key, so we’ll use wp_remote_get() to grab and cache a list of GIFs and then use WPFBBK_Messaging::reply_with_image_url() to send a random one of them:

case 'GET_GIF':
    // get and cache some gifs
    if( ! $gifs = get_site_transient( 'schwifty_gifs' ) ){
        $gifsearch = 'rick morty';
        $gifs = json_decode( wp_remote_get( 'https://api.tenor.com/v1/search?tag=' . urlencode( $gifsearch ) . '&safesearch=strict&limit=50&key=LIVDSRZULELA' )['body'] )->results;
        set_site_transient( 'schwifty_gifs', $gifs );
    }

    //choose a random GIF from the results
    $gif = $gifs[ rand( 0, count( $gifs ) - 1 ) ]->media[0]->gif->url;

    // reply with text and a schwifty GIF for the road
    $M->reply_with_text( 'Sounds good. Keep it Schwifty!', true );
    $M->reply_with_image_url( $gif );
    break;

Moving up, from the GET_GIF case, we’ll tackle GET_ARCHIVE_POST next. To keep this pithy, we’ll just use get_posts to find the first published post and then we’ll use WPFBBK_Messaging::reply_with_generic_template_link() to send the user a nicely formatted link to the article using the Messenger API’s Generic template:

case 'GET_ARCHIVE_POST':
    // get the oldest published post
    $posts = get_posts( array(
        'posts_per_page'   => 1,
        'orderby'          => 'date',
        'order'            => 'DESC',
    ) );

    // populate fields required for generic template
    $title = $posts[0]->post_title;
    $image = str_replace( 'http://', 'https://', wp_get_attachment_image_src( get_post_thumbnail_id( $posts[0]->ID ), 'large' )[0] );
    $url = get_permalink( $posts[0]->ID );
    $subtitle = strip_tags( $posts[0]->post_content );

    // trim post content to subtitle length
    if( 70 > strlen( $subtitle ) ) {
        $subtitle = substr( $subtitle, 0, 67 ) . '...';
    }

    // send generic template link card
    $M->reply_with_generic_template_link( $title, $subtitle, $image, $url );
    break; 

Finally, we can use almost all of the same code for the GET_LATEST_POST, we’ll just change the order parameter that we’re passing to get_posts() to from DESC to ASC. Let’s see how this works:

Our completed chatbot interaction

FAQ

Why aren’t images loading in Messenger?

If you find that your images aren’t loading in Messenger, this is likely due to Facebook’s stringent SSL requirements: Images must be served over HTTPS with a valid SSL certificate. I had trouble getting this to work with Ngrok, so I opted to use WP Offload S3 to serve my images directly from S3 over HTTPS which worked great.

Why did my bot respond two/three/n times?

Messenger automatically resends requests to your webhook if it hasn’t received a response within about 20 seconds, and each response that you send delays your server from closing the connection. So if you’re sending a lot of separate messages, or contacting other APIs (like the Tenor GIF API), it’s pretty easy to go over that 20 second limit. Additionally, if you have an error in your code that prevents WordPress from sending a 200 response, Messenger will keep hitting your webhook with the same request indefinitely (though at increasing intervals), so make sure to triple-check your code and keep your debug/error log open so you can spot errors as they happen.

If you’re planning on creating a highly interactive bot, you’ll definitely want to look into implementing a queue server of some sort. This is made possible by WPFBBotKit’s wpfbbk_before_send_request hook which will let you handle the request on your own (send it to a queue of some sort) rather than letting WPFBBK send the request via WP’s Requests class.

Why doesn’t WPFBBK do X?

To be honest, I made WPFBBK because this article would have been three times as long without the abstraction. All of that to say: It’s a very new project. If you like it and want to contribute , please open an issue or submit a pull request on the repo!

Wrapping Up

The chatbot space has been growing rapidly in the last couple of years and it now seems to be getting embraced by more ubiquitous platforms like Messenger, Skype, and WhatsApp. What do you think the future holds for chatbots? Are they a fleeting fad, or here to stay? What have you done or do you hope to create in this space? Let us know in the comments!

P.S. If you want to follow my Messenger Bot experiments, hit like on our Facebook page where all the experimenting will happen:

About the Author

Jeff Gould

Jeff is a problem solver at heart who found his way to the web at an early age and never looked back. Before Delicious Brains, Jeff was a freelance web developer specializing in WordPress and front-end development.

  • Love this. I had exactly the same idea, to use WordPress as a backend for bots, earlier this year. Glad to see someone else running ahead with it! Look forward to seeing where else you go with it.

    • Thanks! Definitely open some issues or PRs on the github repo if you have any ideas for improving WPFBBotKit.

  • Jon

    Funny I was _just_ thinking about trigging WP events (updates/backups/etc…) from Slack… This is awesome.

    • Cool idea! Messenger might not be the best platform for that but you could lock it down to your FB user ID. I might have to look into Slack’s API to see if there’s much overlap.

    • That sounds like ChatOps, which is awesome! Like this http://ocadotechnology.com/blog/how-we-set-up-chatops-within-slack/

      Would be great to have a client WP plugin that would respond to Slack commands to manage the site.

      • Kyle Maurer

        Amazing article! I’m inspired. And as for triggering site actions from Slack, we’ve been doing that in our EDD Slack integration https://easydigitaldownloads.com/downloads/slack/ for a while now. Using the slash commands API we allow creating discount codes and other similar actions to be performed from Slack. Slack’s API is pretty sick so the possibilities are endless.

  • Matt Stinson

    Wow that’s fantastic. Lil trick though… you should use strpos($M->text, ‘hello’) !== false .. so it’d find the string in a sentence. I really doubt that people will come up with only ”hello” lol 🙂 Really good job there

  • HAHA! Funny and cool stuff!

  • Daniel Powney

    Hi Jeff,

    I created a WordPress chatbot plugin powered by API.AI over the weekend which is now available on the WordPress repo (called My Chatbot). API.AI supports various messaging platform integrations such as Facebook Messenger. The plugin allows your chatbot to assume the appearance of a messaging platform so in theory you could also have the same chatbot available on your website.

    Daniel

  • coccoinomane

    Wow, very interesting!
    It seems useful to create a bot that is a “window” on the website.
    I was wondering: is it possible to embed the bot in the website? Like a support chat window? That seems like a natural extension to the plugin… if Facebook allows that 😛
    Thanks!

  • ISMAIL HASSAN

    Is this possible to search for the word in the website that given in a message?
    That way it’ll help them perfectly.

  • This is really cool. You mentioned creating a queue server. Do you have any examples or pointers on how to get that accomplished?