Rubotnik
"Bot-end" Ruby framework to quickly build and launch a Facebook Messenger chatbot
Install / Use
/learn @progapandist/RubotnikREADME
:warning: Hooray! Rubotnik is now a gem that can generate a project for you and serve it from localhost or Heroku. There's been some API changes since it has been a boilerplate. If you are looking for an old README and rubotnik-boilerplate's code you can find it here.
Rubotnik
Tiny "bot-end" Ruby framework with intuitive DSL to quickly build, test and deploy a Messenger chatbot 🤖.
Only minimal Ruby knowledge is required. Perfect for pet projects, classrooms and building bot MVPs from scratch while having a complete freedom over what your bot can do (ChatFuel is great, but what if you actually want to code?). Probably not the best solution for commercial projects at the moment—Rubotnik is yet to prove its worth in production.
This is how you greet your users with Rubotnik:
Rubotnik.route :message do
bind 'hi', 'hello', 'bonjour' do
say 'Hello from your new bot!'
end
end
Rubotnik is zero-configuration, you can have a conversation with your bot on Messenger in under 10 minutes (and most of that time you'll spend on Facebook and Facebook for Developers, creating a page and an "app" for the bot).
Rubotnik is built on top of an excellent facebook-messenger gem by Johannes Gorset that does all the heavy-lifting to actually interact with the Messenger Platform API. While facebook-messenger implements a client, rubotnik offers you a way to reason about your bot design without dozens of nested if and case statements. Rubotnik comes with a bare-bones architecture that ensures multiple connected users are served without delays or overlaps.
What the heck is "bot-end"?
Exactly as with modern front-end, "bot-end" is a separate web application that can talk with your back-end through a (REST) API. Project generated with Rubotnik uses Puma as web server, contains its own config.ru and can be deployed to Heroku in a matter of minutes. And you can still use Heroku's free account, as "sleep time" is not a deciding factor in bot interactions.
Rubotnik currently can not be integrated directly inside the Rails project (although thoughts on that are welcome) and does not have a database adapter of its own on purpose, to keep the boilerplate to the very minimum and extract conversational logic to a separate layer.
In other words:
Rubotnik is perfect to consume existing APIs from a chatbot interface
NB: Rubotnik comes with httparty library to make HTTP requests, but you can use any other tool by including it in the project's Gemfile.
Installation
It is recommended to install Heroku CLI, Ngrok and Bundler before you start.
$ gem install rubotnik
And then create your bot with:
$ rubotnik new PROJECT_NAME
Now you can cd to PROJECT_NAME, open it in your favorite editing and start hacking!
To start playing with your bot directly from Messenger (after you've created an app in Facebook Developer Console):
$ bundle install
$ heroku local
And in a new Terminal tab:
$ ngrok http 5000
Usage
A project generated with rubotnik new will have a following simple structure:
.
├── Gemfile # contains a single dependency on "rubotnik" gem
├── Procfile # ready for Heroku
├── bot
│ ├── bot.rb # <-- YOUR STARTING POINT
│ ├── commands
│ │ ├── commands.rb # define any commands as methods here
│ │ ├── location.rb # or here (contains example for handling user location)
│ │ └── ui_examples.rb # or here (contains examples for UI elements)
│ └── profile.rb # Welcome page, "Get Started" button and a menu for your bot
├── config
│ └── puma.rb # Puma settings
└── config.ru # it's a Rack app, after all!
All the magic happens inside Rubotnik.route :message and Rubotnik.route :postback blocks, this is where you can use Rubotnik's DSL to bind user messages to "commands" that your bot is going to execute.
A "command" is just a plain Ruby method inside the Commands module that has access to message (or postback) and user objects. This is how you match incoming message to a command:
# Will match any of the words and their variations
bind "hello", "hi", "bonjour", "привет", to: :my_method_for_greeting
# Will match only if all words are present (ignoring order)
bind "what", "time", "is", all: true, to: :tell_time
# Same logic for postbacks
bind "ACTION_BUTTON", to: :action_for_button
bind can also take a block for a simple response that does not merit its own method:
bind "damn" do
say "Watch your language, human!"
end
If none of the commands are matched, a default block will be invoked
# Invoked if none of the commands recognized. Has to come last, after all binds
default do
say "Come again?"
end
Setup
-
Login to Facebook For Developers. In the top right corner, select My apps > Add a new app.
-
Select a product "Messenger"
-
Under Token Generation in Products > Messenger > Settings select a page for your bot, or create a new one. Copy the Page Access Token and insert it in
.envin the Rubotnik-generated project underACESS_TOKEN -
While still in
.env, come up with any string forVERIFY_TOKENvariable (or leave the defaultverify_me) -
From the Terminal, while being in the same folder as your project, open a new tab and run
heroku local. It will load environment variables from.envand start Puma server on port 5000. -
Open another tab und run
ngrok http 5000that will expose port 5000 to the Internet. (note, depending on your Ngrok installation, you may want to specify path tongrokexecutable when running it). -
Copy the Forwarding address from the ngrok tab. It should start with https://
-
In the Facebook dashboard, while still under Products > Messenger > Settings, click Setup Webhooks. Under Subscription Fields select "messages" and "messaging_postbacks". Under Callback URL, paste your ngrok secure forwarding address and postpend it with
/webhook(that's important!). Put your verification token under Verify Token -
Click Verify and Save. Once the modal closes, you will see that under Webhooks section in the dashboard you can now "Select a page to subscribe your webhook to the page events". Select your page and hit "Subscribe".
-
You're done! Now you can find your bot in Messenger under your page's name and start talking to it. Check with your generated project to see what commands are included for demonstration purposes. Start tweaking the bot to your liking!
Debugging your bot
Debugging bots under Facebook Messenger Platorfm is not the most pleasant experience — if your client can not handle the POST request to your webhook from the API that contains a message relayed from user — Facebook will try resending the message again and again, before finally disabling your bot if it still can not return a 200 response. In order to save you from that trouble, Rubotnik sets $DEBUG environment variable to "true" while you're on localhost.
While in this mode, every StandardError exception raised by your bot's code will be forwarded as a bot response to the chat dialogue, ensuring the conversation flow is never broken. As a developer, you will be able to see what is wrong with your bot while talking it. I find it a very natural experience.
Note that Rubotnik does not reload the server on code change. Every time you want to add a new feature or modify an existing one—you will have to relaunch heroku local after code save.
Currently, Rubotnik has quite a verbose logging to stdout that will help you make sense of what's going on.
Developing with Rubotnik
Messages, postbacks and menus
Your starting point is bot.rb file that serves your bot, enables its persistent menu and a greeting screen, and provides top-level routing for messages and postbacks.
Received messages and postbacks are instances of Facebook::Messenger::Incoming::Message and Facebook::Messenger::Incoming::Postback objects of facebook-messenger gem and have all the properties defined in its 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' } } ]
profile.rb contains constants that provide hash structures (mimicking JSON from Facebook docs) for payloads necessary to enable the "Start Button", "Welcome Screen" and "Persistent Menu" of your bot. Modify them to your liking. Note that it's better not to change them very often after enabling them, as Facebook caches interface elements.
You can enable them all or some of them by putting # Rubotnik.set_profile(Profile::START_BUTTON, Profile::START_GREETING, Profile::SIMPLE_MENU) in your code.
Users
Every connected user will be given it's own User object that is stored in the hash in memory, while your bot is running. You can reference user or @user (both will work) from anywhere inside your code.
user.id will give you an unique identifier for connected user (assigned by Facebook), and user.session is a hash that can be used for storing any user-related data during the session. For instance, you can design a thread of conversation that will ask user for some information, keep bits of that information as different keys under user.session hash and make a POST call with
