facebook-messenger 0.4.2 → 0.5.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 +24 -9
- data/lib/facebook/messenger.rb +6 -2
- data/lib/facebook/messenger/bot.rb +6 -6
- data/lib/facebook/messenger/configuration.rb +4 -5
- data/lib/facebook/messenger/incoming/delivery.rb +9 -7
- data/lib/facebook/messenger/incoming/message.rb +13 -7
- data/lib/facebook/messenger/incoming/optin.rb +8 -6
- data/lib/facebook/messenger/incoming/postback.rb +8 -6
- data/lib/facebook/messenger/server.rb +35 -5
- data/lib/facebook/messenger/subscriptions.rb +17 -9
- data/lib/facebook/messenger/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cc6286ba13cf8c0c5239c5c50645cfce5af44c6
|
4
|
+
data.tar.gz: 1c8ab52a23996258d2f4db0254424727471c8c3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ecf386733c99eea428f1704d569703a8f2959412e4bde1139a0d64c5e4dc94d31d34ad9daeb95bd00dfd82de0af35128d7a9a011ffb9c41cc527dfa9c47b569
|
7
|
+
data.tar.gz: 09382794eb526905b5aa4d809156f05ac5dad9794ab920977dc1cb6ff98b47f954a4e0a350cdb86a1555731943ce195cad2fbd543dded414708a904aa1ee36fc
|
data/README.md
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
[](https://gemnasium.com/hyperoslo/facebook-messenger)
|
9
9
|
[](https://codeclimate.com/github/hyperoslo/facebook-messenger)
|
10
10
|
[](https://coveralls.io/r/hyperoslo/facebook-messenger)
|
11
|
+
[](https://gitter.im/hyperoslo/facebook-messenger?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
11
12
|
|
12
13
|
## Installation
|
13
14
|
|
@@ -26,11 +27,12 @@ require 'facebook/messenger'
|
|
26
27
|
include Facebook::Messenger
|
27
28
|
|
28
29
|
Bot.on :message do |message|
|
29
|
-
message.id
|
30
|
-
message.sender
|
31
|
-
message.seq
|
32
|
-
message.sent_at
|
33
|
-
message.text
|
30
|
+
message.id # => 'mid.1457764197618:41d102a3e1ae206a38'
|
31
|
+
message.sender # => { 'id' => '1008372609250235' }
|
32
|
+
message.seq # => 73
|
33
|
+
message.sent_at # => 2016-04-22 21:30:36 +0200
|
34
|
+
message.text # => 'Hello, bot!'
|
35
|
+
message.attachments # => [ { 'type' => 'image', 'payload' => { 'url' => 'https://www.example.com/1.jpg' } } ]
|
34
36
|
|
35
37
|
Bot.deliver(
|
36
38
|
recipient: message.sender,
|
@@ -129,9 +131,7 @@ Bot.on :optin do |optin|
|
|
129
131
|
optin.ref # => 'CONTACT_SKYNET'
|
130
132
|
|
131
133
|
Bot.deliver(
|
132
|
-
recipient:
|
133
|
-
id: '45123'
|
134
|
-
},
|
134
|
+
recipient: optin.sender,
|
135
135
|
message: {
|
136
136
|
text: 'Ah, human!'
|
137
137
|
}
|
@@ -169,13 +169,24 @@ token of your choosing.
|
|
169
169
|
|
170
170
|
Use the generated access token and your verify token to configure your bot:
|
171
171
|
|
172
|
+
##### ... pass a block, or
|
173
|
+
|
172
174
|
```ruby
|
173
175
|
Facebook::Messenger.configure do |config|
|
174
176
|
config.access_token = 'EAAG6WgW...'
|
177
|
+
config.app_secret = '__app_secret_here__'
|
175
178
|
config.verify_token = 'my_voice_is_my_password_verify_me'
|
176
179
|
end
|
177
180
|
```
|
178
181
|
|
182
|
+
##### ... set directly
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
Facebook::Messenger.config.access_token = 'EAAG6WgW...'
|
186
|
+
Facebook::Messenger.config.app_secret = '__app_secret_here__'
|
187
|
+
Facebook::Messenger.config.verify_token = 'my_voice_is_my_password_verify_me'
|
188
|
+
```
|
189
|
+
|
179
190
|
### Subscribe your Application to a Page
|
180
191
|
|
181
192
|
Once you've configured your bot, subscribe it to the Page to get messages
|
@@ -243,11 +254,14 @@ reference constants. You'll need to explicitly load `app/bot`, then:
|
|
243
254
|
|
244
255
|
```ruby
|
245
256
|
# config/initializers/bot.rb
|
246
|
-
|
257
|
+
unless Rails.env.production?
|
247
258
|
Dir["#{Rails.root}/app/bot/**/*.rb"].each { |file| require file }
|
248
259
|
end
|
249
260
|
```
|
250
261
|
|
262
|
+
To test your locally running bot, you can use [ngrok]. This will create a secure
|
263
|
+
tunnel to localhost so that Facebook can reach the webhook.
|
264
|
+
|
251
265
|
## Development
|
252
266
|
|
253
267
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run
|
@@ -280,3 +294,4 @@ If you're using Facebook Messenger, we probably want to [hire you].
|
|
280
294
|
[developers.facebook.com]: https://developers.facebook.com/
|
281
295
|
[rack]: https://github.com/rack/rack
|
282
296
|
[send-to-messenger-plugin]: https://developers.facebook.com/docs/messenger-platform/plugin-reference
|
297
|
+
[ngrok]: https://ngrok.com/
|
data/lib/facebook/messenger.rb
CHANGED
@@ -10,11 +10,15 @@ module Facebook
|
|
10
10
|
# All the code for this gem resides in this module.
|
11
11
|
module Messenger
|
12
12
|
def self.configure
|
13
|
-
yield
|
13
|
+
yield config
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.config
|
17
|
-
Configuration
|
17
|
+
@config ||= Configuration.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.config=(config)
|
21
|
+
@config = config
|
18
22
|
end
|
19
23
|
|
20
24
|
configure do |config|
|
@@ -45,13 +45,13 @@ module Facebook
|
|
45
45
|
#
|
46
46
|
# * https://developers.facebook.com/docs/messenger-platform/webhook-reference
|
47
47
|
def receive(payload)
|
48
|
-
|
48
|
+
callback = Facebook::Messenger::Incoming.parse(payload)
|
49
49
|
|
50
|
-
case
|
51
|
-
when Incoming::Message then trigger(:message,
|
52
|
-
when Incoming::Delivery then trigger(:delivery,
|
53
|
-
when Incoming::Postback then trigger(:postback,
|
54
|
-
when Incoming::Optin then trigger(:optin,
|
50
|
+
case callback
|
51
|
+
when Incoming::Message then trigger(:message, callback)
|
52
|
+
when Incoming::Delivery then trigger(:delivery, callback)
|
53
|
+
when Incoming::Postback then trigger(:postback, callback)
|
54
|
+
when Incoming::Optin then trigger(:optin, callback)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module Facebook
|
2
2
|
module Messenger
|
3
3
|
# This module holds the configuration.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :access_token
|
6
|
+
attr_accessor :app_secret
|
7
|
+
attr_accessor :verify_token
|
9
8
|
end
|
10
9
|
end
|
11
10
|
end
|
@@ -3,28 +3,30 @@ module Facebook
|
|
3
3
|
module Incoming
|
4
4
|
# The Delivery class represents the receipt of a delivered message.
|
5
5
|
class Delivery
|
6
|
-
|
7
|
-
|
6
|
+
attr_reader :messaging
|
7
|
+
|
8
|
+
def initialize(messaging)
|
9
|
+
@messaging = messaging
|
8
10
|
end
|
9
11
|
|
10
12
|
def ids
|
11
|
-
@
|
13
|
+
@messaging['delivery']['mids']
|
12
14
|
end
|
13
15
|
|
14
16
|
def at
|
15
|
-
Time.at(@
|
17
|
+
Time.at(@messaging['delivery']['watermark'] / 1000)
|
16
18
|
end
|
17
19
|
|
18
20
|
def seq
|
19
|
-
@
|
21
|
+
@messaging['delivery']['seq']
|
20
22
|
end
|
21
23
|
|
22
24
|
def sender
|
23
|
-
@
|
25
|
+
@messaging['sender']
|
24
26
|
end
|
25
27
|
|
26
28
|
def recipient
|
27
|
-
@
|
29
|
+
@messaging['recipient']
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
@@ -3,28 +3,34 @@ module Facebook
|
|
3
3
|
module Incoming
|
4
4
|
# The Message class represents an incoming Facebook Messenger message.
|
5
5
|
class Message
|
6
|
-
|
7
|
-
|
6
|
+
attr_reader :messaging
|
7
|
+
|
8
|
+
def initialize(messaging)
|
9
|
+
@messaging = messaging
|
8
10
|
end
|
9
11
|
|
10
12
|
def id
|
11
|
-
@
|
13
|
+
@messaging['message']['mid']
|
12
14
|
end
|
13
15
|
|
14
16
|
def sender
|
15
|
-
@
|
17
|
+
@messaging['sender']
|
16
18
|
end
|
17
19
|
|
18
20
|
def seq
|
19
|
-
@
|
21
|
+
@messaging['message']['seq']
|
20
22
|
end
|
21
23
|
|
22
24
|
def sent_at
|
23
|
-
Time.at(@
|
25
|
+
Time.at(@messaging['timestamp'] / 1000)
|
24
26
|
end
|
25
27
|
|
26
28
|
def text
|
27
|
-
@
|
29
|
+
@messaging['message']['text']
|
30
|
+
end
|
31
|
+
|
32
|
+
def attachments
|
33
|
+
@messaging['message']['attachments']
|
28
34
|
end
|
29
35
|
end
|
30
36
|
end
|
@@ -6,24 +6,26 @@ module Facebook
|
|
6
6
|
#
|
7
7
|
# https://developers.facebook.com/docs/messenger-platform/plugin-reference
|
8
8
|
class Optin
|
9
|
-
|
10
|
-
|
9
|
+
attr_reader :messaging
|
10
|
+
|
11
|
+
def initialize(messaging)
|
12
|
+
@messaging = messaging
|
11
13
|
end
|
12
14
|
|
13
15
|
def sender
|
14
|
-
@
|
16
|
+
@messaging['sender']
|
15
17
|
end
|
16
18
|
|
17
19
|
def recipient
|
18
|
-
@
|
20
|
+
@messaging['recipient']
|
19
21
|
end
|
20
22
|
|
21
23
|
def sent_at
|
22
|
-
Time.at(@
|
24
|
+
Time.at(@messaging['timestamp'] / 1000)
|
23
25
|
end
|
24
26
|
|
25
27
|
def ref
|
26
|
-
@
|
28
|
+
@messaging['optin']['ref']
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -3,24 +3,26 @@ module Facebook
|
|
3
3
|
module Incoming
|
4
4
|
# The Postback class represents an incoming Facebook Messenger postback.
|
5
5
|
class Postback
|
6
|
-
|
7
|
-
|
6
|
+
attr_reader :messaging
|
7
|
+
|
8
|
+
def initialize(messaging)
|
9
|
+
@messaging = messaging
|
8
10
|
end
|
9
11
|
|
10
12
|
def sender
|
11
|
-
@
|
13
|
+
@messaging['sender']
|
12
14
|
end
|
13
15
|
|
14
16
|
def recipient
|
15
|
-
@
|
17
|
+
@messaging['recipient']
|
16
18
|
end
|
17
19
|
|
18
20
|
def sent_at
|
19
|
-
Time.at(@
|
21
|
+
Time.at(@messaging['timestamp'] / 1000)
|
20
22
|
end
|
21
23
|
|
22
24
|
def payload
|
23
|
-
@
|
25
|
+
@messaging['postback']['payload']
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rack'
|
2
2
|
require 'json'
|
3
|
+
require 'openssl'
|
3
4
|
|
4
5
|
module Facebook
|
5
6
|
module Messenger
|
@@ -14,18 +15,19 @@ module Facebook
|
|
14
15
|
@request = Rack::Request.new(env)
|
15
16
|
@response = Rack::Response.new
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
when @request.post? then receive
|
18
|
+
if @request.get? then verify
|
19
|
+
elsif @request.post? then receive
|
20
20
|
else @response.status = 405
|
21
21
|
end
|
22
22
|
|
23
23
|
@response.finish
|
24
24
|
end
|
25
25
|
|
26
|
+
private
|
27
|
+
|
26
28
|
def verify
|
27
|
-
if @request['hub.verify_token'] == verify_token
|
28
|
-
@response.write @request['hub.challenge']
|
29
|
+
if @request.params['hub.verify_token'] == verify_token
|
30
|
+
@response.write @request.params['hub.challenge']
|
29
31
|
else
|
30
32
|
@response.write 'Error; wrong verify token'
|
31
33
|
end
|
@@ -36,6 +38,8 @@ module Facebook
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def receive
|
41
|
+
return if app_secret && !integrity?
|
42
|
+
|
39
43
|
hash = JSON.parse(@request.body.read)
|
40
44
|
|
41
45
|
# Facebook may batch several items in the 'entry' array during
|
@@ -48,6 +52,32 @@ module Facebook
|
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
55
|
+
|
56
|
+
def integrity?
|
57
|
+
Rack::Utils.secure_compare(x_hub_signature, signature)
|
58
|
+
end
|
59
|
+
|
60
|
+
def x_hub_signature
|
61
|
+
@request.env['HTTP_X_HUB_SIGNATURE'.freeze]
|
62
|
+
end
|
63
|
+
|
64
|
+
def signature
|
65
|
+
format('sha1=%s'.freeze, generate_hmac(@request.body.read))
|
66
|
+
ensure
|
67
|
+
@request.body.rewind
|
68
|
+
end
|
69
|
+
|
70
|
+
def generate_hmac(content)
|
71
|
+
OpenSSL::HMAC.hexdigest(
|
72
|
+
OpenSSL::Digest.new('sha1'),
|
73
|
+
app_secret,
|
74
|
+
content
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def app_secret
|
79
|
+
Facebook::Messenger.config.app_secret
|
80
|
+
end
|
51
81
|
end
|
52
82
|
end
|
53
83
|
end
|
@@ -8,30 +8,38 @@ module Facebook
|
|
8
8
|
|
9
9
|
base_uri 'https://graph.facebook.com/v2.6/me'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
format :json
|
12
|
+
|
13
|
+
module_function
|
14
|
+
|
15
|
+
def subscribe
|
16
|
+
response = post '/subscribed_apps'
|
15
17
|
|
16
18
|
raise_errors(response)
|
17
19
|
|
18
20
|
true
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
22
|
-
response = delete '/subscribed_apps'
|
23
|
-
access_token: Facebook::Messenger.config.access_token
|
24
|
-
}
|
23
|
+
def unsubscribe
|
24
|
+
response = delete '/subscribed_apps'
|
25
25
|
|
26
26
|
raise_errors(response)
|
27
27
|
|
28
28
|
true
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
31
|
+
def raise_errors(response)
|
32
32
|
raise Error, response['error']['message'] if response.key? 'error'
|
33
33
|
end
|
34
34
|
|
35
|
+
def default_options
|
36
|
+
super.merge(
|
37
|
+
query: {
|
38
|
+
access_token: Facebook::Messenger.config.access_token
|
39
|
+
}
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
35
43
|
class Error < Facebook::Messenger::Error; end
|
36
44
|
end
|
37
45
|
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.
|
4
|
+
version: 0.5.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-
|
11
|
+
date: 2016-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
name: rack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.6.4
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.6.4
|
41
41
|
- !ruby/object:Gem::Dependency
|