facebook-messenger 1.0.0 → 1.1.0
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 +4 -4
- data/README.md +151 -10
- data/lib/facebook/messenger.rb +3 -0
- data/lib/facebook/messenger/bot.rb +43 -10
- 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/configuration.rb +3 -1
- data/lib/facebook/messenger/configuration/providers/base.rb +4 -2
- data/lib/facebook/messenger/configuration/providers/environment.rb +6 -1
- data/lib/facebook/messenger/error.rb +14 -1
- data/lib/facebook/messenger/incoming.rb +31 -6
- data/lib/facebook/messenger/incoming/account_linking.rb +6 -0
- data/lib/facebook/messenger/incoming/common.rb +75 -1
- data/lib/facebook/messenger/incoming/delivery.rb +1 -0
- data/lib/facebook/messenger/incoming/message.rb +86 -1
- data/lib/facebook/messenger/incoming/message_echo.rb +2 -2
- data/lib/facebook/messenger/incoming/message_request.rb +13 -0
- data/lib/facebook/messenger/incoming/optin.rb +18 -1
- 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 +5 -1
- data/lib/facebook/messenger/incoming/read.rb +3 -0
- data/lib/facebook/messenger/incoming/referral.rb +5 -2
- data/lib/facebook/messenger/profile.rb +43 -3
- data/lib/facebook/messenger/server.rb +40 -4
- data/lib/facebook/messenger/server_no_error.rb +36 -0
- data/lib/facebook/messenger/subscriptions.rb +42 -2
- data/lib/facebook/messenger/version.rb +3 -1
- metadata +12 -5
@@ -2,8 +2,10 @@ module Facebook
|
|
2
2
|
module Messenger
|
3
3
|
class Configuration
|
4
4
|
module Providers
|
5
|
-
# This is the base configuration provider.
|
6
|
-
#
|
5
|
+
# This is the base configuration provider.
|
6
|
+
# User can overwrite this class to customize the environment variables
|
7
|
+
# Be sure to implement all the functions as it raises
|
8
|
+
# NotImplementedError errors.
|
7
9
|
class Base
|
8
10
|
def valid_verify_token?(*)
|
9
11
|
raise NotImplementedError
|
@@ -2,16 +2,21 @@ module Facebook
|
|
2
2
|
module Messenger
|
3
3
|
class Configuration
|
4
4
|
module Providers
|
5
|
-
#
|
5
|
+
# The default configuration provider for environment variables.
|
6
6
|
class Environment
|
7
7
|
def valid_verify_token?(verify_token)
|
8
8
|
verify_token == ENV['VERIFY_TOKEN']
|
9
9
|
end
|
10
10
|
|
11
|
+
# Return String of app secret of Facebook App.
|
12
|
+
# Make sure you are returning the app secret if you overwrite
|
13
|
+
# configuration provider class as this app secret is used to
|
14
|
+
# validate the incoming requests.
|
11
15
|
def app_secret_for(*)
|
12
16
|
ENV['APP_SECRET']
|
13
17
|
end
|
14
18
|
|
19
|
+
# Return String of page access token.
|
15
20
|
def access_token_for(*)
|
16
21
|
ENV['ACCESS_TOKEN']
|
17
22
|
end
|
@@ -13,6 +13,11 @@ module Facebook
|
|
13
13
|
attr_reader :user_msg
|
14
14
|
attr_reader :fbtrace_id
|
15
15
|
|
16
|
+
#
|
17
|
+
# Constructor function.
|
18
|
+
#
|
19
|
+
# @param [Hash] error Hash containing information about error.
|
20
|
+
#
|
16
21
|
def initialize(error)
|
17
22
|
@message = error['message']
|
18
23
|
@type = error['type']
|
@@ -23,8 +28,16 @@ module Facebook
|
|
23
28
|
@fbtrace_id = error['fbtrace_id']
|
24
29
|
end
|
25
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
|
+
#
|
26
39
|
def to_s
|
27
|
-
@message
|
40
|
+
"#{@message} (subcode: #{subcode})"
|
28
41
|
end
|
29
42
|
end
|
30
43
|
end
|
@@ -1,18 +1,25 @@
|
|
1
1
|
require 'facebook/messenger/incoming/common'
|
2
2
|
require 'facebook/messenger/incoming/message'
|
3
3
|
require 'facebook/messenger/incoming/message_echo'
|
4
|
+
require 'facebook/messenger/incoming/message_request'
|
4
5
|
require 'facebook/messenger/incoming/delivery'
|
5
6
|
require 'facebook/messenger/incoming/postback'
|
6
7
|
require 'facebook/messenger/incoming/optin'
|
7
8
|
require 'facebook/messenger/incoming/read'
|
8
9
|
require 'facebook/messenger/incoming/account_linking'
|
9
10
|
require 'facebook/messenger/incoming/referral'
|
11
|
+
require 'facebook/messenger/incoming/payment'
|
12
|
+
require 'facebook/messenger/incoming/policy_enforcement'
|
10
13
|
|
11
14
|
module Facebook
|
12
15
|
module Messenger
|
13
|
-
#
|
14
|
-
#
|
16
|
+
#
|
17
|
+
# Module Incoming parses and abstracts incoming requests from Messenger.
|
18
|
+
#
|
15
19
|
module Incoming
|
20
|
+
#
|
21
|
+
# @return [Hash] Hash containing facebook messenger events and its event
|
22
|
+
# handler classes.
|
16
23
|
EVENTS = {
|
17
24
|
'message' => Message,
|
18
25
|
'delivery' => Delivery,
|
@@ -21,14 +28,22 @@ module Facebook
|
|
21
28
|
'read' => Read,
|
22
29
|
'account_linking' => AccountLinking,
|
23
30
|
'referral' => Referral,
|
24
|
-
'message_echo' => MessageEcho
|
31
|
+
'message_echo' => MessageEcho,
|
32
|
+
'message_request' => MessageRequest,
|
33
|
+
'payment' => Payment,
|
34
|
+
'policy_enforcement' => PolicyEnforcement
|
25
35
|
}.freeze
|
26
36
|
|
27
|
-
# Parse the given payload
|
37
|
+
# Parse the given payload and create new object of class related
|
38
|
+
# to event in payload.
|
39
|
+
#
|
40
|
+
# @see https://developers.facebook.com/docs/messenger-platform/webhook-reference
|
41
|
+
#
|
42
|
+
# @raise [Facebook::Messenger::Incoming::UnknownPayload] if event is not
|
43
|
+
# registered in EVENTS constant
|
28
44
|
#
|
29
|
-
# payload
|
45
|
+
# @param [Hash] payload A Hash describing a payload from Facebook.
|
30
46
|
#
|
31
|
-
# * https://developers.facebook.com/docs/messenger-platform/webhook-reference
|
32
47
|
def self.parse(payload)
|
33
48
|
return MessageEcho.new(payload) if payload_is_echo?(payload)
|
34
49
|
|
@@ -39,10 +54,20 @@ module Facebook
|
|
39
54
|
raise UnknownPayload, payload
|
40
55
|
end
|
41
56
|
|
57
|
+
#
|
58
|
+
# Check if event is echo.
|
59
|
+
#
|
60
|
+
# @param [Hash] payload Request payload from facebook.
|
61
|
+
#
|
62
|
+
# @return [Boolean] If event is echo return true else false.
|
63
|
+
#
|
42
64
|
def self.payload_is_echo?(payload)
|
43
65
|
payload.key?('message') && payload['message']['is_echo'] == true
|
44
66
|
end
|
45
67
|
|
68
|
+
#
|
69
|
+
# Class UnknownPayload provides errors related to incoming messages.
|
70
|
+
#
|
46
71
|
class UnknownPayload < Facebook::Messenger::Error; end
|
47
72
|
end
|
48
73
|
end
|
@@ -1,18 +1,24 @@
|
|
1
1
|
module Facebook
|
2
2
|
module Messenger
|
3
3
|
module Incoming
|
4
|
+
#
|
4
5
|
# The AccountLinking class represents an incoming Facebook Messenger
|
5
6
|
# Account Linking webhook, when the Linked Account
|
6
7
|
# or Unlink Account call-to-action have been tapped
|
7
8
|
#
|
8
9
|
# https://developers.facebook.com/docs/messenger-platform/webhook-reference/account-linking
|
10
|
+
#
|
9
11
|
class AccountLinking
|
10
12
|
include Facebook::Messenger::Incoming::Common
|
11
13
|
|
14
|
+
# Return String defining whether account in linked or not.
|
15
|
+
#
|
16
|
+
# @return [String] linked/unlinked.
|
12
17
|
def status
|
13
18
|
@messaging['account_linking']['status']
|
14
19
|
end
|
15
20
|
|
21
|
+
# The authorization code allows to match business user entity to PSID.
|
16
22
|
def authorization_code
|
17
23
|
@messaging['account_linking']['authorization_code']
|
18
24
|
end
|
@@ -1,26 +1,73 @@
|
|
1
1
|
module Facebook
|
2
2
|
module Messenger
|
3
3
|
module Incoming
|
4
|
+
#
|
4
5
|
# Common attributes for all incoming data from Facebook.
|
6
|
+
#
|
5
7
|
module Common
|
6
8
|
attr_reader :messaging
|
7
9
|
|
10
|
+
#
|
11
|
+
# Assign message to instance variable
|
12
|
+
#
|
13
|
+
# @param [Object] messaging Object of message.
|
14
|
+
#
|
8
15
|
def initialize(messaging)
|
9
16
|
@messaging = messaging
|
10
17
|
end
|
11
18
|
|
19
|
+
#
|
20
|
+
# Function return PSID of sender.
|
21
|
+
# @see https://developers.facebook.com/docs/messenger-platform/identity
|
22
|
+
# Info about PSID.
|
23
|
+
# @see https://developers.facebook.com/docs/messenger-platform/webhook#format
|
24
|
+
# Webhook event format.
|
25
|
+
#
|
26
|
+
# @return [String] PSID of sender.
|
27
|
+
#
|
12
28
|
def sender
|
13
29
|
@messaging['sender']
|
14
30
|
end
|
15
31
|
|
32
|
+
#
|
33
|
+
# Function return the page of id from which the message is arrived.
|
34
|
+
#
|
35
|
+
# @return [String] Facebook page id.
|
36
|
+
#
|
16
37
|
def recipient
|
17
38
|
@messaging['recipient']
|
18
39
|
end
|
19
40
|
|
41
|
+
#
|
42
|
+
# If the user responds to your message, the appropriate event
|
43
|
+
# (messages, messaging_postbacks, etc.) will be sent to your webhook,
|
44
|
+
# with a prior_message object appended. The prior_message object
|
45
|
+
# includes the source of the message the user is responding to, as well
|
46
|
+
# as the user_ref used for the original message send.
|
47
|
+
#
|
48
|
+
# @return [Hash] The 'prior_message' hash.
|
49
|
+
#
|
50
|
+
def prior_message
|
51
|
+
@messaging['prior_message']
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Function return timestamp when message is sent.
|
56
|
+
#
|
57
|
+
#
|
58
|
+
# @return [Object] Message time sent.
|
59
|
+
#
|
20
60
|
def sent_at
|
21
61
|
Time.at(@messaging['timestamp'] / 1000)
|
22
62
|
end
|
23
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
|
+
#
|
24
71
|
def typing_on
|
25
72
|
payload = {
|
26
73
|
recipient: sender,
|
@@ -30,6 +77,13 @@ module Facebook
|
|
30
77
|
Facebook::Messenger::Bot.deliver(payload, access_token: access_token)
|
31
78
|
end
|
32
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
|
+
#
|
33
87
|
def typing_off
|
34
88
|
payload = {
|
35
89
|
recipient: sender,
|
@@ -39,6 +93,13 @@ module Facebook
|
|
39
93
|
Facebook::Messenger::Bot.deliver(payload, access_token: access_token)
|
40
94
|
end
|
41
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
|
+
#
|
42
103
|
def mark_seen
|
43
104
|
payload = {
|
44
105
|
recipient: sender,
|
@@ -48,15 +109,28 @@ module Facebook
|
|
48
109
|
Facebook::Messenger::Bot.deliver(payload, access_token: access_token)
|
49
110
|
end
|
50
111
|
|
112
|
+
#
|
113
|
+
# Send reply to sender.
|
114
|
+
#
|
115
|
+
# @param [Hash] message Hash defining the message.
|
116
|
+
#
|
117
|
+
# @return Send reply to sender.
|
118
|
+
#
|
51
119
|
def reply(message)
|
52
120
|
payload = {
|
53
121
|
recipient: sender,
|
54
|
-
message: message
|
122
|
+
message: message,
|
123
|
+
message_type: Facebook::Messenger::Bot::MessageType::RESPONSE
|
55
124
|
}
|
56
125
|
|
57
126
|
Facebook::Messenger::Bot.deliver(payload, access_token: access_token)
|
58
127
|
end
|
59
128
|
|
129
|
+
#
|
130
|
+
# Function returns the configured access token.
|
131
|
+
#
|
132
|
+
# @return [String] Access token.
|
133
|
+
#
|
60
134
|
def access_token
|
61
135
|
Facebook::Messenger.config.provider.access_token_for(recipient)
|
62
136
|
end
|
@@ -2,6 +2,7 @@ module Facebook
|
|
2
2
|
module Messenger
|
3
3
|
module Incoming
|
4
4
|
# The Delivery class represents the receipt of a delivered message.
|
5
|
+
# @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/message-deliveries
|
5
6
|
class Delivery
|
6
7
|
include Facebook::Messenger::Incoming::Common
|
7
8
|
|
@@ -1,12 +1,24 @@
|
|
1
1
|
module Facebook
|
2
2
|
module Messenger
|
3
3
|
module Incoming
|
4
|
-
#
|
4
|
+
#
|
5
|
+
# Message class represents an incoming Facebook Messenger message event.
|
6
|
+
# @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messages
|
7
|
+
#
|
5
8
|
class Message
|
6
9
|
include Facebook::Messenger::Incoming::Common
|
7
10
|
|
11
|
+
#
|
12
|
+
# @return [Array] Supported attachments for message.
|
8
13
|
ATTACHMENT_TYPES = %w[image audio video file location fallback].freeze
|
9
14
|
|
15
|
+
#
|
16
|
+
# Function returns unique id of message
|
17
|
+
# @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messages
|
18
|
+
# Info about received message format.
|
19
|
+
#
|
20
|
+
# @return [String] Unique id of message.
|
21
|
+
#
|
10
22
|
def id
|
11
23
|
@messaging['message']['mid']
|
12
24
|
end
|
@@ -15,34 +27,85 @@ module Facebook
|
|
15
27
|
@messaging['message']['seq']
|
16
28
|
end
|
17
29
|
|
30
|
+
#
|
31
|
+
# Function returns text of message
|
32
|
+
#
|
33
|
+
# @return [String] Text of message.
|
34
|
+
#
|
18
35
|
def text
|
19
36
|
@messaging['message']['text']
|
20
37
|
end
|
21
38
|
|
39
|
+
#
|
40
|
+
# Whether message is echo or not?
|
41
|
+
#
|
42
|
+
# @return [Boolean] If message is echo return true else false.
|
43
|
+
#
|
22
44
|
def echo?
|
23
45
|
@messaging['message']['is_echo']
|
24
46
|
end
|
25
47
|
|
48
|
+
#
|
49
|
+
# Function returns array containing attachment data
|
50
|
+
# @see https://developers.facebook.com/docs/messenger-platform/send-messages#sending_attachments
|
51
|
+
# More info about attachments.
|
52
|
+
#
|
53
|
+
# @return [Array] Attachment data.
|
54
|
+
#
|
26
55
|
def attachments
|
27
56
|
@messaging['message']['attachments']
|
28
57
|
end
|
29
58
|
|
59
|
+
#
|
60
|
+
# If facebook messenger built-in NLP is enabled, message will
|
61
|
+
# contain 'nlp' key in response.
|
62
|
+
# @see https://developers.facebook.com/docs/messenger-platform/built-in-nlp
|
63
|
+
# More information about built-in NLP.
|
64
|
+
#
|
65
|
+
#
|
66
|
+
# @return [Hash] NLP information about message.
|
67
|
+
#
|
68
|
+
def nlp
|
69
|
+
@messaging['message']['nlp']
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Function return app id from message.
|
74
|
+
#
|
75
|
+
# @return [String] App ID.
|
76
|
+
#
|
30
77
|
def app_id
|
31
78
|
@messaging['message']['app_id']
|
32
79
|
end
|
33
80
|
|
81
|
+
#
|
82
|
+
# This meta programming defines function for
|
83
|
+
# every attachment type to check whether the attachment
|
84
|
+
# in message is of defined type or not.
|
85
|
+
#
|
34
86
|
ATTACHMENT_TYPES.each do |attachment_type|
|
35
87
|
define_method "#{attachment_type}_attachment?" do
|
36
88
|
attachment_type?(attachment_type)
|
37
89
|
end
|
38
90
|
end
|
39
91
|
|
92
|
+
#
|
93
|
+
# Get the type of attachment in message.
|
94
|
+
#
|
95
|
+
# @return [String] Attachment type.
|
96
|
+
#
|
40
97
|
def attachment_type
|
41
98
|
return if attachments.nil?
|
42
99
|
|
43
100
|
attachments.first['type']
|
44
101
|
end
|
45
102
|
|
103
|
+
#
|
104
|
+
# Get the URL of attachment in message.
|
105
|
+
# URL is only available for attachments of type image/audio/video/file.
|
106
|
+
#
|
107
|
+
# @return [String] URL of attachment.
|
108
|
+
#
|
46
109
|
def attachment_url
|
47
110
|
return if attachments.nil?
|
48
111
|
return unless %w[image audio video file].include? attachment_type
|
@@ -50,6 +113,12 @@ module Facebook
|
|
50
113
|
attachments.first['payload']['url']
|
51
114
|
end
|
52
115
|
|
116
|
+
#
|
117
|
+
# Get the location coordinates if attachment type is 'location'.
|
118
|
+
# @example [LATITUDE, LONGITUDE]
|
119
|
+
#
|
120
|
+
# @return [Array] Location coordinates.
|
121
|
+
#
|
53
122
|
def location_coordinates
|
54
123
|
return [] unless attachment_type?('location')
|
55
124
|
|
@@ -57,14 +126,30 @@ module Facebook
|
|
57
126
|
[coordinates_data['lat'], coordinates_data['long']]
|
58
127
|
end
|
59
128
|
|
129
|
+
#
|
130
|
+
# Get the payload of quick reply.
|
131
|
+
# @see https://developers.facebook.com/docs/messenger-platform/send-messages/quick-replies
|
132
|
+
# More info about quick reply.
|
133
|
+
#
|
134
|
+
# @return [String] Payload string.
|
135
|
+
#
|
60
136
|
def quick_reply
|
61
137
|
return unless @messaging['message']['quick_reply']
|
62
138
|
|
63
139
|
@messaging['message']['quick_reply']['payload']
|
64
140
|
end
|
65
141
|
|
142
|
+
# @private
|
66
143
|
private
|
67
144
|
|
145
|
+
#
|
146
|
+
# Check if attachment in message is of given type or not?
|
147
|
+
#
|
148
|
+
# @param [String] attachment_type Attachment type
|
149
|
+
#
|
150
|
+
# @return [Boolean] If type of attachment in message
|
151
|
+
# and provided attachment type are same then return true else false.
|
152
|
+
#
|
68
153
|
def attachment_type?(attachment_type)
|
69
154
|
!attachments.nil? && attachments.first['type'] == attachment_type
|
70
155
|
end
|