facebook-messenger 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4cc6286ba13cf8c0c5239c5c50645cfce5af44c6
4
- data.tar.gz: 1c8ab52a23996258d2f4db0254424727471c8c3e
3
+ metadata.gz: 55e300c4f11036d518035144eaf94581e5e99ce5
4
+ data.tar.gz: ca59746d98d4fab7f37284468fe57c6cf6414106
5
5
  SHA512:
6
- metadata.gz: 0ecf386733c99eea428f1704d569703a8f2959412e4bde1139a0d64c5e4dc94d31d34ad9daeb95bd00dfd82de0af35128d7a9a011ffb9c41cc527dfa9c47b569
7
- data.tar.gz: 09382794eb526905b5aa4d809156f05ac5dad9794ab920977dc1cb6ff98b47f954a4e0a350cdb86a1555731943ce195cad2fbd543dded414708a904aa1ee36fc
6
+ metadata.gz: 3b3e31067f8f111b86d712d68566b8f6de895ccd016a71d47b8ccc9b6a886cd99a1e84db20ec2860f006903b63cef874656a0cfc383cc0b7d6f728b32df9022c
7
+ data.tar.gz: 3dc23071c67f9060f27125646afb8236c5cac30b101311ac880242611b141a80ff31012642ff04e89a93a6d100e8d7498713a565dedb91d39748810ea579564e
@@ -52,6 +52,7 @@ module Facebook
52
52
  when Incoming::Delivery then trigger(:delivery, callback)
53
53
  when Incoming::Postback then trigger(:postback, callback)
54
54
  when Incoming::Optin then trigger(:optin, callback)
55
+ when Incoming::Read then trigger(:read, callback)
55
56
  end
56
57
  end
57
58
 
@@ -2,6 +2,7 @@ require 'facebook/messenger/incoming/message'
2
2
  require 'facebook/messenger/incoming/delivery'
3
3
  require 'facebook/messenger/incoming/postback'
4
4
  require 'facebook/messenger/incoming/optin'
5
+ require 'facebook/messenger/incoming/read'
5
6
 
6
7
  module Facebook
7
8
  module Messenger
@@ -12,7 +13,8 @@ module Facebook
12
13
  'message' => Message,
13
14
  'delivery' => Delivery,
14
15
  'postback' => Postback,
15
- 'optin' => Optin
16
+ 'optin' => Optin,
17
+ 'read' => Read
16
18
  }.freeze
17
19
 
18
20
  # Parse the given payload.
@@ -0,0 +1,30 @@
1
+ module Facebook
2
+ module Messenger
3
+ module Incoming
4
+ # The Read class represents the user reading a delivered message.
5
+ class Read
6
+ attr_reader :messaging
7
+
8
+ def initialize(messaging)
9
+ @messaging = messaging
10
+ end
11
+
12
+ def at
13
+ Time.at(@messaging['read']['watermark'] / 1000)
14
+ end
15
+
16
+ def seq
17
+ @messaging['read']['seq']
18
+ end
19
+
20
+ def sender
21
+ @messaging['sender']
22
+ end
23
+
24
+ def recipient
25
+ @messaging['recipient']
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -4,6 +4,8 @@ require 'openssl'
4
4
 
5
5
  module Facebook
6
6
  module Messenger
7
+ class BadRequestError < Error; end
8
+
7
9
  # This module holds the server that processes incoming messages from the
8
10
  # Facebook Messenger Platform.
9
11
  class Server
@@ -15,9 +17,12 @@ module Facebook
15
17
  @request = Rack::Request.new(env)
16
18
  @response = Rack::Response.new
17
19
 
18
- if @request.get? then verify
19
- elsif @request.post? then receive
20
- else @response.status = 405
20
+ if @request.get?
21
+ verify
22
+ elsif @request.post?
23
+ receive
24
+ else
25
+ @response.status = 405
21
26
  end
22
27
 
23
28
  @response.finish
@@ -38,46 +43,74 @@ module Facebook
38
43
  end
39
44
 
40
45
  def receive
41
- return if app_secret && !integrity?
46
+ body = @request.body.read
42
47
 
