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
Initializer
Create messenger.rb
initializer in you app directory and paste Page Access Token
from previous step:
Messenger.configure do |config|
config.verify_token = '<VERIFY_TOKEN>'
config.page_access_token = '<PAGE_ACCESS_TOKEN>'
end
Routes
Add to your routes.rb
:
mount Messenger::Engine, at: "/messenger"
Controller
Create messenger_controller.rb
in your controllers directory - controller has to inherit from Messenger::MessengerController
:
class MessengerController < Messenger::MessengerController
def webhook
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 at https://example.com
, your Callback URL
will be https://example.com/messenger/webhook
- select
message_deliveries
, messages
, messaging_optins
and messaging_postbacks
under Subscription Fields - visit
/messenger/subscribe
in your app (it's replacement for 4. Subscribe the App to the Page step) - call subscribe
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)
Messenger::Client.send(request)
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.message?
Messenger::Client.send(
Messenger::Request.new(
Messenger::Elements::Text.new(text: 'some text'),
fb_params.first_entry.sender_id
)
)
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
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"
)
]
)
Messenger::Client.send(
Messenger::Request.new(quick_replies, fb_params.first_entry.sender_id)
)
Generic template
Example usage:
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 = ...
generic = Messenger::Templates::Generic.new(
elements: [bubble1, bubble2]
)
Messenger::Client.send(
Messenger::Request.new(generic, fb_params.first_entry.sender_id)
)
Button template
Example usage:
buttons = Messenger::Templates::Buttons.new(
text: 'Some Cool Text',
buttons: [
Messenger::Elements::Button.new(
type: 'web_url',
title: 'Show Website',
value: 'https://petersapparel.parseapp.com'
)
]
)
Messenger::Client.send(
Messenger::Request.new(buttons, fb_params.first_entry.sender_id)
)
Receipt template
Example usage:
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'
)
item1 = ...
item2 = ...
address = ...
summary = ...
adjustment1 = ...
adjustment2 = ...
receipt = Messenger::Templates::Receipt.new(
recipient_name: 'Random Recipient',
order: order,
elements: [item1, item2],
address: address,
summary: summary,
adjustments: [adjustment1, adjustment2]
)
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.message?
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.message?
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
Messaging
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.message?
fb_params.first_entry.callback.postback?
fb_params.first_entry.callback.delivery?
fb_params.first_entry.callback.optin?
fb_params.first_entry.callback.attachments
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.
License
The gem is available as open source under the terms of the MIT License.