messenger-bot-client 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +9 -0
  3. data/.gitignore +6 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +4 -0
  6. data/README.md +593 -0
  7. data/Rakefile +8 -0
  8. data/app/controllers/messenger/messenger_controller.rb +89 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/circle.yml +6 -0
  12. data/config/routes.rb +8 -0
  13. data/lib/messenger-ruby.rb +57 -0
  14. data/lib/messenger/client.rb +19 -0
  15. data/lib/messenger/components/attachment.rb +33 -0
  16. data/lib/messenger/components/element.rb +13 -0
  17. data/lib/messenger/components/elements/bubble.rb +23 -0
  18. data/lib/messenger/components/elements/button.rb +25 -0
  19. data/lib/messenger/components/elements/image.rb +18 -0
  20. data/lib/messenger/components/elements/quick_reply.rb +24 -0
  21. data/lib/messenger/components/elements/receipt/address.rb +20 -0
  22. data/lib/messenger/components/elements/receipt/adjustment.rb +16 -0
  23. data/lib/messenger/components/elements/receipt/item.rb +20 -0
  24. data/lib/messenger/components/elements/receipt/order.rb +19 -0
  25. data/lib/messenger/components/elements/receipt/summary.rb +18 -0
  26. data/lib/messenger/components/elements/sender_action.rb +15 -0
  27. data/lib/messenger/components/elements/text.rb +15 -0
  28. data/lib/messenger/components/elements/video.rb +18 -0
  29. data/lib/messenger/components/templates/buttons.rb +20 -0
  30. data/lib/messenger/components/templates/generic.rb +19 -0
  31. data/lib/messenger/components/templates/quick_replies.rb +18 -0
  32. data/lib/messenger/components/templates/receipt.rb +40 -0
  33. data/lib/messenger/configuration.rb +10 -0
  34. data/lib/messenger/engine.rb +7 -0
  35. data/lib/messenger/parameters/account_linking.rb +14 -0
  36. data/lib/messenger/parameters/attachment.rb +23 -0
  37. data/lib/messenger/parameters/callback.rb +15 -0
  38. data/lib/messenger/parameters/delivery.rb +15 -0
  39. data/lib/messenger/parameters/entry.rb +17 -0
  40. data/lib/messenger/parameters/message.rb +29 -0
  41. data/lib/messenger/parameters/messaging.rb +24 -0
  42. data/lib/messenger/parameters/optin.rb +13 -0
  43. data/lib/messenger/parameters/postback.rb +13 -0
  44. data/lib/messenger/parameters/quick_reply.rb +11 -0
  45. data/lib/messenger/parameters/read.rb +14 -0
  46. data/lib/messenger/parameters/referral.rb +15 -0
  47. data/lib/messenger/params.rb +25 -0
  48. data/lib/messenger/request.rb +35 -0
  49. data/lib/messenger/version.rb +3 -0
  50. data/messenger-ruby.gemspec +31 -0
  51. metadata +219 -0
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ task default: :spec
5
+
6
+ task :console do
7
+ exec "irb -r messenger-ruby -I ./lib"
8
+ end
@@ -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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/circle.yml ADDED
@@ -0,0 +1,6 @@
1
+ dependencies:
2
+ pre:
3
+ - gem install bundler --pre
4
+ machine:
5
+ ruby:
6
+ version: 2.2.0
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ Messenger::Engine.routes.draw do
2
+ get :subscribe, to: "messenger#subscribe"
3
+ get :webhook, to: "messenger#validate"
4
+ end
5
+
6
+ Rails.application.routes.draw do
7
+ post 'messenger/webhook', to: "messenger#webhook"
8
+ end
@@ -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