message_quickly 1.1.2 → 1.2.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/message_quickly/application_helper.rb +4 -0
  3. data/lib/generators/message_quickly/callbacks/templates/account_linking_callback.rb +14 -0
  4. data/lib/generators/message_quickly/callbacks/templates/message_read_callback.rb +14 -0
  5. data/lib/message_quickly.rb +1 -0
  6. data/lib/message_quickly/api/account_link.rb +41 -0
  7. data/lib/message_quickly/api/client.rb +9 -0
  8. data/lib/message_quickly/api/thread_settings.rb +74 -19
  9. data/lib/message_quickly/api/user_profile.rb +1 -1
  10. data/lib/message_quickly/callback_parser.rb +9 -1
  11. data/lib/message_quickly/messaging/account_link_button.rb +23 -0
  12. data/lib/message_quickly/messaging/account_link_event.rb +41 -0
  13. data/lib/message_quickly/messaging/account_unlink_button.rb +22 -0
  14. data/lib/message_quickly/messaging/audio_attachment.rb +41 -0
  15. data/lib/message_quickly/messaging/button_template_attachment.rb +2 -0
  16. data/lib/message_quickly/messaging/element.rb +2 -0
  17. data/lib/message_quickly/messaging/image_attachment.rb +1 -1
  18. data/lib/message_quickly/messaging/location_attachment.rb +30 -0
  19. data/lib/message_quickly/messaging/message.rb +16 -3
  20. data/lib/message_quickly/messaging/message_event.rb +28 -5
  21. data/lib/message_quickly/messaging/quick_reply.rb +34 -0
  22. data/lib/message_quickly/messaging/read_event.rb +49 -0
  23. data/lib/message_quickly/messaging/user.rb +1 -1
  24. data/lib/message_quickly/messaging/video_attachment.rb +41 -0
  25. data/lib/message_quickly/version.rb +2 -2
  26. data/spec/callback_parser_spec.rb +22 -0
  27. data/spec/controllers/webhooks_controller_spec.rb +35 -1
  28. data/spec/dummy/app/webhooks/account_linking_callback.rb +14 -0
  29. data/spec/dummy/app/webhooks/message_read_callback.rb +14 -0
  30. data/spec/dummy/log/test.log +7166 -0
  31. data/spec/fixtures/SampleVideo_1280x720_1mb.mp4 +0 -0
  32. data/spec/fixtures/account_link.json +24 -0
  33. data/spec/fixtures/jailhouse-rock-demo.mp3 +0 -0
  34. data/spec/fixtures/message_read.json +24 -0
  35. data/spec/fixtures/message_request_with_attachment.json +13 -1
  36. data/spec/message_quickly/api/account_link_spec.rb +49 -0
  37. data/spec/message_quickly/api/messages_spec.rb +70 -0
  38. data/spec/message_quickly/api/thread_settings_spec.rb +83 -7
  39. metadata +27 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 50e84b3ef8343c78048a81ffe8e06a18ec160538
4
- data.tar.gz: ba28b127efdcf9569202fe26ac375ddbacd6d54d
3
+ metadata.gz: f40defb57698c809f71d70ed577debd4a5f085d7
4
+ data.tar.gz: 45b8b80b3b61984b678a3bc58ae00705f1defc98
5
5
  SHA512:
6
- metadata.gz: 525a00f7e6803fd9d74513c5a49be838c9c6d8e31d5e8b822e8ee2a6c23af5aa9198f6908853fc7d5671256a0098df0dd52aeedf15d0a45f6381011f9550101c
7
- data.tar.gz: 16692e9535cbfdc4ec1712f848f518c6e57b136f04c36caf91d8c7348c0f63eebb6e78404d925be13764126868c7d26647c9ff9c1c899a117a7ac38445568e30
6
+ metadata.gz: d51150793b85d9293a90df174ecdcaf59a631e3e2ddc73fb1a0ae67394b1a3347f268a53bfdb04b17a28f3ef4e3dff1969343236892edf786367b1bfe3519f19
7
+ data.tar.gz: 9e326b869a79eb7ea26f7f2a8e35142b4d4430309114792f09519399afaae295bb48c2699124ecb942f1417dc1b9417293cc4069cb4f0f786874ec25bf8d0039
@@ -21,5 +21,9 @@ module MessageQuickly
21
21
  content_tag(:div, '', params)