43
- hash = JSON.parse(@request.body.read)
48
+ check_integrity(body) if app_secret
44
49
 
45
- # Facebook may batch several items in the 'entry' array during
46
- # periods of high load.
47
- hash['entry'].each do |entry|
48
- # Facebook may batch several items in the 'messaging' array during
49
- # periods of high load.
50
- entry['messaging'].each do |messaging|
51
- Facebook::Messenger::Bot.receive(messaging)
52
- end
53
- end
50
+ events = parse_events(body)
51
+
52
+ trigger_events(events)
53
+ rescue BadRequestError => error
54
+ respond_with_error(error)
54
55
  end
55
56
 
56
- def integrity?
57
- Rack::Utils.secure_compare(x_hub_signature, signature)
57
+ WARNING = 'The X-Hub-Signature header is not present in the request. ' \
58
+ 'This is expected for the first webhook requests. If this ' \
59
+ 'continues after some time, check your app\'s secret token.'.freeze
60
+
61
+ def check_integrity(body)
62
+ x_hub_signature = @request.env['HTTP_X_HUB_SIGNATURE'.freeze].to_s
63
+
64
+ unless x_hub_signature.start_with?('sha1='.freeze)
65
+ $stderr.puts(WARNING)
66
+
67
+ raise BadRequestError, 'Error getting integrity signature'.freeze
68
+ end
69
+
70
+ unless secure_compare(x_hub_signature, signature(body))
71
+ raise BadRequestError, 'Error checking message integrity'.freeze
72
+ end
58
73
  end
59
74
 
60
- def x_hub_signature
61
- @request.env['HTTP_X_HUB_SIGNATURE'.freeze]
75
+ def secure_compare(x, y)
76
+ Rack::Utils.secure_compare(x, y)
62
77
  end
63
78
 
64
- def signature
65
- format('sha1=%s'.freeze, generate_hmac(@request.body.read))
66
- ensure
67
- @request.body.rewind
79
+ def signature(body)
80
+ format('sha1=%s'.freeze, generate_hmac(body))
68
81
  end
69
82
 
70
83
  def generate_hmac(content)
71
- OpenSSL::HMAC.hexdigest(
72
- OpenSSL::Digest.new('sha1'),
73
- app_secret,
74
- content
75
- )
84
+ OpenSSL::HMAC.hexdigest('sha1'.freeze, app_secret, content)
76
85
  end
77
86
 
78
87
  def app_secret
79
88
  Facebook::Messenger.config.app_secret
80
89
  end
90
+
91
+ def parse_events(body)
92
+ JSON.parse(body)
93
+ rescue JSON::ParserError
94
+ raise BadRequestError, 'Error parsing request body format'
95
+ end
96
+
97
+ def trigger_events(events)
98
+ # Facebook may batch several items in the 'entry' array during
99
+ # periods of high load.
100
+ events['entry'.freeze].each do |entry|
101
+ # Facebook may batch several items in the 'messaging' array during
102
+ # periods of high load.
103
+ entry['messaging'.freeze].each do |messaging|
104
+ Facebook::Messenger::Bot.receive(messaging)
105
+ end
106
+ end
107
+ end
108
+
109
+ def respond_with_error(error)
110
+ @response.status = 400
111
+ @response.write(error.message)
112
+ @response.headers['Content-Type'.freeze] = 'text/plain'.freeze
113
+ end
81
114
  end
82
115
  end
83
116
  end
@@ -1,5 +1,5 @@
1
1
  module Facebook
2
2
  module Messenger
3
- VERSION = '0.5.0'.freeze
3
+ VERSION = '0.6.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: facebook-messenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johannes Gorset
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-26 00:00:00.000000000 Z
11
+ date: 2016-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -169,6 +169,7 @@ files:
169
169
  - lib/facebook/messenger/incoming/message.rb
170
170
  - lib/facebook/messenger/incoming/optin.rb
171
171
  - lib/facebook/messenger/incoming/postback.rb
172
+ - lib/facebook/messenger/incoming/read.rb
172
173
  - lib/facebook/messenger/server.rb
173
174
  - lib/facebook/messenger/subscriptions.rb
174
175
  - lib/facebook/messenger/version.rb