warb 0.1.4 → 1.0.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/.rubocop.yml +5 -12
- data/README.md +9 -32
- data/Rakefile +3 -3
- data/docs/README.md +1 -4
- data/docs/components/README.md +1 -4
- data/docs/messages/README.md +1 -2
- data/docs/messages/flow.md +5 -241
- data/docs/messages/interactive_call_to_action_url.md +9 -9
- data/docs/messages/interactive_list.md +2 -2
- data/docs/messages/interactive_reply_button.md +9 -9
- data/docs/setup.md +1 -45
- data/examples/audio.rb +10 -10
- data/examples/document.rb +34 -34
- data/examples/image.rb +22 -22
- data/examples/interactive_call_to_action_url.rb +46 -46
- data/examples/interactive_list.rb +61 -61
- data/examples/interactive_reply_button.rb +43 -43
- data/examples/location.rb +32 -32
- data/examples/location_request.rb +11 -11
- data/examples/message.rb +8 -8
- data/examples/sticker.rb +10 -10
- data/examples/video.rb +22 -22
- data/examples/webhook.rb +43 -77
- data/lib/warb/client.rb +5 -7
- data/lib/warb/components/action.rb +8 -12
- data/lib/warb/configuration.rb +1 -4
- data/lib/warb/connection.rb +9 -15
- data/lib/warb/dispatcher.rb +3 -4
- data/lib/warb/dispatcher_concern.rb +0 -6
- data/lib/warb/indicator_dispatcher.rb +4 -4
- data/lib/warb/media_dispatcher.rb +10 -10
- data/lib/warb/resources/audio.rb +1 -1
- data/lib/warb/resources/contact.rb +20 -22
- data/lib/warb/resources/document.rb +1 -1
- data/lib/warb/resources/flow.rb +20 -82
- data/lib/warb/resources/image.rb +1 -1
- data/lib/warb/resources/interactive_call_to_action_url.rb +8 -10
- data/lib/warb/resources/interactive_list.rb +5 -7
- data/lib/warb/resources/interactive_reply_button.rb +8 -10
- data/lib/warb/resources/location.rb +1 -11
- data/lib/warb/resources/location_request.rb +3 -5
- data/lib/warb/resources/reaction.rb +1 -1
- data/lib/warb/resources/resource.rb +4 -14
- data/lib/warb/resources/sticker.rb +1 -1
- data/lib/warb/resources/text.rb +3 -31
- data/lib/warb/resources/video.rb +1 -1
- data/lib/warb/utils.rb +1 -3
- data/lib/warb/version.rb +1 -1
- data/lib/warb.rb +31 -67
- metadata +3 -34
- data/docs/components/button.md +0 -62
- data/docs/components/copy_code_button.md +0 -57
- data/docs/components/flow_button.md +0 -102
- data/docs/components/url_button.md +0 -57
- data/docs/messages/template.md +0 -373
- data/docs/resources/README.md +0 -14
- data/docs/resources/currency.md +0 -22
- data/docs/resources/date_time.md +0 -11
- data/docs/resources/text.md +0 -9
- data/lib/warb/category.rb +0 -8
- data/lib/warb/components/button.rb +0 -29
- data/lib/warb/components/component.rb +0 -19
- data/lib/warb/components/copy_code_button.rb +0 -30
- data/lib/warb/components/flow_button.rb +0 -32
- data/lib/warb/components/quick_reply_button.rb +0 -15
- data/lib/warb/components/url_button.rb +0 -30
- data/lib/warb/components/voice_call_button.rb +0 -15
- data/lib/warb/errors.rb +0 -27
- data/lib/warb/language.rb +0 -8
- data/lib/warb/resources/currency.rb +0 -47
- data/lib/warb/resources/date_time.rb +0 -34
- data/lib/warb/resources/helpers/header.rb +0 -35
- data/lib/warb/resources/template.rb +0 -163
- data/lib/warb/resources/validation.rb +0 -30
- data/lib/warb/response.rb +0 -33
- data/lib/warb/response_error_handler.rb +0 -42
- data/lib/warb/template_dispatcher.rb +0 -21
data/examples/sticker.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "../lib/warb"
|
|
4
4
|
|
|
5
5
|
# Configure your variables here
|
|
6
6
|
|
|
7
|
-
access_token =
|
|
8
|
-
business_id =
|
|
9
|
-
sender_id =
|
|
10
|
-
recipient_number =
|
|
7
|
+
access_token = ""
|
|
8
|
+
business_id = ""
|
|
9
|
+
sender_id = ""
|
|
10
|
+
recipient_number = ""
|
|
11
11
|
|
|
12
|
-
image_link =
|
|
12
|
+
image_link = ""
|
|
13
13
|
|
|
14
14
|
# We recommend testing one section at a time, as it can be overwhelming to see all the messages at once.
|
|
15
15
|
# So you can comment out the sections you don't want to test.
|
|
@@ -25,8 +25,8 @@ warb_from_setup = Warb.setup do |config|
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# To send sticker using its ID, you may need to retrieve it first, which can be retrieved this way
|
|
28
|
-
file_path =
|
|
29
|
-
file_type =
|
|
28
|
+
file_path = "" # fill this in with the file path pointing to wherever the sticker is located
|
|
29
|
+
file_type = "image/webp" # fill this in with the mimetype of the sticker to be uploaded
|
|
30
30
|
# only image/webp is allowed for sticker file type
|
|
31
31
|
image_id = warb_from_setup.sticker.upload(file_path: file_path, file_type: file_type)
|
|
32
32
|
# if you already have an sticker id, you can simply replace the above line with such id
|
|
@@ -53,8 +53,8 @@ warb_from_new = Warb.new(
|
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
# Same as stated above, if you need a sticker id, you can upload it this way
|
|
56
|
-
file_path =
|
|
57
|
-
file_type =
|
|
56
|
+
file_path = "" # fill this in with the file path pointing to wherever the sticker is located
|
|
57
|
+
file_type = "" # fill this in with the mimetype of the sticker to be uploaded
|
|
58
58
|
# allow values for file_type: sticker/aac, sticker/amr, sticker/mpeg, sticker/mp4 or sticker/ogg
|
|
59
59
|
image_id = warb_from_setup.sticker.upload(file_path: file_path, file_type: file_type)
|
|
60
60
|
# if you already have a sticker id, you can simply replace the above line with such id
|
data/examples/video.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "../lib/warb"
|
|
4
4
|
|
|
5
5
|
# Configure your variables here
|
|
6
6
|
|
|
7
|
-
access_token =
|
|
8
|
-
business_id =
|
|
9
|
-
sender_id =
|
|
10
|
-
recipient_number =
|
|
7
|
+
access_token = ""
|
|
8
|
+
business_id = ""
|
|
9
|
+
sender_id = ""
|
|
10
|
+
recipient_number = ""
|
|
11
11
|
|
|
12
|
-
video_link =
|
|
12
|
+
video_link = ""
|
|
13
13
|
|
|
14
14
|
# We recommend testing one section at a time, as it can be overwhelming to see all the messages at once.
|
|
15
15
|
# So you can comment out the sections you don't want to test.
|
|
@@ -25,24 +25,24 @@ warb_from_setup = Warb.setup do |config|
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# To send video using its ID, you may need to retrieve it first, which can be retrieved this way
|
|
28
|
-
file_path =
|
|
29
|
-
file_type =
|
|
28
|
+
file_path = "" # fill this in with the file path pointing to wherever the video is located
|
|
29
|
+
file_type = "" # fill this in with the mimetype of the video to be uploaded. allowed values: "video/3gpp" or "video/mp4"
|
|
30
30
|
video_id = warb_from_setup.video.upload(file_path: file_path, file_type: file_type)
|
|
31
31
|
# if you already have a video id, you can simply replace the above line with such id
|
|
32
32
|
|
|
33
33
|
warb_from_setup.video.dispatch(recipient_number, media_id: video_id)
|
|
34
|
-
warb_from_setup.video.dispatch(recipient_number, media_id: video_id, caption:
|
|
34
|
+
warb_from_setup.video.dispatch(recipient_number, media_id: video_id, caption: "OPTIONAL - Image caption")
|
|
35
35
|
warb_from_setup.video.dispatch(recipient_number, link: video_link)
|
|
36
|
-
warb_from_setup.video.dispatch(recipient_number, link: video_link, caption:
|
|
36
|
+
warb_from_setup.video.dispatch(recipient_number, link: video_link, caption: "OPTIONAL - Image caption")
|
|
37
37
|
|
|
38
38
|
warb_from_setup.video.dispatch(recipient_number) do |builder|
|
|
39
39
|
builder.media_id = video_id
|
|
40
|
-
builder.caption =
|
|
40
|
+
builder.caption = "OPTIONAL - Image caption"
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
warb_from_setup.video.dispatch(recipient_number) do |builder|
|
|
44
44
|
builder.link = video_link
|
|
45
|
-
builder.caption =
|
|
45
|
+
builder.caption = "OPTIONAL - Image caption"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# ############################################ #
|
|
@@ -56,24 +56,24 @@ warb_from_new = Warb.new(
|
|
|
56
56
|
)
|
|
57
57
|
|
|
58
58
|
# Same as stated above, if you need a video id, you can upload it this way
|
|
59
|
-
file_path =
|
|
60
|
-
file_type =
|
|
59
|
+
file_path = "" # fill this in with the file path pointing to wherever the video is located
|
|
60
|
+
file_type = "" # fill this in with the mimetype of the video to be uploaded. allowed values: "video/3gpp" or "video/mp4"
|
|
61
61
|
video_id = warb_from_setup.video.upload(file_path: file_path, file_type: file_type)
|
|
62
62
|
# if you already have a video id, you can simply replace the above line with such id
|
|
63
63
|
|
|
64
64
|
warb_from_new.video.dispatch(recipient_number, media_id: video_id)
|
|
65
|
-
warb_from_new.video.dispatch(recipient_number, media_id: video_id, caption:
|
|
65
|
+
warb_from_new.video.dispatch(recipient_number, media_id: video_id, caption: "OPTIONAL - Image caption")
|
|
66
66
|
warb_from_new.video.dispatch(recipient_number, link: video_link)
|
|
67
|
-
warb_from_new.video.dispatch(recipient_number, link: video_link, caption:
|
|
67
|
+
warb_from_new.video.dispatch(recipient_number, link: video_link, caption: "OPTIONAL - Image caption")
|
|
68
68
|
|
|
69
69
|
warb_from_new.video.dispatch(recipient_number) do |builder|
|
|
70
70
|
builder.media_id = video_id
|
|
71
|
-
builder.caption =
|
|
71
|
+
builder.caption = "OPTIONAL - Image caption"
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
warb_from_new.video.dispatch(recipient_number) do |builder|
|
|
75
75
|
builder.link = video_link
|
|
76
|
-
builder.caption =
|
|
76
|
+
builder.caption = "OPTIONAL - Image caption"
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
# ################################################# #
|
|
@@ -81,16 +81,16 @@ end
|
|
|
81
81
|
# ################################################# #
|
|
82
82
|
|
|
83
83
|
Warb.video.dispatch(recipient_number, media_id: video_id)
|
|
84
|
-
Warb.video.dispatch(recipient_number, media_id: video_id, caption:
|
|
84
|
+
Warb.video.dispatch(recipient_number, media_id: video_id, caption: "OPTIONAL - Image caption")
|
|
85
85
|
Warb.video.dispatch(recipient_number, link: video_link)
|
|
86
|
-
Warb.video.dispatch(recipient_number, link: video_link, caption:
|
|
86
|
+
Warb.video.dispatch(recipient_number, link: video_link, caption: "OPTIONAL - Image caption")
|
|
87
87
|
|
|
88
88
|
Warb.video.dispatch(recipient_number) do |builder|
|
|
89
89
|
builder.media_id = video_id
|
|
90
|
-
builder.caption =
|
|
90
|
+
builder.caption = "OPTIONAL - Image caption"
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
Warb.video.dispatch(recipient_number) do |builder|
|
|
94
94
|
builder.link = video_link
|
|
95
|
-
builder.caption =
|
|
95
|
+
builder.caption = "OPTIONAL - Image caption"
|
|
96
96
|
end
|
data/examples/webhook.rb
CHANGED
|
@@ -1,69 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require_relative '../lib/warb'
|
|
4
|
-
require 'sinatra/base'
|
|
5
|
-
require 'faraday'
|
|
6
|
-
require 'openssl'
|
|
1
|
+
require "sinatra/base"
|
|
2
|
+
require "faraday"
|
|
7
3
|
|
|
8
4
|
class Webhook < Sinatra::Base
|
|
9
|
-
|
|
10
|
-
Warb.setup do |config|
|
|
11
|
-
config.access_token = token
|
|
12
|
-
config.business_id = business
|
|
13
|
-
config.sender_id = sender
|
|
14
|
-
end
|
|
15
|
-
|
|
16
5
|
configure do
|
|
17
|
-
set :bind,
|
|
6
|
+
set :bind, "0.0.0.0"
|
|
18
7
|
set :port, 3000
|
|
19
8
|
set :host_authorization, { permitted_hosts: [] }
|
|
20
9
|
end
|
|
21
10
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
header = request.env['HTTP_X_HUB_SIGNATURE_256']
|
|
25
|
-
|
|
26
|
-
halt 400, 'Missing X-Hub-Signature-256' if APP_SECRET && (!header || header.empty?)
|
|
27
|
-
|
|
28
|
-
received = header.sub('sha256=', '')
|
|
29
|
-
expected = OpenSSL::HMAC.hexdigest('SHA256', APP_SECRET, raw_body)
|
|
30
|
-
|
|
31
|
-
unless Rack::Utils.secure_compare(received, expected)
|
|
32
|
-
puts "⚠️ Invalid webhook signature."
|
|
33
|
-
halt 403, 'Invalid signature'
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
true
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
post '/webhook' do
|
|
41
|
-
request.body.rewind
|
|
42
|
-
raw_body = request.body.read
|
|
43
|
-
|
|
44
|
-
verify_signature!(raw_body)
|
|
45
|
-
|
|
46
|
-
request_body = JSON.parse(raw_body)
|
|
11
|
+
post "/webhook" do
|
|
12
|
+
request_body = JSON.parse(request.body.read)
|
|
47
13
|
|
|
48
14
|
puts "\n🪝 Incoming webhook message: #{request_body}"
|
|
49
15
|
|
|
50
|
-
message = request_body.dig(
|
|
16
|
+
message = request_body.dig("entry", 0, "changes", 0, "value", "messages", 0)
|
|
51
17
|
|
|
52
|
-
if message && message[
|
|
53
|
-
message_id = message[
|
|
18
|
+
if message && message["type"] == "text"
|
|
19
|
+
message_id = message["id"]
|
|
54
20
|
|
|
55
21
|
Warb.indicator.mark_as_read(message_id)
|
|
56
22
|
|
|
57
|
-
Warb.message.dispatch(message[
|
|
23
|
+
Warb.message.dispatch(message["from"], reply_to: message_id, message: "Echo #{message["text"]["body"]}")
|
|
58
24
|
|
|
59
25
|
reaction = {
|
|
60
26
|
message_id:,
|
|
61
|
-
emoji:
|
|
27
|
+
emoji: "✅"
|
|
62
28
|
}
|
|
63
29
|
|
|
64
|
-
Warb.reaction.dispatch(message[
|
|
65
|
-
elsif message && message[
|
|
66
|
-
message_id = message[
|
|
30
|
+
Warb.reaction.dispatch(message["from"], **reaction)
|
|
31
|
+
elsif message && message["type"] == "location"
|
|
32
|
+
message_id = message["id"]
|
|
67
33
|
|
|
68
34
|
Warb.indicator.mark_as_read(message_id)
|
|
69
35
|
|
|
@@ -74,15 +40,15 @@ class Webhook < Sinatra::Base
|
|
|
74
40
|
sleep 2
|
|
75
41
|
|
|
76
42
|
location = {
|
|
77
|
-
latitude: message[
|
|
78
|
-
longitude: message[
|
|
79
|
-
name: message[
|
|
80
|
-
address: message[
|
|
43
|
+
latitude: message["location"]["latitude"],
|
|
44
|
+
longitude: message["location"]["longitude"],
|
|
45
|
+
name: message["location"]["name"],
|
|
46
|
+
address: message["location"]["address"]
|
|
81
47
|
}
|
|
82
48
|
|
|
83
|
-
Warb.location.dispatch(message[
|
|
84
|
-
elsif message && message[
|
|
85
|
-
message_id = message[
|
|
49
|
+
Warb.location.dispatch(message["from"], reply_to: message_id, **location)
|
|
50
|
+
elsif message && message["type"] == "image"
|
|
51
|
+
message_id = message["id"]
|
|
86
52
|
|
|
87
53
|
Warb.indicator.mark_as_read(message_id)
|
|
88
54
|
|
|
@@ -101,39 +67,39 @@ class Webhook < Sinatra::Base
|
|
|
101
67
|
# below, we resend the received image, using its id.
|
|
102
68
|
|
|
103
69
|
image = {
|
|
104
|
-
media_id: message[
|
|
105
|
-
link: message[
|
|
106
|
-
caption: message[
|
|
70
|
+
media_id: message["image"]["id"],
|
|
71
|
+
link: message["image"]["link"],
|
|
72
|
+
caption: message["image"]["caption"]
|
|
107
73
|
}
|
|
108
74
|
|
|
109
|
-
Warb.image.dispatch(message[
|
|
75
|
+
Warb.image.dispatch(message["from"], reply_to: message_id, **image)
|
|
110
76
|
|
|
111
77
|
# and here, we download the received image
|
|
112
78
|
Warb.image.download(media_id: image[:media_id], file_path: "#{Time.now}.jpg")
|
|
113
|
-
elsif message && message[
|
|
114
|
-
message_id = message[
|
|
79
|
+
elsif message && message["type"] == "document"
|
|
80
|
+
message_id = message["id"]
|
|
115
81
|
|
|
116
82
|
Warb.indicator.mark_as_read(message_id)
|
|
117
83
|
|
|
118
84
|
document = {
|
|
119
|
-
id: message[
|
|
120
|
-
link: message[
|
|
121
|
-
caption: message[
|
|
122
|
-
filename: message[
|
|
85
|
+
id: message["document"]["id"],
|
|
86
|
+
link: message["document"]["link"],
|
|
87
|
+
caption: message["document"]["caption"],
|
|
88
|
+
filename: message["document"]["filename"]
|
|
123
89
|
}
|
|
124
90
|
|
|
125
|
-
Warb.document.dispatch(message[
|
|
126
|
-
elsif message && message[
|
|
127
|
-
message_id = message[
|
|
91
|
+
Warb.document.dispatch(message["from"], reply_to: message_id, **document)
|
|
92
|
+
elsif message && message["type"] == "sticker"
|
|
93
|
+
message_id = message["id"]
|
|
128
94
|
|
|
129
95
|
Warb.indicator.mark_as_read(message_id)
|
|
130
96
|
|
|
131
97
|
sticker = {
|
|
132
|
-
media_id: message[
|
|
133
|
-
link: message[
|
|
98
|
+
media_id: message["sticker"]["id"],
|
|
99
|
+
link: message["sticker"]["link"]
|
|
134
100
|
}
|
|
135
101
|
|
|
136
|
-
Warb.sticker.dispatch(message[
|
|
102
|
+
Warb.sticker.dispatch(message["from"], reply_to: message_id, **sticker)
|
|
137
103
|
# you could keep adding verifications for different types of messages...
|
|
138
104
|
# elsif message && message["type"] == "image"
|
|
139
105
|
# elsif message && message["type"] == "video"
|
|
@@ -149,12 +115,12 @@ class Webhook < Sinatra::Base
|
|
|
149
115
|
# this is the endpoint which gets called to verify the server within the Meta's API
|
|
150
116
|
# you can do whatever you want here to verify your server
|
|
151
117
|
# returning the challenge value which was received as query param is enough
|
|
152
|
-
get
|
|
153
|
-
mode = params[
|
|
154
|
-
token = params[
|
|
155
|
-
challenge = params[
|
|
118
|
+
get "/webhook" do
|
|
119
|
+
mode = params["hub.mode"]
|
|
120
|
+
token = params["hub.verify_token"]
|
|
121
|
+
challenge = params["hub.challenge"]
|
|
156
122
|
|
|
157
|
-
if mode ==
|
|
123
|
+
if mode == "subscribe" && token == Warb.configuration.webhook_verify_token
|
|
158
124
|
status 200
|
|
159
125
|
body challenge
|
|
160
126
|
|
|
@@ -169,8 +135,8 @@ class Webhook < Sinatra::Base
|
|
|
169
135
|
private
|
|
170
136
|
|
|
171
137
|
def conn
|
|
172
|
-
@conn ||= Faraday.new(
|
|
173
|
-
conn.headers[
|
|
138
|
+
@conn ||= Faraday.new("https://graph.facebook.com/v22.0") do |conn|
|
|
139
|
+
conn.headers["Authorization"] = "Bearer #{Warb.configuration.access_token}" if Warb.configuration.access_token
|
|
174
140
|
conn.request(:json)
|
|
175
141
|
conn.response(:json)
|
|
176
142
|
end
|
data/lib/warb/client.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "connection"
|
|
4
4
|
module Warb
|
|
5
5
|
class Client
|
|
6
6
|
include DispatcherConcern
|
|
@@ -10,7 +10,6 @@ module Warb
|
|
|
10
10
|
|
|
11
11
|
def_delegators :@configuration, :access_token, :sender_id, :business_id, :adapter, :logger
|
|
12
12
|
|
|
13
|
-
# rubocop:disable Metrics/ParameterLists
|
|
14
13
|
def initialize(configuration = nil, access_token: nil, sender_id: nil, business_id: nil,
|
|
15
14
|
adapter: nil, logger: nil)
|
|
16
15
|
@configuration = (configuration || Warb.configuration).dup
|
|
@@ -21,22 +20,21 @@ module Warb
|
|
|
21
20
|
@configuration.adapter = adapter || @configuration.adapter
|
|
22
21
|
@configuration.logger = logger || @configuration.logger
|
|
23
22
|
end
|
|
24
|
-
# rubocop:enable Metrics/ParameterLists
|
|
25
23
|
|
|
26
24
|
def get(endpoint, data = {}, **args)
|
|
27
|
-
conn.send_request(http_method:
|
|
25
|
+
conn.send_request(http_method: "get", endpoint: endpoint, data: data, **args)
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
def post(endpoint, data = {}, **args)
|
|
31
|
-
conn.send_request(http_method:
|
|
29
|
+
conn.send_request(http_method: "post", endpoint: endpoint, data: data, **args)
|
|
32
30
|
end
|
|
33
31
|
|
|
34
32
|
def put(endpoint, data = {}, **args)
|
|
35
|
-
conn.send_request(http_method:
|
|
33
|
+
conn.send_request(http_method: "put", endpoint: endpoint, data: data, **args)
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
def delete(endpoint, data = {}, **args)
|
|
39
|
-
conn.send_request(http_method:
|
|
37
|
+
conn.send_request(http_method: "delete", endpoint: endpoint, data: data, **args)
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
private
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
module Warb
|
|
4
2
|
module Components
|
|
5
3
|
class Row
|
|
@@ -26,12 +24,12 @@ module Warb
|
|
|
26
24
|
@rows = rows
|
|
27
25
|
end
|
|
28
26
|
|
|
29
|
-
def add_row(**args, &)
|
|
27
|
+
def add_row(**args, &block)
|
|
30
28
|
row = Row.new(**args)
|
|
31
29
|
|
|
32
30
|
@rows << row
|
|
33
31
|
|
|
34
|
-
block_given? ? row.tap(&) : row
|
|
32
|
+
block_given? ? row.tap(&block) : row
|
|
35
33
|
end
|
|
36
34
|
|
|
37
35
|
def to_h
|
|
@@ -39,7 +37,7 @@ module Warb
|
|
|
39
37
|
title: @title,
|
|
40
38
|
rows: @rows.map.with_index do |row, index|
|
|
41
39
|
row_title = row.title.slice(0, 10)
|
|
42
|
-
title = row_title.normalize.gsub(/\s/,
|
|
40
|
+
title = row_title.normalize.gsub(/\s/, "").downcase
|
|
43
41
|
id = "#{title}_#{index}"
|
|
44
42
|
|
|
45
43
|
row.to_h.merge(id: id)
|
|
@@ -56,12 +54,12 @@ module Warb
|
|
|
56
54
|
@sections = sections
|
|
57
55
|
end
|
|
58
56
|
|
|
59
|
-
def add_section(**args, &)
|
|
57
|
+
def add_section(**args, &block)
|
|
60
58
|
section = Section.new(**args)
|
|
61
59
|
|
|
62
60
|
@sections << section
|
|
63
61
|
|
|
64
|
-
block_given? ? section.tap(&) : section
|
|
62
|
+
block_given? ? section.tap(&block) : section
|
|
65
63
|
end
|
|
66
64
|
|
|
67
65
|
def to_h
|
|
@@ -79,15 +77,14 @@ module Warb
|
|
|
79
77
|
@buttons_texts = buttons_texts
|
|
80
78
|
end
|
|
81
79
|
|
|
82
|
-
# rubocop:disable Metrics/MethodLength
|
|
83
80
|
def to_h
|
|
84
81
|
{
|
|
85
82
|
buttons: @buttons_texts.map.with_index do |button_text, index|
|
|
86
|
-
text = button_text.normalize.gsub(/\s/,
|
|
83
|
+
text = button_text.normalize.gsub(/\s/, "").downcase
|
|
87
84
|
id = "#{text}_#{index}"
|
|
88
85
|
|
|
89
86
|
{
|
|
90
|
-
type:
|
|
87
|
+
type: "reply",
|
|
91
88
|
reply: {
|
|
92
89
|
id: id,
|
|
93
90
|
title: button_text
|
|
@@ -96,7 +93,6 @@ module Warb
|
|
|
96
93
|
end
|
|
97
94
|
}
|
|
98
95
|
end
|
|
99
|
-
# rubocop:enable Metrics/MethodLength
|
|
100
96
|
|
|
101
97
|
def add_button_text(button_text)
|
|
102
98
|
@buttons_texts << button_text
|
|
@@ -113,7 +109,7 @@ module Warb
|
|
|
113
109
|
|
|
114
110
|
def to_h
|
|
115
111
|
{
|
|
116
|
-
name:
|
|
112
|
+
name: "cta_url",
|
|
117
113
|
parameters: {
|
|
118
114
|
display_text: @button_text,
|
|
119
115
|
url: @url
|
data/lib/warb/configuration.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
module Warb
|
|
4
2
|
class Configuration
|
|
5
|
-
attr_accessor :access_token, :sender_id, :business_id, :adapter, :logger
|
|
3
|
+
attr_accessor :access_token, :sender_id, :business_id, :adapter, :logger
|
|
6
4
|
|
|
7
5
|
def initialize(access_token: nil, sender_id: nil, business_id: nil, adapter: nil, logger: nil)
|
|
8
6
|
@access_token = access_token
|
|
@@ -10,7 +8,6 @@ module Warb
|
|
|
10
8
|
@business_id = business_id
|
|
11
9
|
@adapter = adapter || Faraday.default_adapter
|
|
12
10
|
@logger = logger || Logger.new($stdout)
|
|
13
|
-
@custom_errors = CustomErrors.new.build
|
|
14
11
|
end
|
|
15
12
|
end
|
|
16
13
|
end
|
data/lib/warb/connection.rb
CHANGED
|
@@ -8,34 +8,28 @@ module Warb
|
|
|
8
8
|
@client = client
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
# rubocop:disable Metrics/ParameterLists
|
|
12
11
|
def send_request(http_method:, endpoint:, url: nil, data: {}, headers: {}, multipart: false,
|
|
13
12
|
endpoint_prefix: :sender_id)
|
|
14
|
-
conn =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Warb::ResponseErrorHandler.new(response.body, response.status).handle
|
|
20
|
-
end
|
|
21
|
-
rescue Faraday::Error => e
|
|
22
|
-
msg = e.response_body || e.message
|
|
23
|
-
raise RequestError, msg
|
|
13
|
+
conn = set_connection(url:, multipart:)
|
|
14
|
+
conn.send(http_method, handle_endpoint(endpoint:, endpoint_prefix:), data, headers)
|
|
15
|
+
rescue StandardError => e
|
|
16
|
+
@client.logger.error e.inspect
|
|
17
|
+
e.response
|
|
24
18
|
end
|
|
25
|
-
# rubocop:enable Metrics/ParameterLists
|
|
26
19
|
|
|
27
20
|
private
|
|
28
21
|
|
|
29
|
-
def
|
|
30
|
-
url ||=
|
|
22
|
+
def set_connection(url:, multipart:)
|
|
23
|
+
url ||= "https://graph.facebook.com/v22.0"
|
|
31
24
|
|
|
32
25
|
Faraday.new(url) do |conn|
|
|
33
26
|
conn.request(:multipart) if multipart
|
|
34
27
|
conn.request(:url_encoded) if multipart
|
|
35
28
|
conn.request(:json)
|
|
36
29
|
conn.response(:json)
|
|
37
|
-
conn.headers[
|
|
30
|
+
conn.headers["Authorization"] = "Bearer #{@client.access_token}" unless @client.access_token.nil?
|
|
38
31
|
conn.adapter(@client.adapter)
|
|
32
|
+
conn.response :raise_error
|
|
39
33
|
end
|
|
40
34
|
end
|
|
41
35
|
|
data/lib/warb/dispatcher.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
module Warb
|
|
4
2
|
class Dispatcher
|
|
5
3
|
def initialize(klass, client)
|
|
@@ -8,10 +6,11 @@ module Warb
|
|
|
8
6
|
end
|
|
9
7
|
|
|
10
8
|
def dispatch(recipient_number, reply_to: nil, **args, &block)
|
|
11
|
-
resource = block_given? ? @klass.new
|
|
9
|
+
resource = block_given? ? @klass.new.tap(&block) : @klass.new(**args)
|
|
12
10
|
|
|
13
11
|
data = resource.call(recipient_number, reply_to:)
|
|
14
|
-
|
|
12
|
+
|
|
13
|
+
@client.post("messages", data)
|
|
15
14
|
end
|
|
16
15
|
end
|
|
17
16
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
module Warb
|
|
4
2
|
module DispatcherConcern
|
|
5
3
|
def message
|
|
@@ -58,10 +56,6 @@ module Warb
|
|
|
58
56
|
@contact ||= Dispatcher.new Resources::Contact, dispatcher
|
|
59
57
|
end
|
|
60
58
|
|
|
61
|
-
def template
|
|
62
|
-
@template ||= TemplateDispatcher.new Resources::Template, dispatcher
|
|
63
|
-
end
|
|
64
|
-
|
|
65
59
|
def flow
|
|
66
60
|
@flow ||= Dispatcher.new Resources::Flow, dispatcher
|
|
67
61
|
end
|
|
@@ -7,15 +7,15 @@ module Warb
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def send_typing_indicator(message_id)
|
|
10
|
-
data = common_indicator_params(message_id).merge(typing_indicator: { type:
|
|
10
|
+
data = common_indicator_params(message_id).merge(typing_indicator: { type: "text" })
|
|
11
11
|
|
|
12
|
-
@client.post(
|
|
12
|
+
@client.post("messages", data)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def mark_as_read(message_id)
|
|
16
16
|
data = common_indicator_params(message_id)
|
|
17
17
|
|
|
18
|
-
@client.post(
|
|
18
|
+
@client.post("messages", data)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
private
|
|
@@ -24,7 +24,7 @@ module Warb
|
|
|
24
24
|
{
|
|
25
25
|
messaging_product: Warb::MESSAGING_PRODUCT,
|
|
26
26
|
message_id: message_id,
|
|
27
|
-
status:
|
|
27
|
+
status: "read"
|
|
28
28
|
}
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
module Warb
|
|
4
2
|
class MediaDispatcher < Dispatcher
|
|
5
|
-
def upload(file_path:, file_type:
|
|
3
|
+
def upload(file_path:, file_type: "text/plain")
|
|
6
4
|
file = Faraday::UploadIO.new(file_path, file_type)
|
|
7
5
|
|
|
8
6
|
data = { file:, messaging_product: Warb::MESSAGING_PRODUCT }
|
|
9
7
|
|
|
10
|
-
@client.post(
|
|
8
|
+
@client.post("media", data, multipart: true).body["id"]
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
def download(file_path:, media_url: nil, media_id: nil)
|
|
14
|
-
media_url ||= retrieve(media_id)[
|
|
12
|
+
media_url ||= retrieve(media_id)["url"]
|
|
15
13
|
|
|
16
14
|
resp = downloaded_media_response(media_url)
|
|
17
15
|
|
|
18
|
-
File.
|
|
16
|
+
File.open(file_path, "wb") do |file|
|
|
17
|
+
file.write(resp.body)
|
|
18
|
+
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def retrieve(media_id)
|
|
@@ -25,9 +25,9 @@ module Warb
|
|
|
25
25
|
def delete(media_id)
|
|
26
26
|
response_body = @client.delete(media_id, endpoint_prefix: nil).body
|
|
27
27
|
|
|
28
|
-
return response_body[
|
|
28
|
+
return response_body["success"] if response_body["success"]
|
|
29
29
|
|
|
30
|
-
response_body[
|
|
30
|
+
response_body["error"]["message"]
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
private
|
|
@@ -36,9 +36,9 @@ module Warb
|
|
|
36
36
|
uri = URI(url)
|
|
37
37
|
|
|
38
38
|
request = Net::HTTP::Get.new(uri)
|
|
39
|
-
request[
|
|
39
|
+
request["Authorization"] = "Bearer #{@client.access_token}"
|
|
40
40
|
|
|
41
|
-
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme ==
|
|
41
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
|
|
42
42
|
http.request(request)
|
|
43
43
|
end
|
|
44
44
|
end
|