warb 1.0.0 → 1.0.1
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 +12 -5
- data/README.md +32 -9
- data/Rakefile +3 -3
- data/docs/README.md +4 -1
- data/docs/components/README.md +4 -1
- data/docs/components/button.md +62 -0
- data/docs/components/copy_code_button.md +57 -0
- data/docs/components/flow_button.md +102 -0
- data/docs/components/url_button.md +57 -0
- data/docs/messages/README.md +2 -1
- data/docs/messages/flow.md +241 -5
- 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/messages/template.md +373 -0
- data/docs/resources/README.md +14 -0
- data/docs/resources/currency.md +22 -0
- data/docs/resources/date_time.md +11 -0
- data/docs/resources/text.md +9 -0
- data/docs/setup.md +45 -1
- 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 +77 -43
- data/lib/warb/category.rb +8 -0
- data/lib/warb/client.rb +7 -5
- data/lib/warb/components/action.rb +12 -8
- data/lib/warb/components/button.rb +29 -0
- data/lib/warb/components/component.rb +19 -0
- data/lib/warb/components/copy_code_button.rb +30 -0
- data/lib/warb/components/flow_button.rb +32 -0
- data/lib/warb/components/quick_reply_button.rb +15 -0
- data/lib/warb/components/url_button.rb +30 -0
- data/lib/warb/components/voice_call_button.rb +15 -0
- data/lib/warb/configuration.rb +4 -1
- data/lib/warb/connection.rb +15 -9
- data/lib/warb/dispatcher.rb +4 -3
- data/lib/warb/dispatcher_concern.rb +6 -0
- data/lib/warb/errors.rb +27 -0
- data/lib/warb/indicator_dispatcher.rb +4 -4
- data/lib/warb/language.rb +8 -0
- data/lib/warb/media_dispatcher.rb +10 -10
- data/lib/warb/resources/audio.rb +1 -1
- data/lib/warb/resources/contact.rb +22 -20
- data/lib/warb/resources/currency.rb +47 -0
- data/lib/warb/resources/date_time.rb +34 -0
- data/lib/warb/resources/document.rb +1 -1
- data/lib/warb/resources/flow.rb +82 -20
- data/lib/warb/resources/helpers/header.rb +35 -0
- data/lib/warb/resources/image.rb +1 -1
- data/lib/warb/resources/interactive_call_to_action_url.rb +10 -8
- data/lib/warb/resources/interactive_list.rb +7 -5
- data/lib/warb/resources/interactive_reply_button.rb +10 -8
- data/lib/warb/resources/location.rb +11 -1
- data/lib/warb/resources/location_request.rb +5 -3
- data/lib/warb/resources/reaction.rb +1 -1
- data/lib/warb/resources/resource.rb +14 -4
- data/lib/warb/resources/sticker.rb +1 -1
- data/lib/warb/resources/template.rb +163 -0
- data/lib/warb/resources/text.rb +31 -3
- data/lib/warb/resources/validation.rb +30 -0
- data/lib/warb/resources/video.rb +1 -1
- data/lib/warb/response.rb +33 -0
- data/lib/warb/response_error_handler.rb +42 -0
- data/lib/warb/template_dispatcher.rb +21 -0
- data/lib/warb/utils.rb +3 -1
- data/lib/warb/version.rb +1 -1
- data/lib/warb.rb +67 -31
- metadata +34 -3
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,35 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/warb'
|
|
4
|
+
require 'sinatra/base'
|
|
5
|
+
require 'faraday'
|
|
6
|
+
require 'openssl'
|
|
3
7
|
|
|
4
8
|
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
|
+
|
|
5
16
|
configure do
|
|
6
|
-
set :bind,
|
|
17
|
+
set :bind, '0.0.0.0'
|
|
7
18
|
set :port, 3000
|
|
8
19
|
set :host_authorization, { permitted_hosts: [] }
|
|
9
20
|
end
|
|
10
21
|
|
|
11
|
-
|
|
12
|
-
|
|
22
|
+
helpers do
|
|
23
|
+
def verify_signature!(raw_body)
|
|
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)
|
|
13
47
|
|
|
14
48
|
puts "\n🪝 Incoming webhook message: #{request_body}"
|
|
15
49
|
|
|
16
|
-
message = request_body.dig(
|
|
50
|
+
message = request_body.dig('entry', 0, 'changes', 0, 'value', 'messages', 0)
|
|
17
51
|
|
|
18
|
-
if message && message[
|
|
19
|
-
message_id = message[
|
|
52
|
+
if message && message['type'] == 'text'
|
|
53
|
+
message_id = message['id']
|
|
20
54
|
|
|
21
55
|
Warb.indicator.mark_as_read(message_id)
|
|
22
56
|
|
|
23
|
-
Warb.message.dispatch(message[
|
|
57
|
+
Warb.message.dispatch(message['from'], reply_to: message_id, message: "Echo #{message['text']['body']}")
|
|
24
58
|
|
|
25
59
|
reaction = {
|
|
26
60
|
message_id:,
|
|
27
|
-
emoji:
|
|
61
|
+
emoji: '✅'
|
|
28
62
|
}
|
|
29
63
|
|
|
30
|
-
Warb.reaction.dispatch(message[
|
|
31
|
-
elsif message && message[
|
|
32
|
-
message_id = message[
|
|
64
|
+
Warb.reaction.dispatch(message['from'], **reaction)
|
|
65
|
+
elsif message && message['type'] == 'location'
|
|
66
|
+
message_id = message['id']
|
|
33
67
|
|
|
34
68
|
Warb.indicator.mark_as_read(message_id)
|
|
35
69
|
|
|
@@ -40,15 +74,15 @@ class Webhook < Sinatra::Base
|
|
|
40
74
|
sleep 2
|
|
41
75
|
|
|
42
76
|
location = {
|
|
43
|
-
latitude: message[
|
|
44
|
-
longitude: message[
|
|
45
|
-
name: message[
|
|
46
|
-
address: message[
|
|
77
|
+
latitude: message['location']['latitude'],
|
|
78
|
+
longitude: message['location']['longitude'],
|
|
79
|
+
name: message['location']['name'],
|
|
80
|
+
address: message['location']['address']
|
|
47
81
|
}
|
|
48
82
|
|
|
49
|
-
Warb.location.dispatch(message[
|
|
50
|
-
elsif message && message[
|
|
51
|
-
message_id = message[
|
|
83
|
+
Warb.location.dispatch(message['from'], reply_to: message_id, **location)
|
|
84
|
+
elsif message && message['type'] == 'image'
|
|
85
|
+
message_id = message['id']
|
|
52
86
|
|
|
53
87
|
Warb.indicator.mark_as_read(message_id)
|
|
54
88
|
|
|
@@ -67,39 +101,39 @@ class Webhook < Sinatra::Base
|
|
|
67
101
|
# below, we resend the received image, using its id.
|
|
68
102
|
|
|
69
103
|
image = {
|
|
70
|
-
media_id: message[
|
|
71
|
-
link: message[
|
|
72
|
-
caption: message[
|
|
104
|
+
media_id: message['image']['id'],
|
|
105
|
+
link: message['image']['link'],
|
|
106
|
+
caption: message['image']['caption']
|
|
73
107
|
}
|
|
74
108
|
|
|
75
|
-
Warb.image.dispatch(message[
|
|
109
|
+
Warb.image.dispatch(message['from'], reply_to: message_id, **image)
|
|
76
110
|
|
|
77
111
|
# and here, we download the received image
|
|
78
112
|
Warb.image.download(media_id: image[:media_id], file_path: "#{Time.now}.jpg")
|
|
79
|
-
elsif message && message[
|
|
80
|
-
message_id = message[
|
|
113
|
+
elsif message && message['type'] == 'document'
|
|
114
|
+
message_id = message['id']
|
|
81
115
|
|
|
82
116
|
Warb.indicator.mark_as_read(message_id)
|
|
83
117
|
|
|
84
118
|
document = {
|
|
85
|
-
id: message[
|
|
86
|
-
link: message[
|
|
87
|
-
caption: message[
|
|
88
|
-
filename: message[
|
|
119
|
+
id: message['document']['id'],
|
|
120
|
+
link: message['document']['link'],
|
|
121
|
+
caption: message['document']['caption'],
|
|
122
|
+
filename: message['document']['filename']
|
|
89
123
|
}
|
|
90
124
|
|
|
91
|
-
Warb.document.dispatch(message[
|
|
92
|
-
elsif message && message[
|
|
93
|
-
message_id = message[
|
|
125
|
+
Warb.document.dispatch(message['from'], reply_to: message_id, **document)
|
|
126
|
+
elsif message && message['type'] == 'sticker'
|
|
127
|
+
message_id = message['id']
|
|
94
128
|
|
|
95
129
|
Warb.indicator.mark_as_read(message_id)
|
|
96
130
|
|
|
97
131
|
sticker = {
|
|
98
|
-
media_id: message[
|
|
99
|
-
link: message[
|
|
132
|
+
media_id: message['sticker']['id'],
|
|
133
|
+
link: message['sticker']['link']
|
|
100
134
|
}
|
|
101
135
|
|
|
102
|
-
Warb.sticker.dispatch(message[
|
|
136
|
+
Warb.sticker.dispatch(message['from'], reply_to: message_id, **sticker)
|
|
103
137
|
# you could keep adding verifications for different types of messages...
|
|
104
138
|
# elsif message && message["type"] == "image"
|
|
105
139
|
# elsif message && message["type"] == "video"
|
|
@@ -115,12 +149,12 @@ class Webhook < Sinatra::Base
|
|
|
115
149
|
# this is the endpoint which gets called to verify the server within the Meta's API
|
|
116
150
|
# you can do whatever you want here to verify your server
|
|
117
151
|
# returning the challenge value which was received as query param is enough
|
|
118
|
-
get
|
|
119
|
-
mode = params[
|
|
120
|
-
token = params[
|
|
121
|
-
challenge = params[
|
|
152
|
+
get '/webhook' do
|
|
153
|
+
mode = params['hub.mode']
|
|
154
|
+
token = params['hub.verify_token']
|
|
155
|
+
challenge = params['hub.challenge']
|
|
122
156
|
|
|
123
|
-
if mode ==
|
|
157
|
+
if mode == 'subscribe' && token == Warb.configuration.webhook_verify_token
|
|
124
158
|
status 200
|
|
125
159
|
body challenge
|
|
126
160
|
|
|
@@ -135,8 +169,8 @@ class Webhook < Sinatra::Base
|
|
|
135
169
|
private
|
|
136
170
|
|
|
137
171
|
def conn
|
|
138
|
-
@conn ||= Faraday.new(
|
|
139
|
-
conn.headers[
|
|
172
|
+
@conn ||= Faraday.new('https://graph.facebook.com/v22.0') do |conn|
|
|
173
|
+
conn.headers['Authorization'] = "Bearer #{Warb.configuration.access_token}" if Warb.configuration.access_token
|
|
140
174
|
conn.request(:json)
|
|
141
175
|
conn.response(:json)
|
|
142
176
|
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,6 +10,7 @@ module Warb
|
|
|
10
10
|
|
|
11
11
|
def_delegators :@configuration, :access_token, :sender_id, :business_id, :adapter, :logger
|
|
12
12
|
|
|
13
|
+
# rubocop:disable Metrics/ParameterLists
|
|
13
14
|
def initialize(configuration = nil, access_token: nil, sender_id: nil, business_id: nil,
|
|
14
15
|
adapter: nil, logger: nil)
|
|
15
16
|
@configuration = (configuration || Warb.configuration).dup
|
|
@@ -20,21 +21,22 @@ module Warb
|
|
|
20
21
|
@configuration.adapter = adapter || @configuration.adapter
|
|
21
22
|
@configuration.logger = logger || @configuration.logger
|
|
22
23
|
end
|
|
24
|
+
# rubocop:enable Metrics/ParameterLists
|
|
23
25
|
|
|
24
26
|
def get(endpoint, data = {}, **args)
|
|
25
|
-
conn.send_request(http_method:
|
|
27
|
+
conn.send_request(http_method: 'get', endpoint: endpoint, data: data, **args)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def post(endpoint, data = {}, **args)
|
|
29
|
-
conn.send_request(http_method:
|
|
31
|
+
conn.send_request(http_method: 'post', endpoint: endpoint, data: data, **args)
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def put(endpoint, data = {}, **args)
|
|
33
|
-
conn.send_request(http_method:
|
|
35
|
+
conn.send_request(http_method: 'put', endpoint: endpoint, data: data, **args)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def delete(endpoint, data = {}, **args)
|
|
37
|
-
conn.send_request(http_method:
|
|
39
|
+
conn.send_request(http_method: 'delete', endpoint: endpoint, data: data, **args)
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
private
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Warb
|
|
2
4
|
module Components
|
|
3
5
|
class Row
|
|
@@ -24,12 +26,12 @@ module Warb
|
|
|
24
26
|
@rows = rows
|
|
25
27
|
end
|
|
26
28
|
|
|
27
|
-
def add_row(**args, &
|
|
29
|
+
def add_row(**args, &)
|
|
28
30
|
row = Row.new(**args)
|
|
29
31
|
|
|
30
32
|
@rows << row
|
|
31
33
|
|
|
32
|
-
block_given? ? row.tap(&
|
|
34
|
+
block_given? ? row.tap(&) : row
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def to_h
|
|
@@ -37,7 +39,7 @@ module Warb
|
|
|
37
39
|
title: @title,
|
|
38
40
|
rows: @rows.map.with_index do |row, index|
|
|
39
41
|
row_title = row.title.slice(0, 10)
|
|
40
|
-
title = row_title.normalize.gsub(/\s/,
|
|
42
|
+
title = row_title.normalize.gsub(/\s/, '').downcase
|
|
41
43
|
id = "#{title}_#{index}"
|
|
42
44
|
|
|
43
45
|
row.to_h.merge(id: id)
|
|
@@ -54,12 +56,12 @@ module Warb
|
|
|
54
56
|
@sections = sections
|
|
55
57
|
end
|
|
56
58
|
|
|
57
|
-
def add_section(**args, &
|
|
59
|
+
def add_section(**args, &)
|
|
58
60
|
section = Section.new(**args)
|
|
59
61
|
|
|
60
62
|
@sections << section
|
|
61
63
|
|
|
62
|
-
block_given? ? section.tap(&
|
|
64
|
+
block_given? ? section.tap(&) : section
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
def to_h
|
|
@@ -77,14 +79,15 @@ module Warb
|
|
|
77
79
|
@buttons_texts = buttons_texts
|
|
78
80
|
end
|
|
79
81
|
|
|
82
|
+
# rubocop:disable Metrics/MethodLength
|
|
80
83
|
def to_h
|
|
81
84
|
{
|
|
82
85
|
buttons: @buttons_texts.map.with_index do |button_text, index|
|
|
83
|
-
text = button_text.normalize.gsub(/\s/,
|
|
86
|
+
text = button_text.normalize.gsub(/\s/, '').downcase
|
|
84
87
|
id = "#{text}_#{index}"
|
|
85
88
|
|
|
86
89
|
{
|
|
87
|
-
type:
|
|
90
|
+
type: 'reply',
|
|
88
91
|
reply: {
|
|
89
92
|
id: id,
|
|
90
93
|
title: button_text
|
|
@@ -93,6 +96,7 @@ module Warb
|
|
|
93
96
|
end
|
|
94
97
|
}
|
|
95
98
|
end
|
|
99
|
+
# rubocop:enable Metrics/MethodLength
|
|
96
100
|
|
|
97
101
|
def add_button_text(button_text)
|
|
98
102
|
@buttons_texts << button_text
|
|
@@ -109,7 +113,7 @@ module Warb
|
|
|
109
113
|
|
|
110
114
|
def to_h
|
|
111
115
|
{
|
|
112
|
-
name:
|
|
116
|
+
name: 'cta_url',
|
|
113
117
|
parameters: {
|
|
114
118
|
display_text: @button_text,
|
|
115
119
|
url: @url
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Warb
|
|
4
|
+
module Components
|
|
5
|
+
class Button < Component
|
|
6
|
+
attr_accessor :index, :sub_type
|
|
7
|
+
|
|
8
|
+
def initialize(**params)
|
|
9
|
+
params[:sub_type] = button_type unless params[:sub_type]
|
|
10
|
+
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_h
|
|
15
|
+
{
|
|
16
|
+
type: 'button',
|
|
17
|
+
sub_type: sub_type || @params[:sub_type],
|
|
18
|
+
index: index || @params[:index]
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def button_type
|
|
25
|
+
raise NotImplementedError
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Warb
|
|
4
|
+
module Components
|
|
5
|
+
class Component
|
|
6
|
+
def initialize(**params)
|
|
7
|
+
@params = params
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_h
|
|
11
|
+
raise NotImplementedError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
attr_reader :params
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Warb
|
|
4
|
+
module Components
|
|
5
|
+
class CopyCodeButton < Button
|
|
6
|
+
BUTTON_TYPE = 'copy_code'
|
|
7
|
+
|
|
8
|
+
attr_accessor :coupon_code
|
|
9
|
+
|
|
10
|
+
def to_h
|
|
11
|
+
button_payload = super
|
|
12
|
+
|
|
13
|
+
if coupon_code || @params[:coupon_code]
|
|
14
|
+
button_payload[:parameters] = Array.new(1, {
|
|
15
|
+
type: 'coupon_code',
|
|
16
|
+
coupon_code: coupon_code || @params[:coupon_code]
|
|
17
|
+
})
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
button_payload
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def button_type
|
|
26
|
+
BUTTON_TYPE
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Warb
|
|
4
|
+
module Components
|
|
5
|
+
class FlowButton < Button
|
|
6
|
+
BUTTON_TYPE = 'flow'
|
|
7
|
+
|
|
8
|
+
attr_accessor :flow_token, :flow_action_data
|
|
9
|
+
|
|
10
|
+
def to_h
|
|
11
|
+
button_payload = super
|
|
12
|
+
|
|
13
|
+
token = flow_token || @params[:flow_token]
|
|
14
|
+
data = flow_action_data || @params[:flow_action_data]
|
|
15
|
+
|
|
16
|
+
action = {}
|
|
17
|
+
action[:flow_token] = token if token
|
|
18
|
+
action[:flow_action_data] = data if data
|
|
19
|
+
|
|
20
|
+
button_payload[:parameters] = [{ type: 'action', action: action }]
|
|
21
|
+
|
|
22
|
+
button_payload
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def button_type
|
|
28
|
+
BUTTON_TYPE
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Warb
|
|
4
|
+
module Components
|
|
5
|
+
class UrlButton < Button
|
|
6
|
+
BUTTON_TYPE = 'url'
|
|
7
|
+
|
|
8
|
+
attr_accessor :text
|
|
9
|
+
|
|
10
|
+
def to_h
|
|
11
|
+
button_payload = super
|
|
12
|
+
|
|
13
|
+
if text || @params[:text]
|
|
14
|
+
button_payload[:parameters] = Array.new(1, {
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: text || @params[:text]
|
|
17
|
+
})
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
button_payload
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def button_type
|
|
26
|
+
BUTTON_TYPE
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/warb/configuration.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Warb
|
|
2
4
|
class Configuration
|
|
3
|
-
attr_accessor :access_token, :sender_id, :business_id, :adapter, :logger
|
|
5
|
+
attr_accessor :access_token, :sender_id, :business_id, :adapter, :logger, :custom_errors
|
|
4
6
|
|
|
5
7
|
def initialize(access_token: nil, sender_id: nil, business_id: nil, adapter: nil, logger: nil)
|
|
6
8
|
@access_token = access_token
|
|
@@ -8,6 +10,7 @@ module Warb
|
|
|
8
10
|
@business_id = business_id
|
|
9
11
|
@adapter = adapter || Faraday.default_adapter
|
|
10
12
|
@logger = logger || Logger.new($stdout)
|
|
13
|
+
@custom_errors = CustomErrors.new.build
|
|
11
14
|
end
|
|
12
15
|
end
|
|
13
16
|
end
|