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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +151 -10
  3. data/lib/facebook/messenger.rb +3 -0
  4. data/lib/facebook/messenger/bot.rb +43 -10
  5. data/lib/facebook/messenger/bot/message_type.rb +13 -0
  6. data/lib/facebook/messenger/bot/messaging_type.rb +12 -0
  7. data/lib/facebook/messenger/bot/tag.rb +27 -0
  8. data/lib/facebook/messenger/configuration.rb +3 -1
  9. data/lib/facebook/messenger/configuration/providers/base.rb +4 -2
  10. data/lib/facebook/messenger/configuration/providers/environment.rb +6 -1
  11. data/lib/facebook/messenger/error.rb +14 -1
  12. data/lib/facebook/messenger/incoming.rb +31 -6
  13. data/lib/facebook/messenger/incoming/account_linking.rb +6 -0
  14. data/lib/facebook/messenger/incoming/common.rb +75 -1
  15. data/lib/facebook/messenger/incoming/delivery.rb +1 -0
  16. data/lib/facebook/messenger/incoming/message.rb +86 -1
  17. data/lib/facebook/messenger/incoming/message_echo.rb +2 -2
  18. data/lib/facebook/messenger/incoming/message_request.rb +13 -0
  19. data/lib/facebook/messenger/incoming/optin.rb +18 -1
  20. data/lib/facebook/messenger/incoming/payment.rb +49 -0
  21. data/lib/facebook/messenger/incoming/policy_enforcement.rb +21 -0
  22. data/lib/facebook/messenger/incoming/postback.rb +5 -1
  23. data/lib/facebook/messenger/incoming/read.rb +3 -0
  24. data/lib/facebook/messenger/incoming/referral.rb +5 -2
  25. data/lib/facebook/messenger/profile.rb +43 -3
  26. data/lib/facebook/messenger/server.rb +40 -4
  27. data/lib/facebook/messenger/server_no_error.rb +36 -0
  28. data/lib/facebook/messenger/subscriptions.rb +42 -2
  29. data/lib/facebook/messenger/version.rb +3 -1
  30. 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. It raises errors so that you
6
- # get nice ones.
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
- # Configuration provider for environment variables.
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
- # The Incoming module parses and abstracts incoming requests from
14
- # Facebook Messenger.
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 - A Hash describing a payload from Facebook.
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
- # The Message class represents an incoming Facebook Messenger message.
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