message_quickly 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/message_quickly/application_helper.rb +4 -0
- data/lib/generators/message_quickly/callbacks/templates/account_linking_callback.rb +14 -0
- data/lib/generators/message_quickly/callbacks/templates/message_read_callback.rb +14 -0
- data/lib/message_quickly.rb +1 -0
- data/lib/message_quickly/api/account_link.rb +41 -0
- data/lib/message_quickly/api/client.rb +9 -0
- data/lib/message_quickly/api/thread_settings.rb +74 -19
- data/lib/message_quickly/api/user_profile.rb +1 -1
- data/lib/message_quickly/callback_parser.rb +9 -1
- data/lib/message_quickly/messaging/account_link_button.rb +23 -0
- data/lib/message_quickly/messaging/account_link_event.rb +41 -0
- data/lib/message_quickly/messaging/account_unlink_button.rb +22 -0
- data/lib/message_quickly/messaging/audio_attachment.rb +41 -0
- data/lib/message_quickly/messaging/button_template_attachment.rb +2 -0
- data/lib/message_quickly/messaging/element.rb +2 -0
- data/lib/message_quickly/messaging/image_attachment.rb +1 -1
- data/lib/message_quickly/messaging/location_attachment.rb +30 -0
- data/lib/message_quickly/messaging/message.rb +16 -3
- data/lib/message_quickly/messaging/message_event.rb +28 -5
- data/lib/message_quickly/messaging/quick_reply.rb +34 -0
- data/lib/message_quickly/messaging/read_event.rb +49 -0
- data/lib/message_quickly/messaging/user.rb +1 -1
- data/lib/message_quickly/messaging/video_attachment.rb +41 -0
- data/lib/message_quickly/version.rb +2 -2
- data/spec/callback_parser_spec.rb +22 -0
- data/spec/controllers/webhooks_controller_spec.rb +35 -1
- data/spec/dummy/app/webhooks/account_linking_callback.rb +14 -0
- data/spec/dummy/app/webhooks/message_read_callback.rb +14 -0
- data/spec/dummy/log/test.log +7166 -0
- data/spec/fixtures/SampleVideo_1280x720_1mb.mp4 +0 -0
- data/spec/fixtures/account_link.json +24 -0
- data/spec/fixtures/jailhouse-rock-demo.mp3 +0 -0
- data/spec/fixtures/message_read.json +24 -0
- data/spec/fixtures/message_request_with_attachment.json +13 -1
- data/spec/message_quickly/api/account_link_spec.rb +49 -0
- data/spec/message_quickly/api/messages_spec.rb +70 -0
- data/spec/message_quickly/api/thread_settings_spec.rb +83 -7
- metadata +27 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f40defb57698c809f71d70ed577debd4a5f085d7
|
4
|
+
data.tar.gz: 45b8b80b3b61984b678a3bc58ae00705f1defc98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d51150793b85d9293a90df174ecdcaf59a631e3e2ddc73fb1a0ae67394b1a3347f268a53bfdb04b17a28f3ef4e3dff1969343236892edf786367b1bfe3519f19
|
7
|
+
data.tar.gz: 9e326b869a79eb7ea26f7f2a8e35142b4d4430309114792f09519399afaae295bb48c2699124ecb942f1417dc1b9417293cc4069cb4f0f786874ec25bf8d0039
|
data/lib/message_quickly.rb
CHANGED
@@ -11,6 +11,7 @@ require "message_quickly/api/not_permitted_exception"
|
|
11
11
|
require "message_quickly/api/send_message_exception"
|
12
12
|
require "message_quickly/api/thread_settings"
|
13
13
|
require "message_quickly/api/user_profile"
|
14
|
+
require "message_quickly/api/account_link"
|
14
15
|
|
15
16
|
require "message_quickly/engine"
|
16
17
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module MessageQuickly
|
2
|
+
module Api
|
3
|
+
class AccountLink < Base
|
4
|
+
|
5
|
+
def self.page_scoped_id(account_linking_token)
|
6
|
+
# curl -X GET "https://graph.facebook.com/v2.6/me?access_token=PAGE_ACCESS_TOKEN \
|
7
|
+
# &fields=recipient \
|
8
|
+
# &account_linking_token=ACCOUNT_LINKING_TOKEN"
|
9
|
+
|
10
|
+
# {
|
11
|
+
# "id": "PAGE_ID",
|
12
|
+
# "recipient": "PSID"
|
13
|
+
# }
|
14
|
+
AccountLink.new.page_scoped_id(account_linking_token)
|
15
|
+
end
|
16
|
+
|
17
|
+
def page_scoped_id(account_linking_token)
|
18
|
+
json = @client.get("me", { fields: 'recipient', account_linking_token: account_linking_token })
|
19
|
+
json['recipient']
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.unlink_account(page_scoped_id)
|
23
|
+
# curl -X POST -H "Content-Type: application/json" -d '{
|
24
|
+
# "psid":"PSID"
|
25
|
+
# }' "https://graph.facebook.com/v2.6/me/unlink_accounts?access_token=PAGE_ACCESS_TOKEN"
|
26
|
+
|
27
|
+
# {
|
28
|
+
# "result": "unlink account success"
|
29
|
+
# }
|
30
|
+
AccountLink.new.unlink_account(page_scoped_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def unlink_account(page_scoped_id)
|
34
|
+
json = @client.post("me/unlink_accounts", { psid: page_scoped_id })
|
35
|
+
json['result'] == "unlink account success"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -31,6 +31,15 @@ module MessageQuickly
|
|
31
31
|
parse_json(response)
|
32
32
|
end
|
33
33
|
|
34
|
+
def delete(request_string, params = {})
|
35
|
+
params[:access_token] = page_access_token
|
36
|
+
response = connection.delete(request_string) do |request|
|
37
|
+
request.headers['Content-Type'] = 'application/json'
|
38
|
+
request.body = JSON.generate(params)
|
39
|
+
end
|
40
|
+
parse_json(response)
|
41
|
+
end
|
42
|
+
|
34
43
|
private
|
35
44
|
|
36
45
|
def parse_json(response)
|
@@ -2,40 +2,95 @@ module MessageQuickly
|
|
2
2
|
module Api
|
3
3
|
class ThreadSettings < Base
|
4
4
|
|
5
|
-
def self.
|
5
|
+
def self.greeting(text)
|
6
|
+
# curl -X POST -H "Content-Type: application/json" -d '{
|
7
|
+
# "setting_type":"greeting",
|
8
|
+
# "greeting":{
|
9
|
+
# "text":"Welcome to My Company!"
|
10
|
+
# }
|
11
|
+
# }' "https://graph.facebook.com/v2.6/<PAGE_ID>/thread_settings?access_token=<PAGE_ACCESS_TOKEN>"
|
12
|
+
ThreadSettings.new.greeting(text)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.get_started_button(payload)
|
6
16
|
# curl -X POST -H "Content-Type: application/json" -d '{
|
7
17
|
# "setting_type":"call_to_actions",
|
8
18
|
# "thread_state":"new_thread",
|
9
19
|
# "call_to_actions":[
|
10
20
|
# {
|
11
|
-
# "
|
12
|
-
# "text":"Welcome to My Company!"
|
13
|
-
# }
|
21
|
+
# "payload":"USER_DEFINED_PAYLOAD"
|
14
22
|
# }
|
15
23
|
# ]
|
16
|
-
# }' "https://graph.facebook.com/v2.6
|
17
|
-
ThreadSettings.new.
|
24
|
+
# }' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=PAGE_ACCESS_TOKEN"
|
25
|
+
ThreadSettings.new.get_started_button(payload)
|
18
26
|
end
|
19
27
|
|
20
|
-
def self.
|
21
|
-
# curl -X
|
28
|
+
def self.remove_get_started_button
|
29
|
+
# curl -X DELETE -H "Content-Type: application/json" -d '{
|
22
30
|
# "setting_type":"call_to_actions",
|
23
|
-
# "thread_state":"new_thread"
|
24
|
-
#
|
25
|
-
|
26
|
-
|
31
|
+
# "thread_state":"new_thread"
|
32
|
+
# }' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=PAGE_ACCESS_TOKEN"
|
33
|
+
ThreadSettings.new.remove_get_started_button
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.persistent_menu(payloads = [])
|
37
|
+
# curl -X POST -H "Content-Type: application/json" -d '{
|
38
|
+
# "setting_type" : "call_to_actions",
|
39
|
+
# "thread_state" : "existing_thread",
|
40
|
+
# "call_to_actions":[
|
41
|
+
# {
|
42
|
+
# "type":"postback",
|
43
|
+
# "title":"Help",
|
44
|
+
# "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_HELP"
|
45
|
+
# },
|
46
|
+
# {
|
47
|
+
# "type":"postback",
|
48
|
+
# "title":"Start a New Order",
|
49
|
+
# "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_START_ORDER"
|
50
|
+
# },
|
51
|
+
# {
|
52
|
+
# "type":"web_url",
|
53
|
+
# "title":"View Website",
|
54
|
+
# "url":"http://petersapparel.parseapp.com/"
|
55
|
+
# }
|
56
|
+
# ]
|
57
|
+
# }' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=PAGE_ACCESS_TOKEN"
|
58
|
+
ThreadSettings.new.persistent_menu(payloads)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.remove_persistent_menu
|
62
|
+
ThreadSettings.new.remove_persistent_menu
|
63
|
+
end
|
64
|
+
|
65
|
+
def greeting(text)
|
66
|
+
json = @client.post(request_string, { setting_type: 'greeting', greeting: { text: text } })
|
67
|
+
json['result'] == "Successfully updated greeting"
|
27
68
|
end
|
28
69
|
|
29
|
-
def
|
30
|
-
|
31
|
-
json = @client.post(request_string, { setting_type: 'call_to_actions', thread_state: 'new_thread', call_to_actions: [{ message: { text: message } }] })
|
70
|
+
def get_started_button(payload)
|
71
|
+
json = @client.post(request_string, { setting_type: 'call_to_actions', thread_state: 'new_thread', call_to_actions: [payload: payload] })
|
32
72
|
json['result'] == "Successfully added new_thread's CTAs"
|
33
73
|
end
|
34
74
|
|
35
|
-
def
|
36
|
-
|
37
|
-
json
|
38
|
-
|
75
|
+
def remove_get_started_button
|
76
|
+
json = @client.delete(request_string, { setting_type: 'call_to_actions', thread_state: 'new_thread' })
|
77
|
+
json['result'] == "Successfully deleted all new_thread's CTAs"
|
78
|
+
end
|
79
|
+
|
80
|
+
def persistent_menu(payloads = [])
|
81
|
+
json = @client.post(request_string, { setting_type: 'call_to_actions', thread_state: 'existing_thread', call_to_actions: payloads })
|
82
|
+
json['result'] == "Successfully added structured menu CTAs"
|
83
|
+
end
|
84
|
+
|
85
|
+
def remove_persistent_menu(payloads = [])
|
86
|
+
json = @client.delete(request_string, { setting_type: 'call_to_actions', thread_state: 'existing_thread' })
|
87
|
+
json['result'] == "Successfully deleted structured menu CTAs"
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def request_string
|
93
|
+
"#{ENV['FACEBOOK_MESSENGER_PAGE_ID']}/thread_settings"
|
39
94
|
end
|
40
95
|
|
41
96
|
end
|
@@ -3,13 +3,17 @@ require 'json'
|
|
3
3
|
require "message_quickly/messaging/base"
|
4
4
|
require "message_quickly/messaging/attachment"
|
5
5
|
require "message_quickly/messaging/image_attachment"
|
6
|
+
require "message_quickly/messaging/video_attachment"
|
7
|
+
require "message_quickly/messaging/audio_attachment"
|
6
8
|
require "message_quickly/messaging/template_attachment"
|
7
9
|
require "message_quickly/messaging/element"
|
8
10
|
require "message_quickly/messaging/button"
|
9
11
|
require "message_quickly/messaging/web_url_button"
|
10
12
|
require "message_quickly/messaging/postback_button"
|
13
|
+
require "message_quickly/messaging/account_link_button"
|
11
14
|
require "message_quickly/messaging/button_template_attachment"
|
12
15
|
require "message_quickly/messaging/generic_template_attachment"
|
16
|
+
require "message_quickly/messaging/quick_reply"
|
13
17
|
|
14
18
|
require "message_quickly/messaging/receipt/address"
|
15
19
|
require "message_quickly/messaging/receipt/adjustment"
|
@@ -29,6 +33,8 @@ require "message_quickly/messaging/optin_event"
|
|
29
33
|
require "message_quickly/messaging/delivery_event"
|
30
34
|
require "message_quickly/messaging/message_event"
|
31
35
|
require "message_quickly/messaging/postback_event"
|
36
|
+
require "message_quickly/messaging/read_event"
|
37
|
+
require "message_quickly/messaging/account_link_event"
|
32
38
|
|
33
39
|
module MessageQuickly
|
34
40
|
class CallbackParser
|
@@ -41,7 +47,9 @@ module MessageQuickly
|
|
41
47
|
optin: MessageQuickly::Messaging::OptinEvent,
|
42
48
|
postback: MessageQuickly::Messaging::PostbackEvent,
|
43
49
|
delivery: MessageQuickly::Messaging::DeliveryEvent,
|
44
|
-
|
50
|
+
account_linking: MessageQuickly::Messaging::AccountLinkEvent,
|
51
|
+
message: MessageQuickly::Messaging::MessageEvent,
|
52
|
+
read: MessageQuickly::Messaging::ReadEvent
|
45
53
|
}
|
46
54
|
|
47
55
|
def parse
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module MessageQuickly
|
2
|
+
module Messaging
|
3
|
+
class AccountLinkButton < Button
|
4
|
+
|
5
|
+
attr_accessor :url
|
6
|
+
|
7
|
+
def initialize(params = {})
|
8
|
+
params['type'] ||= 'account_link'
|
9
|
+
super(params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash
|
13
|
+
{ type: type, url: url }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# "buttons": [{
|
21
|
+
# "type": "account_link",
|
22
|
+
# "url": "https://www.example.com/oauth/authorize"
|
23
|
+
# }]
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "message_quickly/messaging/event"
|
2
|
+
|
3
|
+
module MessageQuickly
|
4
|
+
module Messaging
|
5
|
+
class AccountLinkEvent < Event
|
6
|
+
|
7
|
+
attr_reader :status, :authorization_code
|
8
|
+
|
9
|
+
def initialize(params = {})
|
10
|
+
|
11
|
+
if params.include? :account_linking
|
12
|
+
@status = params[:account_linking][:status]
|
13
|
+
@authorization_code = params[:account_linking][:authorization_code]
|
14
|
+
params.delete(:account_linking)
|
15
|
+
end
|
16
|
+
|
17
|
+
super(params)
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def webhook_name
|
22
|
+
:account_linking
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# {
|
30
|
+
# "sender":{
|
31
|
+
# "id":"USER_ID"
|
32
|
+
# },
|
33
|
+
# "recipient":{
|
34
|
+
# "id":"PAGE_ID"
|
35
|
+
# },
|
36
|
+
# "timestamp":1234567890,
|
37
|
+
# "account_linking":{
|
38
|
+
# "status":"linked",
|
39
|
+
# "authorization_code":"PASS_THROUGH_AUTHORIZATION_CODE"
|
40
|
+
# }
|
41
|
+
# }
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MessageQuickly
|
2
|
+
module Messaging
|
3
|
+
class AccountUnlinkButton < Button
|
4
|
+
|
5
|
+
attr_accessor :url
|
6
|
+
|
7
|
+
def initialize(params = {})
|
8
|
+
params['type'] ||= 'account_unlink'
|
9
|
+
super(params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash
|
13
|
+
{ type: type }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# "buttons": [{
|
21
|
+
# "type": "account_link"
|
22
|
+
# }]
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module MessageQuickly
|
2
|
+
module Messaging
|
3
|
+
class AudioAttachment < Attachment
|
4
|
+
|
5
|
+
attr_accessor :url, :file, :file_type
|
6
|
+
|
7
|
+
def initialize(params = {})
|
8
|
+
params['type'] ||= 'audio'
|
9
|
+
super(params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def file?
|
13
|
+
file.present? && file_type.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
if file?
|
18
|
+
{ type: type, payload: { url: '' } } # cannot send empty hash
|
19
|
+
else
|
20
|
+
{ type: type, payload: { url: url } }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# "attachments":[
|
29
|
+
# {
|
30
|
+
# "type":"audio",
|
31
|
+
# "payload":{
|
32
|
+
# "url":"https://petersapparel.com/bin/clip.mp3"
|
33
|
+
# }
|
34
|
+
# }
|
35
|
+
# ]
|
36
|
+
|
37
|
+
# curl \
|
38
|
+
# -F recipient='{"id":"USER_ID"}' \
|
39
|
+
# -F message='{"attachment":{"type":"audio", "payload":{}}}' \
|
40
|
+
# -F filedata=@/tmp/clip.mp3;type=audio/mp3 \
|
41
|
+
# "https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS_TOKEN"
|