How to quickly get past ubiquitous «echo bots» tutorials and build an assistant that actually does something. Just clone, tweak and launch. Can it become a «bot-end» framework? *a reference to Kraftwerk’s single “The Robot” (1978) It started with a screw up I have to admit: as a former journalist, I still write faster than I think. Turns out, it applies to code too. in my series. Even though saw it and some readers used it to create their own projects, no one seemed to have noticed the gaping design flaw. I misused gem in a way that when several users try talking to the tutorial bot at the same time, their messages get mixed up. When one user is in the middle of the interaction, bot is hung up on the task in progress and any other message from any other user would be treated as the next step in the conversation thread. and I desperately wanted to make up for it. I had to rethink the architecture to handle requests from different users and remember their place in conversation. A simple refactoring led to more refactoring, and more refactoring, and more… As a result, I created a simple tool that solves a number of design problems with bots, so you don’t have to solve them yourself**.** I royally screwed up “Build your first Messenget bot in Ruby” more than 6000 people facebook-messenger That sucked M — your starting point to mess with Ruby chatbots for Messenger, the largest messaging platform out there. At this early stage it’s more a and I haven’t packaged it as a separate gem yet, so when you download the boilerplate, you can see how its internals are implemented inside the folder. It also contains some example code that you’re free to tweak and replace. eet Rubotnik Facebook proof of concept /rubotnik What it does You can bind keywords (“help”, for instance, as in or to your bot’s functions (we will call them “commands” from now on) with a straightforward syntax: . Forget about with a dozen of ’s to parse your input. “help!” “Would you help me, please” bind ‘help’, to: :give_help case when You write all your bot’s logic as separate methods inside boilerplate’s module and you can chain them together to create threads of dialogue with Commands next_command :method_name You can generate UI elements with the help of convenience classes: (it also makes those Facebook’s Generic Templates a bit easier to generate) UI::ImageAttachment.new(‘http://your.image/url’).send(@user) You can set up a nested persistent menu and a greeting screen for your bot. Alter and to create your own. rubotnik/persistent_menu.rb rubotnik/bot_profile.rb Its will walk you through all the steps necessary to hook up your bot on Facebook and bring it to life. README It’s a standalone service that runs on Rack (it uses Puma server with default config). Think of it as framework for your web app, if you have one. It has enabled by default so you can create your own webhooks and handle incoming API connections. “bot-end” Sinatra It’s primed for easy deployment with Heroku. Just do and once you’re done testing on localhost. heroku create heroku push origin master What it doesn’t do It has no persistence, but can be extended to work with any database. By default, Rubotnik has simple in-memory storage that keeps track of connected users and their state (see and to see how it’s implemented). rubotnik/user.rb rubotnik/user_store.rb It doesn’t work inside of a Rails project (this is one of the features that can be thought about in future). On the other hand, it can talk to your existing Rails app through REST API. How it works So how do you build your bot with Rubotnik? First, make sure you have your and installed — we will need this for development, as well as for moving your bot to the cloud. Then follow this steps: Heroku CLI ngrok git clone :progapandist/rubotnik-boilerplate.git git@github.com mv rubotnik-boilerplate NAME_OF_YOUR_PROJECT cd NAME_OF_YOUR_PROJECT rm -rf .git # remove boilerplate’s git history git init # track your own project Open the project in your favorite editor and take a look at the file. There’s a bunch of stuff already written, that constitutes logic for a that you can play with . bot.rb demo bot here The that demoes boilerplate features bot It implements an example of a simple API call to Geocoding to determine details about your location, a sample questionnaire to demonstrate gathering data from user message by message, and it also renders some of Facebook’s UI elements to get a taste what your own bot can offer in terms of user experience. Google If you don’t change anything at this point and just follow in the boilerplate’s readme, you’ll get the exact copy of the demo bot. It lets you understand what does what inside the boilerplate, but you probably want to build your own thing, right? Then just take a quick glance at the sample code and replace it with your own. instructions for bot setup Note that all the heavy lifting (sending data to Facebook Messenger Platform and handling incoming requests to your bot’s webhook) is done by the gem ( from Norway did a terrific job, and a community around his project is growing steadily). Rubotnik merely piggybacks on its API, like so: facebook-messenger that guy Same logic applies to postbacks, which are events triggered when the user interacts with buttons in your bot’s UI. Let’s take a closer look, two things are happening in this snippet: is an example of Rubotnik’s . bind ‘string' DSL is a helper function that allows you to send a text message to connected user with a simplicity of say say "Hello!" Take a look at to see how commands can be chained together to form threads. /commands/questionnaire.rb Check the and read through comments in boilerplate’s code to learn more about DSL, helper functions and where to apply them. README How it’s done Rubotnik’s main classes are called and , they can be found inside of folder. Here’s a snippet that shows how message dispatching is implemented: MessageDispatch PostbackDispatch /rubotnik A instance variable is accessible everywhere through common Rubotnik namespace and represents any given incoming message. It’s an instance of facebook-messenger’s class and has all its properties (refer to facebook-messenger’s ) @message Facebook::Messenger::Incoming::Message README @message.id # => 'mid.1457764197618:41d102a3e1ae206a38'@message.sender # => { 'id' => '1008372609250235' }@message.seq # => 73@message.sent_at # => 2016-04-22 21:30:36 +0200@message.text # => 'Hello, bot!'@message.attachments # => [ { 'type' => 'image', 'payload' => { 'url' => 'https://www.example.com/1.jpg' } } ] Same goes for that’s an instance of @postback Facebook::Messenger::Incoming::Postback references the connected user and is an instance of class defined in . The main point of this class is to hold onto user’s facebook ID and keep track of commands bound for execution. You can add your custom containers for state (as in the case with property, used to track user’s answers in ). @user User user.rb answers questionnaire.rb That’s pretty much all the not-so-secret sauce that ensures all users are served independent of each other and the conversation with them continues exactly at the point it stopped, even after a long interruption. How to go live Once you’re done building and testing your bot, just create a heroku app from your console and run . Then update your webhook in Facebook developer console and that’s it! git push heroku master How to say if you ❤️ it or 👺 it For now Rubotnik is just a bunch of code organised in some folders. It’s raw. It’s a proof of concept. It needs polishing. Some of the code has to do with actual “framework” logic, while other bits just demo example bot’s features. It has statements sprinkled everywhere. There’s a bunch of debug statements that are designed to help with understanding how bot performs. But they can’t be allowed to stay there for long. require_relative Some of my practices may be frowned upon by seasoned programmers. That’s understandable, I only discovered Ruby magic . last year That’s exactly why I invite everyone to collaborate. Feel free to fork the boilerplate and make PR’s or just and I’ll add you as a collaborator for the main repo. email me I’m also looking for ways to test Rubotnik with some real world examples, so if you are planning to integrate your service with Messenger, contact me and I’ll help you out. What next? Obviously, Rubotnik should be turned into a gem. But as it’s tightly coupled with , I don’t know where to start yet. It should also probably have -style generators to create directory structure for new projects. facebook-messenger rails new I’m also looking into and tools to enable easy interactions with NLU engines that would make your bot a better conversationalist. wit.ai api.ai Recommend 💚 this article on Medium and stay tuned! 🤖 BOT POWER! 🤖