meta-messenger 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +681 -0
  3. data/bin/console +14 -0
  4. data/bin/setup +8 -0
  5. data/lib/facebook/messenger/bot/error_parser.rb +111 -0
  6. data/lib/facebook/messenger/bot/exceptions.rb +15 -0
  7. data/lib/facebook/messenger/bot/message_type.rb +13 -0
  8. data/lib/facebook/messenger/bot/messaging_type.rb +12 -0
  9. data/lib/facebook/messenger/bot/tag.rb +27 -0
  10. data/lib/facebook/messenger/bot.rb +180 -0
  11. data/lib/facebook/messenger/configuration/app_secret_proof_calculator.rb +16 -0
  12. data/lib/facebook/messenger/configuration/providers/base.rb +48 -0
  13. data/lib/facebook/messenger/configuration/providers/environment.rb +29 -0
  14. data/lib/facebook/messenger/configuration/providers.rb +13 -0
  15. data/lib/facebook/messenger/configuration.rb +12 -0
  16. data/lib/facebook/messenger/error.rb +44 -0
  17. data/lib/facebook/messenger/incoming/account_linking.rb +28 -0
  18. data/lib/facebook/messenger/incoming/common.rb +131 -0
  19. data/lib/facebook/messenger/incoming/delivery.rb +23 -0
  20. data/lib/facebook/messenger/incoming/feed.rb +16 -0
  21. data/lib/facebook/messenger/incoming/feed_common.rb +17 -0
  22. data/lib/facebook/messenger/incoming/game_play.rb +39 -0
  23. data/lib/facebook/messenger/incoming/leadgen.rb +13 -0
  24. data/lib/facebook/messenger/incoming/message.rb +159 -0
  25. data/lib/facebook/messenger/incoming/message_echo.rb +10 -0
  26. data/lib/facebook/messenger/incoming/message_reaction.rb +23 -0
  27. data/lib/facebook/messenger/incoming/message_request.rb +13 -0
  28. data/lib/facebook/messenger/incoming/optin.rb +34 -0
  29. data/lib/facebook/messenger/incoming/pass_thread_control.rb +22 -0
  30. data/lib/facebook/messenger/incoming/payment.rb +49 -0
  31. data/lib/facebook/messenger/incoming/policy_enforcement.rb +21 -0
  32. data/lib/facebook/messenger/incoming/postback.rb +26 -0
  33. data/lib/facebook/messenger/incoming/read.rb +21 -0
  34. data/lib/facebook/messenger/incoming/referral.rb +47 -0
  35. data/lib/facebook/messenger/incoming.rb +85 -0
  36. data/lib/facebook/messenger/profile.rb +92 -0
  37. data/lib/facebook/messenger/server.rb +195 -0
  38. data/lib/facebook/messenger/server_no_error.rb +36 -0
  39. data/lib/facebook/messenger/subscriptions.rb +85 -0
  40. data/lib/facebook/messenger/version.rb +7 -0
  41. data/lib/facebook/messenger.rb +32 -0
  42. metadata +229 -0