22
22
  end
23
23
 
24
+ # def close_window(image_url = '', display_text = '')
25
+ # redirect_to "https://www.messenger.com/closeWindow/?image_url=#{image_url}&display_text=#{display_text}."
26
+ # end
27
+
24
28
  end
25
29
  end
@@ -0,0 +1,14 @@
1
+ class AccountLinkingCallback < MessageQuickly::Callback
2
+
3
+ def self.webhook_name
4
+ :account_linking
5
+ end
6
+
7
+ def initialize(event, json)
8
+ super
9
+ end
10
+
11
+ def run
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ class MessageReadCallback < MessageQuickly::Callback
2
+
3
+ def self.webhook_name
4
+ :message_reads
5
+ end
6
+
7
+ def initialize(event, json)
8
+ super
9
+ end
10
+
11
+ def run
12
+ end
13
+
14
+ end
@@ -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.create(message)
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
- # "message":{
12
- # "text":"Welcome to My Company!"
13
- # }
21
+ # "payload":"USER_DEFINED_PAYLOAD"
14
22
  # }
15
23
  # ]
16
- # }' "https://graph.facebook.com/v2.6/<PAGE_ID>/thread_settings?access_token=<PAGE_ACCESS_TOKEN>"
17
- ThreadSettings.new.create(message)
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.delete
21
- # curl -X POST -H "Content-Type: application/json" -d '{
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
- # "call_to_actions":[]
25
- # }' "https://graph.facebook.com/v2.6/<PAGE_ID>/thread_settings?access_token=<PAGE_ACCESS_TOKEN>"
26
- ThreadSettings.new.delete
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 create(message)
30
- request_string = "#{ENV['FACEBOOK_MESSENGER_PAGE_ID']}/thread_settings"
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 delete
36
- request_string = "#{ENV['FACEBOOK_MESSENGER_PAGE_ID']}/thread_settings"
37
- json = @client.post(request_string, { setting_type: 'call_to_actions', thread_state: 'new_thread', call_to_actions: [] })
38
- json['result'] == "Successfully removed all new_thread's CTAs"
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
@@ -13,7 +13,7 @@ module MessageQuickly
13
13
  end
14
14
 
15
15
  def find(id)
16
- json = @client.get(id, { fields: 'first_name,last_name,profile_pic' })
16
+ json = @client.get(id, { fields: 'first_name,last_name,profile_pic,locale,timezone,gender' })
17
17
  Messaging::User.new(json)
18
18
  end
19
19
 
@@ -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
- message: MessageQuickly::Messaging::MessageEvent
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"
@@ -16,6 +16,8 @@ module MessageQuickly
16
16
  button = WebUrlButton.new
17
17
  when :postback
18
18
  button = PostbackButton.new
19
+ when :account_link
20
+ button = AccountLinkButton.new
19
21
  end
20
22
  buttons << button.tap { |button| yield button }
21
23
  end
@@ -15,6 +15,8 @@ module MessageQuickly
15
15
  button = WebUrlButton.new
16
16
  when :postback
17
17
  button = PostbackButton.new
18
+ when :account_link
19
+ button = AccountLinkButton.new
18
20
  end
19
21
  buttons << button.tap { |button| yield button }
20
22
  end
@@ -15,7 +15,7 @@ module MessageQuickly
15
15
 
16
16
  def to_hash
17
17
  if file?
18
- { type: type, payload: { _: '' } } # cannot send empty hash
18
+ { type: type, payload: { url: '' } } # cannot send empty hash
19
19
  else
20
20
  { type: type, payload: { url: url } }
21
21
  end