messenger-ruby
A simple library for supporting implementation of Facebook Messenger Bot in Ruby on Rails.
Requirments
ruby 2.1+
Installation
Add this line to your application's Gemfile:
gem 'messenger-ruby'
And then execute:
$ bundle
Or install it yourself as:
$ gem install messenger-ruby
Configuration
Facebook steps
- create Facebook page (skip if you want to use existing page)
- create Facebook app (skip if you want to use existing app)
- go to Facebook for Developers and get
Page Access Token
(step 3. Get Page Access Token from this tutorial)
Initializer
Create messenger.rb
initializer in you app directory and paste Page Access Token
from previous step:
# YOUR_APP/config/initializers/messenger.rb
Messenger.configure do |config|
config.verify_token = '<VERIFY_TOKEN>' #will be used in webhook verifiction
config.page_access_token = '<PAGE_ACCESS_TOKEN>'
end
Routes
Add to your routes.rb
:
# YOUR_APP/config/routes.rb
mount Messenger::Engine, at: "/messenger"
Controller
Create messenger_controller.rb
in your controllers directory - controller has to inherit from Messenger::MessengerController
:
# YOUR_APP/app/controllers/messenger_controller.rb
class MessengerController < Messenger::MessengerController
def webhook
#logic here
head :ok
end
end
2XX
status is necessary to not clog your bot.
If you want your controller to be named differently, please update your routes.rb
with appropriate route for post /messenger/webhook
request.
Bot subscription
Run your application and:
- complete step 2. Setup Webhook from this tutorial - if you mounted
Messenger::Engine
at/messenger
and your application can be found athttps://example.com
, yourCallback URL
will behttps://example.com/messenger/webhook
- select
message_deliveries
,messages
,messaging_optins
andmessaging_postbacks
under Subscription Fields
- select
- visit
/messenger/subscribe
in your app (it's replacement for 4. Subscribe the App to the Page step) - callsubscribe
action anytime you want to refresh subscription of your app
Usage
To send message you need to create Messenger::Request with one of the available components and pass it to Messenger::Client::send method. You can send message only to users who subscribed to your page (e.g. sent some message before).
Messenger::Request
It's used to build parameters for Facebook API. Requires component and recipient_id
.
Example usage:
Messenger::Request.new(some_component, recipient_id)
Messenger::Client
Sends requests to Facebook API. Has two methods:
get_user_profile
- requires id of existing facebook usersend
- requires Messenger::Request object
Example usage:
Messenger::Client.get_user_profile(user_id) #=> hash with name, surname and profile picture
Messenger::Client.send(request) #=> hash with message details or exception if request is incorrect
Please note that unsuccessful send
will be shown in logs as Facebook API response from invalid request: ...
Elements
Elements can't be used outside of templates.
Button
Lives inside Bubble element or Button template.
Attribute | Allowed values | Required? |
---|---|---|
type | 'web_url' , 'postback' |
✔ |
title | String | ✔ |
value | String | ✔ |
Example usage:
Messenger::Elements::Button.new(type: 'web_url', title: 'Button', value: 'http://github.com')
Bubble
Part of Generic template.
Attribute | Allowed values | Required? |
---|---|---|
title | String | ✔ |
subtitle | String | ✔* |
image_url | String | ✔* |
buttons | Messenger::Elements::Button objects array |
✔* |
item_url | String | ✘ |
*
- at least one of them is required
Example usage:
Messenger::Elements::Bubble.new(title: 'First', subtitle: 'Bubble')
Quick Reply
Used by Quick Replies.
Attribute | Allowed values | Required? |
---|---|---|
content_type | 'text' or 'location' | ✔ |
title | String | only if content_type is 'text' |
payload | String | only if content_type is 'text' |
image_url | String | ✘ |
Example usage:
Messenger::Elements::QuickReply.new(
content_type: 'text',
title: 'SomeTitle',
payload: "PAYLOAD"
)
Address
Used by Receipt template.
Attribute | Allowed values | Required? |
---|---|---|
street_1 | String | ✔ |
street_2 | String | ✘ |
city | String | ✔ |
postal_code | String | ✔ |
state | String | ✔ |
country | String | ✔ |
Example usage:
Messenger::Elements::Address.new(
street_1: 'Vachel Lindsay Dr',
street_2: '',
city: 'Springfield',
postal_code: '62701',
state: 'IL',
country:'USA'
)
Adjustment
Used by Receipt template.
Attribute | Allowed values | Required? |
---|---|---|
name | String | ✔ |
amount | Integer, greater than 0 | ✔ |
Example usage:
Messenger::Elements::Adjustment.new(name: 'Adjustment 1', amount: 20)
Item
Used by Receipt template.
Attribute | Allowed values | Required? |
---|---|---|
title | String | ✔ |
subtilte | String | ✘ |
quantity | Integer | ✘ |
price | Decimal | ✘ |
currency | String, from ISO 4217 Currency Codes | ✘ |
image_url | String | ✘ |
Example usage:
Messenger::Elements::Item.new(
title: 'Cool Tshirt',
subtitle: 'XXL White',
quantity: 3,
price: 34,
currency: 'USD',
image_url: 'http://assets.servedby-buysellads.com/p/manage/asset/id/25397'
)
Order
Used by Receipt template.
Attribute | Allowed values | Required? |
---|---|---|
order_number | String, unique per conversation | ✔ |
currency | String, from ISO 4217 Currency Codes | ✔ |
payment_method | String | ✔ |
timestamp | correct timestamp (String) | ✘ |
order_url | String | ✘ |
Example usage:
Messenger::Elements::Order.new(
order_number: 'R190581345',
currency: 'USD',
payment_method: 'Visa',
timestamp: '1428444852',
order_url: 'http://petersapparel.parseapp.com/order?order_id=123456'
)
Summary
Used by Receipt template.
Attribute | Allowed values | Required? |
---|---|---|
subtotal | Decimal | ✘ |
shipping_cost | Decimal | ✘ |
total_tax | Decimal | ✘ |
total_cost | Decimal | ✔ |
Example usage:
Messenger::Elements::Summary.new(subtotal: 70, shipping_cost: 20, total_tax: 10, total_cost: 100)
Components
You can find more info about what can be send in Messenger Platform Docs.
Text
Attribute | Allowed values | Required? |
---|---|---|
text | String | ✔ |
Here is complete example on how to send sample text to the user:
if fb_params.first_entry.callback.
Messenger::Client.send(
Messenger::Request.new(
Messenger::Elements::Text.new(text: 'some text'),
fb_params.first_entry.sender_id
)
)
end
#make sure to send 200 at the end
head :ok
Image
Attribute | Allowed values | Required? |
---|---|---|
url | String | ✔ |
Sending images is simple as well:
...
Messenger::Client.send(
Messenger::Request.new(
Messenger::Elements::Image.new(url: 'http://lorempixel.com/400/400/cats'),
fb_params.first_entry.sender_id
)
)
...
Sender Actions
Attribute | Allowed values | Required? |
---|---|---|
sender_action | 'typing_on', 'typing_off' or 'mark_seen' | ✔ |
Sending send action:
...
Messenger::Client.send(
Messenger::Request.new(
Messenger::Elements::SenderAction.new(sender_action: 'mark_seen'),
fb_params.first_entry.sender_id
)
)
...
Quick Replies
Attribute | Allowed values | Required? |
---|---|---|
text | String | attachment or text must be set |
attachment | Attachment object | attachment or text must be set |
quick_reply | Array of Messenger::Elements::QuickReply objects | ✘ |
Example usage
#define quick_replies here...
quick_replies = Messenger::Templates::QuickReplies.new(
text: "Green or Red?",
quick_replies: [
Messenger::Elements::QuickReply.new(
content_type: 'text',
title: 'Green',
payload: 'GREEN'
),
Messenger::Elements::QuickReply.new(
content_type: 'text',
title: 'Red',
payload: "RED"
)
]
)
#now send quick_replies to the user
Messenger::Client.send(
Messenger::Request.new(quick_replies, fb_params.first_entry.sender_id)
)
Generic template
Attribute | Allowed values | Required? |
---|---|---|
elements | Array of Messenger::Elements::Bubble objects | ✔ |
Example usage:
#define bubbles here...
bubble1 = Messenger::Elements::Bubble.new(
title: 'Bubble 1',
subtitle: 'Cool Bubble',
item_url: 'http://lorempixel.com/400/400/cats',
image_url: 'http://lorempixel.com/400/400/cats',
buttons: [
Messenger::Elements::Button.new(
type: 'web_url',
title: 'Show Website',
value: 'https://petersapparel.parseapp.com'
)
]
)
bubble2 = ...
#lets create Generic template
generic = Messenger::Templates::Generic.new(
elements: [bubble1, bubble2]
)
#now send Generic template to the user
Messenger::Client.send(
Messenger::Request.new(generic, fb_params.first_entry.sender_id)
)
Button template
Attribute | Allowed values | Required? |
---|---|---|
text | String | ✔ |
buttons | Array of Messenger::Elements::Button objects | ✔ |
Example usage:
#lets create Buttons template
= Messenger::Templates::Buttons.new(
text: 'Some Cool Text',
buttons: [
Messenger::Elements::Button.new(
type: 'web_url',
title: 'Show Website',
value: 'https://petersapparel.parseapp.com'
)
]
)
#now send Buttons template to the user
Messenger::Client.send(
Messenger::Request.new(, fb_params.first_entry.sender_id)
)
Receipt template
Attribute | Allowed values | Required? |
---|---|---|
recipient_name | String | ✔ |
order | Messenger::Elements::Order object | ✔ |
elements | Array of Messenger::Elements::Item objects | ✔ |
address | Messenger::Elements::Address object | ✘ |
summary | Messenger::Elements::Summary object | ✔ |
adjustments | Array of Messenger::Elements::Adjustment objects | ✘ |
Example usage:
#define order element here...
order = Messenger::Elements::Order.new(
order_number: 'R190581345',
currency: 'USD',
payment_method: 'Visa',
timestamp: '1428444852',
order_url: 'http://petersapparel.parseapp.com/order?order_id=123456'
)
#and define all other template elements
item1 = ...
item2 = ...
address = ...
summary = ...
adjustment1 = ...
adjustment2 = ...
#lets create Receipt template
receipt = Messenger::Templates::Receipt.new(
recipient_name: 'Random Recipient',
order: order,
elements: [item1, item2],
address: address,
summary: summary,
adjustments: [adjustment1, adjustment2]
)
#now send Receipt template to the user
Messenger::Client.send(
Messenger::Request.new(receipt, fb_params.first_entry.sender_id)
)
Entries
According to Facebook documentation, there is possibility that you can receive multiple entries
and multiple messagings
.
That's why we made it easy for you to iterate over entries
and messagings
, but we've also created first_entry
method
that returns first entry in entry
array, because that is the most common case.
Example usage:
fb_params.entries.each do |entry|
entry.messagings.each do |messaging|
if messaging.callback.
Messenger::Client.send(
Messenger::Request.new(
Messenger::Elements::Text.new(text: "Echo: #{messaging.callback.text}"),
messaging.sender_id
)
)
end
end
end
Or with first_entry
method:
if fb_params.first_entry.callback.
Messenger::Client.send(
Messenger::Request.new(
Messenger::Elements::Text.new(text: "Echo: #{fb_params.first_entry.callback.text}"),
fb_params.first_entry.sender_id
)
)
end
fb_params
Has control over entries received from Facebook API. For more informations please visit Messenger Platform Docs. fb_params
includes array of Entry objects.
Entry
Attribute | Additional info |
---|---|
id | String, unique for conversation |
time | String, timestamp format |
messagings | Array of Messenger::Parameters::Messaging objects |
Messaging
Attribute | Additional info |
---|---|
sender_id | String |
recipient_id | String |
callback | Messenger::Parameters::Message, Messenger::Parameters::Delivery, Messenger::Parameters::Optin, Messenger::Parameters::Delivery, Messenger::Parameters::Read or Messenger::Parameters::AccountLinking object |
Callback responds to following methods to help detect types:
Method | Type returned |
---|---|
message? | Boolean |
delivery? | Boolean |
optin? | Boolean |
postback? | Boolean |
read? | Boolean |
account_linking? | Boolean |
Message
Attribute | Additional info |
---|---|
mid | |
seq | |
sticker_id | |
text |
s | Array of Messenger::Parameters::Attachment objects is_echo | app_id | metadata |
Attachment
Delivery
Optin
Postback
Read
Account Linking
Example usage:
fb_params.first_entry.callback.
fb_params.first_entry.callback.postback?
fb_params.first_entry.callback.delivery?
fb_params.first_entry.callback.optin?
fb_params.first_entry.callback.
fb_params.first_entry.callback.text
Development
After checking out the repo, run bin/setup
to install dependencies. You can also run rake console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/netguru/messenger-ruby.
License
The gem is available as open source under the terms of the MIT License.