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.
- checksums.yaml +7 -0
- data/README.md +681 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/facebook/messenger/bot/error_parser.rb +111 -0
- data/lib/facebook/messenger/bot/exceptions.rb +15 -0
- data/lib/facebook/messenger/bot/message_type.rb +13 -0
- data/lib/facebook/messenger/bot/messaging_type.rb +12 -0
- data/lib/facebook/messenger/bot/tag.rb +27 -0
- data/lib/facebook/messenger/bot.rb +180 -0
- data/lib/facebook/messenger/configuration/app_secret_proof_calculator.rb +16 -0
- data/lib/facebook/messenger/configuration/providers/base.rb +48 -0
- data/lib/facebook/messenger/configuration/providers/environment.rb +29 -0
- data/lib/facebook/messenger/configuration/providers.rb +13 -0
- data/lib/facebook/messenger/configuration.rb +12 -0
- data/lib/facebook/messenger/error.rb +44 -0
- data/lib/facebook/messenger/incoming/account_linking.rb +28 -0
- data/lib/facebook/messenger/incoming/common.rb +131 -0
- data/lib/facebook/messenger/incoming/delivery.rb +23 -0
- data/lib/facebook/messenger/incoming/feed.rb +16 -0
- data/lib/facebook/messenger/incoming/feed_common.rb +17 -0
- data/lib/facebook/messenger/incoming/game_play.rb +39 -0
- data/lib/facebook/messenger/incoming/leadgen.rb +13 -0
- data/lib/facebook/messenger/incoming/message.rb +159 -0
- data/lib/facebook/messenger/incoming/message_echo.rb +10 -0
- data/lib/facebook/messenger/incoming/message_reaction.rb +23 -0
- data/lib/facebook/messenger/incoming/message_request.rb +13 -0
- data/lib/facebook/messenger/incoming/optin.rb +34 -0
- data/lib/facebook/messenger/incoming/pass_thread_control.rb +22 -0
- data/lib/facebook/messenger/incoming/payment.rb +49 -0
- data/lib/facebook/messenger/incoming/policy_enforcement.rb +21 -0
- data/lib/facebook/messenger/incoming/postback.rb +26 -0
- data/lib/facebook/messenger/incoming/read.rb +21 -0
- data/lib/facebook/messenger/incoming/referral.rb +47 -0
- data/lib/facebook/messenger/incoming.rb +85 -0
- data/lib/facebook/messenger/profile.rb +92 -0
- data/lib/facebook/messenger/server.rb +195 -0
- data/lib/facebook/messenger/server_no_error.rb +36 -0
- data/lib/facebook/messenger/subscriptions.rb +85 -0
- data/lib/facebook/messenger/version.rb +7 -0
- data/lib/facebook/messenger.rb +32 -0
- 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,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,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
|