messenger-bot-client 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +9 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/README.md +593 -0
- data/Rakefile +8 -0
- data/app/controllers/messenger/messenger_controller.rb +89 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/circle.yml +6 -0
- data/config/routes.rb +8 -0
- data/lib/messenger-ruby.rb +57 -0
- data/lib/messenger/client.rb +19 -0
- data/lib/messenger/components/attachment.rb +33 -0
- data/lib/messenger/components/element.rb +13 -0
- data/lib/messenger/components/elements/bubble.rb +23 -0
- data/lib/messenger/components/elements/button.rb +25 -0
- data/lib/messenger/components/elements/image.rb +18 -0
- data/lib/messenger/components/elements/quick_reply.rb +24 -0
- data/lib/messenger/components/elements/receipt/address.rb +20 -0
- data/lib/messenger/components/elements/receipt/adjustment.rb +16 -0
- data/lib/messenger/components/elements/receipt/item.rb +20 -0
- data/lib/messenger/components/elements/receipt/order.rb +19 -0
- data/lib/messenger/components/elements/receipt/summary.rb +18 -0
- data/lib/messenger/components/elements/sender_action.rb +15 -0
- data/lib/messenger/components/elements/text.rb +15 -0
- data/lib/messenger/components/elements/video.rb +18 -0
- data/lib/messenger/components/templates/buttons.rb +20 -0
- data/lib/messenger/components/templates/generic.rb +19 -0
- data/lib/messenger/components/templates/quick_replies.rb +18 -0
- data/lib/messenger/components/templates/receipt.rb +40 -0
- data/lib/messenger/configuration.rb +10 -0
- data/lib/messenger/engine.rb +7 -0
- data/lib/messenger/parameters/account_linking.rb +14 -0
- data/lib/messenger/parameters/attachment.rb +23 -0
- data/lib/messenger/parameters/callback.rb +15 -0
- data/lib/messenger/parameters/delivery.rb +15 -0
- data/lib/messenger/parameters/entry.rb +17 -0
- data/lib/messenger/parameters/message.rb +29 -0
- data/lib/messenger/parameters/messaging.rb +24 -0
- data/lib/messenger/parameters/optin.rb +13 -0
- data/lib/messenger/parameters/postback.rb +13 -0
- data/lib/messenger/parameters/quick_reply.rb +11 -0
- data/lib/messenger/parameters/read.rb +14 -0
- data/lib/messenger/parameters/referral.rb +15 -0
- data/lib/messenger/params.rb +25 -0
- data/lib/messenger/request.rb +35 -0
- data/lib/messenger/version.rb +3 -0
- data/messenger-ruby.gemspec +31 -0
- metadata +219 -0
data/Rakefile
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
class MessengerController < ActionController::Base
|
5
|
+
def validate
|
6
|
+
if verify_token_valid? && access_token_valid?
|
7
|
+
render json: params["hub.challenge"]
|
8
|
+
elsif !verify_token_valid?
|
9
|
+
render json: 'Invalid verify token'
|
10
|
+
else
|
11
|
+
render json: 'Invalid page access token'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def subscribe
|
16
|
+
render json: activate_bot
|
17
|
+
rescue RestClient::BadRequest
|
18
|
+
render json: 'Invalid page access token'
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def app_location
|
24
|
+
"https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=#{Messenger.config.page_access_token}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def activate_bot
|
28
|
+
RestClient.post(app_location, nil)
|
29
|
+
end
|
30
|
+
|
31
|
+
def access_token_valid?
|
32
|
+
JSON.parse(RestClient.get(app_location)).key?('data')
|
33
|
+
rescue RestClient::BadRequest
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
|
37
|
+
def verify_token_valid?
|
38
|
+
params["hub.verify_token"] == Messenger.config.verify_token
|
39
|
+
end
|
40
|
+
|
41
|
+
def fb_params
|
42
|
+
safe_params = params.permit(:object,
|
43
|
+
entry: [
|
44
|
+
:id,
|
45
|
+
:time,
|
46
|
+
messaging: [
|
47
|
+
{ sender: :id },
|
48
|
+
:timestamp,
|
49
|
+
{ recipient: :id },
|
50
|
+
message:
|
51
|
+
[
|
52
|
+
:mid,
|
53
|
+
:seq,
|
54
|
+
{ sticker: :id },
|
55
|
+
:text,
|
56
|
+
{ attachments: [
|
57
|
+
:type,
|
58
|
+
:url,
|
59
|
+
:title,
|
60
|
+
payload: [
|
61
|
+
:url,
|
62
|
+
coordinates: [
|
63
|
+
:lat, :long
|
64
|
+
] ]
|
65
|
+
] },
|
66
|
+
{ quick_reply: :payload },
|
67
|
+
:is_echo,
|
68
|
+
{ app: :id },
|
69
|
+
:metadata
|
70
|
+
],
|
71
|
+
read: [
|
72
|
+
:watermark,
|
73
|
+
:seq
|
74
|
+
],
|
75
|
+
postback: :payload,
|
76
|
+
optin: :ref,
|
77
|
+
delivery: [
|
78
|
+
{ mids: [] },
|
79
|
+
:watermark,
|
80
|
+
:seq
|
81
|
+
],
|
82
|
+
account_linking: [
|
83
|
+
:status, :authorization_code
|
84
|
+
]
|
85
|
+
]])
|
86
|
+
Params.new(safe_params)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "messenger-ruby"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/circle.yml
ADDED
data/config/routes.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "messenger/version"
|
2
|
+
require "messenger/configuration"
|
3
|
+
|
4
|
+
module Messenger
|
5
|
+
class << self
|
6
|
+
attr_accessor :config
|
7
|
+
|
8
|
+
def config
|
9
|
+
@config ||= Configuration.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure
|
13
|
+
yield(config)
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset
|
17
|
+
@config = Configuration.new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require "messenger/engine"
|
23
|
+
require "messenger/params"
|
24
|
+
|
25
|
+
require "messenger/components/elements/text"
|
26
|
+
require "messenger/components/elements/image"
|
27
|
+
require "messenger/components/elements/button"
|
28
|
+
require "messenger/components/elements/bubble"
|
29
|
+
require "messenger/components/elements/quick_reply"
|
30
|
+
require "messenger/components/elements/sender_action"
|
31
|
+
|
32
|
+
require "messenger/parameters/attachment"
|
33
|
+
require "messenger/parameters/quick_reply"
|
34
|
+
require "messenger/parameters/callback"
|
35
|
+
require "messenger/parameters/entry"
|
36
|
+
require "messenger/parameters/messaging"
|
37
|
+
require "messenger/parameters/read"
|
38
|
+
require "messenger/parameters/account_linking"
|
39
|
+
|
40
|
+
require "messenger/parameters/delivery"
|
41
|
+
require "messenger/parameters/message"
|
42
|
+
require "messenger/parameters/optin"
|
43
|
+
require "messenger/parameters/postback"
|
44
|
+
|
45
|
+
require "messenger/components/elements/receipt/address"
|
46
|
+
require "messenger/components/elements/receipt/adjustment"
|
47
|
+
require "messenger/components/elements/receipt/item"
|
48
|
+
require "messenger/components/elements/receipt/order"
|
49
|
+
require "messenger/components/elements/receipt/summary"
|
50
|
+
|
51
|
+
require "messenger/components/templates/buttons"
|
52
|
+
require "messenger/components/templates/generic"
|
53
|
+
require "messenger/components/templates/receipt"
|
54
|
+
require "messenger/components/templates/quick_replies"
|
55
|
+
|
56
|
+
require "messenger/client"
|
57
|
+
require "messenger/request"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Messenger
|
2
|
+
class Client
|
3
|
+
def self.get_user_profile(user_id)
|
4
|
+
JSON.parse(RestClient.get(
|
5
|
+
"https://graph.facebook.com/v2.6/#{user_id}?access_token=#{Messenger.config.page_access_token}",
|
6
|
+
))
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.send(data)
|
10
|
+
RestClient.post(
|
11
|
+
"https://graph.facebook.com/v2.6/me/messages?access_token=#{Messenger.config.page_access_token}",
|
12
|
+
data.build.to_json,
|
13
|
+
content_type: :json
|
14
|
+
)
|
15
|
+
rescue RestClient::ExceptionWithResponse => err
|
16
|
+
puts "\nFacebook API response from invalid request:\n#{err.response}\n\n"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Messenger
|
2
|
+
module Components
|
3
|
+
module Attachment
|
4
|
+
attr_accessor :type
|
5
|
+
|
6
|
+
def build
|
7
|
+
{
|
8
|
+
attachment: {
|
9
|
+
type: @type,
|
10
|
+
payload: payload
|
11
|
+
}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def all_attributes
|
16
|
+
return instance_values unless defined?(flattened_attributes)
|
17
|
+
instance_values.merge! flattened_attributes
|
18
|
+
end
|
19
|
+
|
20
|
+
def payload
|
21
|
+
all_attributes.select { |attribute, value| allowed_attribute?(attribute) && value.present? }
|
22
|
+
end
|
23
|
+
|
24
|
+
def allowed_attribute?(attribute)
|
25
|
+
self.class::ATTRIBUTES.include?(attribute)
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_elements(elements)
|
29
|
+
elements.map { |element| element.build } if elements.present?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Messenger
|
2
|
+
module Components
|
3
|
+
module Element
|
4
|
+
def build
|
5
|
+
instance_values.delete_if { |_attribute, value| value.nil? }
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_elements(elements)
|
9
|
+
elements.map { |element| element.build } if elements.present?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'messenger/components/element'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
module Elements
|
5
|
+
class Bubble
|
6
|
+
include Components::Element
|
7
|
+
|
8
|
+
attr_accessor :title, :item_url, :image_url, :buttons
|
9
|
+
|
10
|
+
def initialize(title:, subtitle: nil, item_url: nil, image_url: nil, buttons: nil)
|
11
|
+
@title = title
|
12
|
+
@subtitle = subtitle
|
13
|
+
@image_url = image_url
|
14
|
+
@item_url = item_url
|
15
|
+
@buttons = build_buttons(buttons)
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_buttons(buttons)
|
19
|
+
buttons.map { |button| button.build } if buttons.present?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Messenger
|
2
|
+
module Elements
|
3
|
+
class Button
|
4
|
+
attr_accessor :type, :title, :value
|
5
|
+
|
6
|
+
def initialize(type:, title:, value:)
|
7
|
+
@type = type
|
8
|
+
@title = title
|
9
|
+
@value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def build
|
13
|
+
{ type: @type, title: @title }.merge! eval(@type.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def web_url
|
17
|
+
{ url: @value }
|
18
|
+
end
|
19
|
+
|
20
|
+
def postback
|
21
|
+
{ payload: @value }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'messenger/components/attachment'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
module Elements
|
5
|
+
class Image
|
6
|
+
include Components::Attachment
|
7
|
+
|
8
|
+
attr_accessor :url
|
9
|
+
|
10
|
+
ATTRIBUTES = %w(url).freeze
|
11
|
+
|
12
|
+
def initialize(url:)
|
13
|
+
@url = url
|
14
|
+
@type = 'image'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'messenger/components/element'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
module Elements
|
5
|
+
class QuickReply
|
6
|
+
include Components::Element
|
7
|
+
|
8
|
+
attr_accessor :content_type, :title, :payload, :image_url
|
9
|
+
|
10
|
+
def initialize(content_type:, title: nil, payload: nil, image_url: nil)
|
11
|
+
@content_type = content_type
|
12
|
+
@title = title if text?(content_type)
|
13
|
+
@payload = payload if text?(content_type)
|
14
|
+
@image_url = image_url
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def text?(value)
|
20
|
+
value == 'text'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'messenger/components/element'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
module Elements
|
5
|
+
class Address
|
6
|
+
include Components::Element
|
7
|
+
|
8
|
+
attr_accessor :street_1, :street_2, :city, :postal_code, :state, :country
|
9
|
+
|
10
|
+
def initialize(street_1:, street_2: nil, city:, postal_code:, state:, country:)
|
11
|
+
@street_1 = street_1
|
12
|
+
@street_2 = street_2
|
13
|
+
@city = city
|
14
|
+
@postal_code = postal_code
|
15
|
+
@state = state
|
16
|
+
@country = country
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'messenger/components/element'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
module Elements
|
5
|
+
class Adjustment
|
6
|
+
include Components::Element
|
7
|
+
|
8
|
+
attr_accessor :name, :amount
|
9
|
+
|
10
|
+
def initialize(name: nil, amount: nil)
|
11
|
+
@name = name
|
12
|
+
@amount = amount
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'messenger/components/element'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
module Elements
|
5
|
+
class Item
|
6
|
+
include Components::Element
|
7
|
+
|
8
|
+
attr_accessor :title, :subtitle, :quantity, :price, :currency, :image_url
|
9
|
+
|
10
|
+
def initialize(title:, subtitle: nil, quantity: nil, price: nil, currency: nil, image_url: nil)
|
11
|
+
@title = title
|
12
|
+
@subtitle = subtitle
|
13
|
+
@quantity = quantity
|
14
|
+
@price = price
|
15
|
+
@currency = currency
|
16
|
+
@image_url = image_url
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'messenger/components/element'
|
2
|
+
|
3
|
+
module Messenger
|
4
|
+
module Elements
|
5
|
+
class Order
|
6
|
+
include Components::Element
|
7
|
+
|
8
|
+
attr_accessor :order_number, :currency, :payment_method, :timestamp, :order_url
|
9
|
+
|
10
|
+
def initialize(order_number:, currency:, payment_method:, timestamp: nil, order_url: nil)
|
11
|
+
@order_number = order_number
|
12
|
+
@currency = currency
|
13
|
+
@payment_method = payment_method
|
14
|
+
@timestamp = timestamp
|
15
|
+
@order_url = order_url
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|