@@ -0,0 +1,111 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Bot
4
+ # Parses and raises Facebook response errors for the send API.
5
+ class ErrorParser
6
+ INTERNAL_ERROR_CODES = {
7
+ 1200 => []
8
+ }.freeze
9
+
10
+ ACCESS_TOKEN_ERROR_CODES = {
11
+ 190 => []
12
+ }.freeze
13
+
14
+ ACCOUNT_LINKING_ERROR_CODES = {
15
+ 10_303 => []
16
+ }.freeze
17
+
18
+ LIMIT_ERROR_CODES = {
19
+ 4 => [2_018_022],
20
+ 100 => [2_018_109],
21
+ 613 => [nil]
22
+ }.freeze
23
+
24
+ BAD_PARAMETER_ERROR_CODES = {
25
+ 100 => [nil, 2_018_001]
26
+ }.freeze
27
+
28
+ PERMISSION_ERROR_CODES = {
29
+ 10 => [2_018_065, 2_018_108],
30
+ 200 => [1_545_041, 2_018_028, 2_018_027, 2_018_021],
31
+ 230 => [nil]
32
+ }.freeze
33
+
34
+ class << self
35
+ # Raise any errors in the given response.
36
+ #
37
+ # response - A HTTParty::Response object.
38
+ #
39
+ # Returns nil if no errors were found, otherwises raises appropriately
40
+ def raise_errors_from(response)
41
+ return unless response.key? 'error'
42
+
43
+ error = response['error']
44
+
45
+ error_code = error['code']
46
+ error_subcode = error['error_subcode']
47
+
48
+ raise_code_only_error(error_code, error) if error_subcode.nil?
49
+
50
+ raise_code_subcode_error(error_code, error_subcode, error)
51
+
52
+ # Default to unidentified error
53
+ raise FacebookError, error
54
+ end
55
+
56
+ private
57
+
58
+ def raise_code_only_error(error_code, args)
59
+ raise InternalError, args if internal_error?(error_code)
60
+ raise AccessTokenError, args if access_token_error?(error_code)
61
+ raise AccountLinkingError, args if account_linking_error?(
62
+ error_code
63
+ )
64
+ end
65
+
66
+ def raise_code_subcode_error(error_code, error_subcode, args)
67
+ raise LimitError, args if limit_error?(error_code,
68
+ error_subcode)
69
+ raise BadParameterError, args if bad_parameter_error?(error_code,
70
+ error_subcode)
71
+ raise PermissionError, args if permission_error?(error_code,
72
+ error_subcode)
73
+ end
74
+
75
+ def internal_error?(error_code)
76
+ INTERNAL_ERROR_CODES.key? error_code
77
+ end
78
+
79
+ def access_token_error?(error_code)
80
+ ACCESS_TOKEN_ERROR_CODES.key? error_code
81
+ end
82
+
83
+ def account_linking_error?(error_code)
84
+ ACCOUNT_LINKING_ERROR_CODES.key? error_code
85
+ end
86
+
87
+ def limit_error?(error_code, error_subcode)
88
+ limit_errors = LIMIT_ERROR_CODES[error_code]
89
+ return unless limit_errors
90
+
91
+ limit_errors.include? error_subcode
92
+ end
93
+
94
+ def bad_parameter_error?(error_code, error_subcode)
95
+ bad_parameter_errors = BAD_PARAMETER_ERROR_CODES[error_code]
96
+ return unless bad_parameter_errors
97
+
98
+ bad_parameter_errors.include? error_subcode
99
+ end
100
+
101
+ def permission_error?(error_code, error_subcode)
102
+ permission_errors = PERMISSION_ERROR_CODES[error_code]
103
+ return unless permission_errors
104
+
105
+ permission_errors.include? error_subcode
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,15 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Bot
4
+ # Base Facebook Messenger send API exception.
5
+ class SendError < Facebook::Messenger::FacebookError; end
6
+
7
+ class AccessTokenError < SendError; end
8
+ class AccountLinkingError < SendError; end
9
+ class BadParameterError < SendError; end
10
+ class InternalError < SendError; end
11
+ class LimitError < SendError; end
12
+ class PermissionError < SendError; end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Bot
4
+ # Supported message types
5
+ module MessageType
6
+ RESPONSE = 'RESPONSE'.freeze
7
+ UPDATE = 'UPDATE'.freeze
8
+ MESSAGE_TAG = 'MESSAGE_TAG'.freeze
9
+ NON_PROMOTIONAL_SUBSCRIPTION = 'NON_PROMOTIONAL_SUBSCRIPTION'.freeze
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Bot
4
+ # Supported message types
5
+ module MessagingType
6
+ RESPONSE = 'RESPONSE'.freeze
7
+ UPDATE = 'UPDATE'.freeze
8
+ MESSAGE_TAG = 'MESSAGE_TAG'.freeze
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Bot
4
+ # Supported tags.
5
+ # Note: A tag is required when sending messages with the
6
+ # message type `MESSAGE_TAG`.
7
+ module Tag
8
+ COMMUNITY_ALERT = 'COMMUNITY_ALERT'.freeze
9
+ CONFIRMED_EVENT_REMINDER = 'CONFIRMED_EVENT_REMINDER'.freeze
10
+ NON_PROMOTIONAL_SUBSCRIPTION = 'NON_PROMOTIONAL_SUBSCRIPTION'.freeze
11
+ PAIRING_UPDATE = 'PAIRING_UPDATE'.freeze
12
+ APPLICATION_UPDATE = 'APPLICATION_UPDATE'.freeze
13
+ ACCOUNT_UPDATE = 'ACCOUNT_UPDATE'.freeze
14
+ PAYMENT_UPDATE = 'PAYMENT_UPDATE'.freeze
15
+ PERSONAL_FINANCE_UPDATE = 'PERSONAL_FINANCE_UPDATE'.freeze
16
+ SHIPPING_UPDATE = 'SHIPPING_UPDATE'.freeze
17
+ RESERVATION_UPDATE = 'RESERVATION_UPDATE'.freeze
18
+ ISSUE_RESOLUTION = 'ISSUE_RESOLUTION'.freeze
19
+ APPOINTMENT_UPDATE = 'APPOINTMENT_UPDATE'.freeze
20
+ GAME_EVENT = 'GAME_EVENT'.freeze
21
+ TRANSPORTATION_UPDATE = 'TRANSPORTATION_UPDATE'.freeze
22
+ FEATURE_FUNCTIONALITY_UPDATE = 'FEATURE_FUNCTIONALITY_UPDATE'.freeze
23
+ TICKET_UPDATE = 'TICKET_UPDATE'.freeze
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,180 @@
1
+ require 'facebook/messenger/bot/error_parser'
2
+ require 'facebook/messenger/bot/exceptions'
3
+ require 'facebook/messenger/bot/message_type'
4
+ require 'facebook/messenger/bot/messaging_type'
5
+ require 'facebook/messenger/bot/tag'
6
+
7
+ module Facebook
8
+ module Messenger
9
+ #
10
+ # Module Bot provides functionality to sends and receives messages.
11
+ #
12
+ module Bot
13
+ include HTTParty
14
+
15
+ # Define base_uri for HTTParty.
16
+ base_uri 'https://graph.facebook.com/v20.0'
17
+
18
+ #
19
+ # @return [Array] Array containing the supported webhook events.
20
+ EVENTS = %i[
21
+ message
22
+ delivery
23
+ postback
24
+ optin
25
+ read
26
+ account_linking
27
+ referral
28
+ message_echo
29
+ payment
30
+ policy_enforcement
31
+ pass_thread_control
32
+ game_play
33
+ reaction
34
+ feed
35
+ leadgen
36
+ ].freeze
37
+
38
+ class << self
39
+ # Deliver a message with the given payload.
40
+ # @see https://developers.facebook.com/docs/messenger-platform/send-api-reference#request
41
+ #
42
+ # @raise [Facebook::Messenger::Bot::SendError] if there is any error
43
+ # in response while sending message.
44
+ #
45
+ # @param [Hash] message The message payload
46
+ # @param [String] page_id The page to send the message from
47
+ #
48
+ # Returns a String describing the message ID if the message was sent,
49
+ # or raises an exception if it was not.
50
+ def deliver(message, page_id:)
51
+ access_token = config.provider.access_token_for(page_id)
52
+ app_secret_proof = config.provider.app_secret_proof_for(page_id)
53
+
54
+ query = { access_token: access_token }
55
+ query[:appsecret_proof] = app_secret_proof if app_secret_proof
56
+
57
+ response = post '/me/messages',
58
+ body: JSON.dump(message),
59
+ format: :json,
60
+ query: query
61
+
62
+ Facebook::Messenger::Bot::ErrorParser.raise_errors_from(response)
63
+
64
+ response.body
65
+ end
66
+
67
+ # Reply to a Facebook comment.
68
+ # @see https://developers.facebook.com/docs/graph-api/reference/v20.0/object/comments
69
+ #
70
+ # @raise [Facebook::Messenger::Bot::SendError] if there is any error
71
+ # in response while sending the comment.
72
+ #
73
+ # @param [Hash] comment The comment payload
74
+ # @param [String] page_id The page ID to send the comment from
75
+ #
76
+ # Returns a Hash describing the API response if the comment was sent,
77
+ # or raises an exception if it was not.
78
+ def reply_to_comment(comment_id, message, page_id:)
79
+ access_token = config.provider.access_token_for(page_id)
80
+ app_secret_proof = config.provider.app_secret_proof_for(page_id)
81
+
82
+ query = { access_token: access_token }
83
+ query[:appsecret_proof] = app_secret_proof if app_secret_proof
84
+
85
+ response = post "/#{comment_id}/comments",
86
+ body: JSON.dump(message),
87
+ format: :json,
88
+ query: query
89
+
90
+ Facebook::Messenger::Bot::ErrorParser.raise_errors_from(response)
91
+
92
+ response.body
93
+ end
94
+
95
+ # Register a hook for the given event.
96
+ #
97
+ # @raise [ArgumentError] if received event is not registered.
98
+ #
99
+ # @param [String] event A String describing a Messenger event.
100
+ # @param [Block] block A code block to run upon the event.
101
+ #
102
+ # @return Save event and its block in hooks.
103
+ def on(event, &block)
104
+ unless EVENTS.include? event
105
+ raise ArgumentError,
106
+ "#{event} is not a valid event; " \
107
+ "available events are #{EVENTS.join(',')}"
108
+ end
109
+
110
+ hooks[event] = block
111
+ end
112
+
113
+ # Receive a given message from Messenger.
114
+ #
115
+ # @see https://developers.facebook.com/docs/messenger-platform/webhook-reference
116
+ #
117
+ # @param [Hash] payload A Hash describing the message.
118
+ #
119
+ # @return pass event and object of callback class to trigger function.
120
+ #
121
+ def receive(payload)
122
+ callback = Facebook::Messenger::Incoming.parse(payload)
123
+ event = Facebook::Messenger::Incoming::EVENTS.invert[callback.class]
124
+ trigger(event.to_sym, callback)
125
+ end
126
+
127
+ # Trigger the hook for the given event.
128
+ # Fetch callback for event from hooks and call it.
129
+ #
130
+ # @raise [KeyError] if hook is not registered for event
131
+ #
132
+ # @param [String] event A String describing a Messenger event.
133
+ # @param [Object] args Arguments to pass to the hook.
134
+ def trigger(event, *args)
135
+ hooks.fetch(event).call(*args)
136
+ rescue KeyError
137
+ warn "Ignoring #{event} (no hook registered)"
138
+ end
139
+
140
+ #
141
+ # Return a Hash of hooks.
142
+ #
143
+ # @return [Hash] Hash of hooks.
144
+ #
145
+ def hooks
146
+ @hooks ||= {}
147
+ end
148
+
149
+ #
150
+ # Deregister all hooks.
151
+ #
152
+ # @return [Hash] Assign empty hash to hooks and return it.
153
+ #
154
+ def unhook
155
+ @hooks = {}
156
+ end
157
+
158
+ #
159
+ # Default HTTParty options.
160
+ #
161
+ # @return [Hash] Default HTTParty options.
162
+ #
163
+ def default_options
164
+ super.merge(
165
+ read_timeout: 300,
166
+ headers: {
167
+ 'Content-Type' => 'application/json'
168
+ }
169
+ )
170
+ end
171
+
172
+ private
173
+
174
+ def config
175
+ Facebook::Messenger.config
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,16 @@
1
+ module Facebook
2
+ module Messenger
3
+ class Configuration
4
+ # We provide a service to calculate an app_secret_proof
5
+ class AppSecretProofCalculator
6
+ def self.call(app_secret, access_token)
7
+ OpenSSL::HMAC.hexdigest(
8
+ OpenSSL::Digest.new('SHA256'.freeze),
9
+ app_secret,
10
+ access_token
11
+ )
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ require 'facebook/messenger/configuration/app_secret_proof_calculator'
2
+
3
+ module Facebook
4
+ module Messenger
5
+ class Configuration
6
+ module Providers
7
+ # This is the base configuration provider.
8
+ # User can overwrite this class to customize the environment variables
9
+ # Be sure to implement all the functions as it raises
10
+ # NotImplementedError errors.
11
+ class Base
12
+ # A default caching implentation of generating the app_secret_proof
13
+ # for a given page_id
14
+ def app_secret_proof_for(page_id = nil)
15
+ memo_key = [app_secret_for(page_id), access_token_for(page_id)]
16
+ memoized_app_secret_proofs[memo_key] ||=
17
+ calculate_app_secret_proof(*memo_key)
18
+ end
19
+
20
+ def valid_verify_token?(*)
21
+ raise NotImplementedError
22
+ end
23
+
24
+ def app_secret_for(*)
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def access_token_for(*)
29
+ raise NotImplementedError
30
+ end
31
+
32
+ private
33
+
34
+ def calculate_app_secret_proof(app_secret, access_token)
35
+ Facebook::Messenger::Configuration::AppSecretProofCalculator.call(
36
+ app_secret,
37
+ access_token
38
+ )
39
+ end
40
+
41
+ def memoized_app_secret_proofs
42
+ @memoized_app_secret_proofs ||= {}
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ require 'facebook/messenger/configuration/providers/base'
2
+
3
+ module Facebook
4
+ module Messenger
5
+ class Configuration
6
+ module Providers
7
+ # The default configuration provider for environment variables.
8
+ class Environment < Base
9
+ def valid_verify_token?(verify_token)
10
+ verify_token == ENV['VERIFY_TOKEN']
11
+ end
12
+
13
+ # Return String of app secret of Facebook App.
14
+ # Make sure you are returning the app secret if you overwrite
15
+ # configuration provider class as this app secret is used to
16
+ # validate the incoming requests.
17
+ def app_secret_for(*)
18
+ ENV['APP_SECRET']
19
+ end
20
+
21
+ # Return String of page access token.
22
+ def access_token_for(*)
23
+ ENV['ACCESS_TOKEN']
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ require 'facebook/messenger/configuration/providers/environment'
2
+ require 'facebook/messenger/configuration/providers/base'
3
+
4
+ module Facebook
5
+ module Messenger
6
+ class Configuration
7
+ # The Providers module contains configuration providers that ship with the
8
+ # gem.
9
+ module Providers
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ require 'facebook/messenger/configuration/providers'
2
+
3
+ module Facebook
4
+ module Messenger
5
+ #
6
+ # Class Configuration holds the configuration for bot.
7
+ #
8
+ class Configuration
9
+ attr_accessor :provider
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,44 @@
1
+ module Facebook
2
+ module Messenger
3
+ # Base Facebook Messenger exception.
4
+ class Error < StandardError; end
5
+
6
+ # Base error class for Facebook API errors.
7
+ class FacebookError < Error
8
+ attr_reader :message
9
+ attr_reader :type
10
+ attr_reader :code
11
+ attr_reader :subcode
12
+ attr_reader :user_title
13
+ attr_reader :user_msg
14
+ attr_reader :fbtrace_id
15
+
16
+ #
17
+ # Constructor function.
18
+ #
19
+ # @param [Hash] error Hash containing information about error.
20
+ #
21
+ def initialize(error)
22
+ @message = error['message']
23
+ @type = error['type']
24
+ @code = error['code']
25
+ @subcode = error['error_subcode']
26
+ @user_title = error['error_user_title']
27
+ @user_msg = error['error_user_msg']
28
+ @fbtrace_id = error['fbtrace_id']
29
+ end
30
+
31
+ #
32
+ # Function to convert the error into string.
33
+ #
34
+ # @example
35
+ # Error_Object.to_s #=> "Invalid OAuth access token. (subcode: 1234567)"
36
+ #
37
+ # @return [String] String describing the error message
38
+ #
39
+ def to_s
40
+ "#{@message} (subcode: #{subcode})"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,28 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Incoming
4
+ #
5
+ # The AccountLinking class represents an incoming Facebook Messenger
6
+ # Account Linking webhook, when the Linked Account
7
+ # or Unlink Account call-to-action have been tapped
8
+ #
9
+ # https://developers.facebook.com/docs/messenger-platform/webhook-reference/account-linking
10
+ #
11
+ class AccountLinking
12
+ include Facebook::Messenger::Incoming::Common
13
+
14
+ # Return String defining whether account in linked or not.
15
+ #
16
+ # @return [String] linked/unlinked.
17
+ def status
18
+ @messaging['account_linking']['status']
19
+ end
20
+
21
+ # The authorization code allows to match business user entity to PSID.
22
+ def authorization_code
23
+ @messaging['account_linking']['authorization_code']
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,131 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Incoming
4
+ #
5
+ # Common attributes for all incoming data from Facebook.
6
+ #
7
+ module Common
8
+ attr_reader :messaging
9
+
10
+ #
11
+ # Assign message to instance variable
12
+ #
13
+ # @param [Object] messaging Object of message.
14
+ #
15
+ def initialize(messaging)
16
+ @messaging = messaging
17
+ end
18
+
19
+ #
20
+ # Function return PSID of sender.
21
+ #
22
+ # @see https://developers.facebook.com/docs/messenger-platform/identity
23
+ # Info about PSID.
24
+ # @see https://developers.facebook.com/docs/messenger-platform/webhook#format
25
+ # Webhook event format.
26
+ #
27
+ # @return [String] PSID of sender.
28
+ #
29
+ def sender
30
+ @messaging['sender']
31
+ end
32
+
33
+ #
34
+ # Function return id of the page from which the message has arrived.
35
+ #
36
+ # @return [String] Facebook page id.
37
+ #
38
+ def recipient
39
+ @messaging['recipient']
40
+ end
41
+
42
+ #
43
+ # If the user responds to your message, the appropriate event
44
+ # (messages, messaging_postbacks, etc.) will be sent to your webhook,
45
+ # with a prior_message object appended. The prior_message object
46
+ # includes the source of the message the user is responding to, as well
47
+ # as the user_ref used for the original message send.
48
+ #
49
+ # @return [Hash] The 'prior_message' hash.
50
+ #
51
+ def prior_message
52
+ @messaging['prior_message']
53
+ end
54
+
55
+ #
56
+ # Function return timestamp when message is sent.
57
+ #
58
+ # @return [Object] Message time sent.
59
+ #
60
+ def sent_at
61
+ Time.at(@messaging['timestamp'] / 1000)
62
+ end
63
+
64
+ #
65
+ # Function send sender_action of 'typing_on' to sender.
66
+ # @see https://developers.facebook.com/docs/messenger-platform/send-messages/sender-actions
67
+ # Info about sender actions.
68
+ #
69
+ # @return Send message to sender.
70
+ #
71
+ def typing_on
72
+ payload = {
73
+ recipient: sender,
74
+ sender_action: 'typing_on'
75
+ }
76
+
77
+ Facebook::Messenger::Bot.deliver(payload, page_id: recipient['id'])
78
+ end
79
+
80
+ #
81
+ # Function send sender_action of 'typing_off' to sender.
82
+ # @see https://developers.facebook.com/docs/messenger-platform/send-messages/sender-actions
83
+ # Info about sender actions.
84
+ #
85
+ # @return Send message to sender.
86
+ #
87
+ def typing_off
88
+ payload = {
89
+ recipient: sender,
90
+ sender_action: 'typing_off'
91
+ }
92
+
93
+ Facebook::Messenger::Bot.deliver(payload, page_id: recipient['id'])
94
+ end
95
+
96
+ #
97
+ # Function send sender_action of 'mark_seen' to sender.
98
+ # @see https://developers.facebook.com/docs/messenger-platform/send-messages/sender-actions
99
+ # Info about sender actions.
100
+ #
101
+ # @return Send message to sender.
102
+ #
103
+ def mark_seen
104
+ payload = {
105
+ recipient: sender,
106
+ sender_action: 'mark_seen'
107
+ }
108
+
109
+ Facebook::Messenger::Bot.deliver(payload, page_id: recipient['id'])
110
+ end
111
+
112
+ #
113
+ # Send reply to sender.
114
+ #
115
+ # @param [Hash] message Hash defining the message.
116
+ #
117
+ # @return Send reply to sender.
118
+ #
119
+ def reply(message)
120
+ payload = {
121
+ recipient: sender,
122
+ message: message,
123
+ message_type: Facebook::Messenger::Bot::MessageType::RESPONSE
124
+ }
125
+
126
+ Facebook::Messenger::Bot.deliver(payload, page_id: recipient['id'])
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end