whatsapp_sdk 0.7.2 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78aea6934c0189c059dbce4818236b2299319a19b41e8c5ca7d0eca21e8facd3
4
- data.tar.gz: 1afd90036deb2f2f2010e2925c09f440215f5bad874d1b0038f4f65f110e1002
3
+ metadata.gz: cf1d072bf1bc9cd834a9917a863177cc0b5b2ddfac0c29b0d4e899ee23cb9c19
4
+ data.tar.gz: 25dca7a61a5d80d19fcf32fa54e07edcb911901e936c5b315e46488d87c8b900
5
5
  SHA512:
6
- metadata.gz: fcf1df484e0246c5d78110089208391bda6ffcaca8914b518d7b95f38b0f7ea5fb8be9c251b0cf24cb7276122b1c8ead1031b612c351697bb0cf22e0996f1c97
7
- data.tar.gz: b39fb20cc9af081b217e4478432190a3941e2d87f6abe85e69626e6891293d6065b180075160e6cf8c84a1a61442cb585a186740a984bfcefd5d650fce903627
6
+ metadata.gz: 5a1204308855d7fb8945a5fda9a3939928b0ec5d6cc6e65fe95abfb303eec2f3dfa4f667f6b9cfc3c264144cdf8290eb80e7aa2ed5e60b213da398d1beded5ef
7
+ data.tar.gz: 82039c3038209445ad552cca6c23755d8acf2662af4ff6c3fb63464979a42533c92d5768cd376c72252e5b4058932b71a8b9d393471aeb7ba4903a1b62358c12
data/.rubocop.yml CHANGED
@@ -26,7 +26,10 @@ Layout/LineLength:
26
26
  Max: 120
27
27
 
28
28
  Metrics/MethodLength:
29
- Max: 40
29
+ Enabled: false
30
+
31
+ Metrics/BlockLength:
32
+ Enabled: false
30
33
 
31
34
  Naming/VariableNumber:
32
35
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Unreleased
2
2
 
3
+ # v 0.8.0
4
+ - Added Send interactive message @alienware [#82](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/82)
5
+ - Support JRuby @ignacio-chiazzo [#83](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/83)
6
+ - Send interactive Reply Buttons Message @alienware [#79](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/79)
7
+
8
+ # v 0.7.3
9
+ - Added the ability to reply messages. @alienware [#77](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/77)
10
+
3
11
  # v 0.7.2
4
12
  - Added new fields to phone numbers API. @ignacio-chiazzo [#73](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/73)
5
13
  - Upgraded API version to v16. @ignacio-chiazzo [#73](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/73)
data/Gemfile CHANGED
@@ -7,7 +7,6 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
7
7
 
8
8
  gem("faraday")
9
9
  gem("faraday-multipart")
10
- gem("oj")
11
10
  gem("rake", ">= 12.3.3")
12
11
  gem('sorbet-runtime')
13
12
  gem("zeitwerk", ">= 2.6.0")
data/Gemfile.lock CHANGED
@@ -1,10 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- whatsapp_sdk (0.7.2)
4
+ whatsapp_sdk (0.8.0)
5
5
  faraday (~> 2.3.0)
6
6
  faraday-multipart (~> 1.0.4)
7
- oj (~> 3.13.13)
8
7
  sorbet-runtime (~> 0.5.1)
9
8
  zeitwerk (~> 2.6.0)
10
9
 
@@ -30,7 +29,6 @@ GEM
30
29
  mocha (1.14.0)
31
30
  multipart-post (2.2.3)
32
31
  netrc (0.11.0)
33
- oj (3.13.14)
34
32
  parallel (1.22.1)
35
33
  parser (3.1.2.0)
36
34
  ast (~> 2.4.1)
@@ -119,7 +117,6 @@ DEPENDENCIES
119
117
  faraday-multipart
120
118
  minitest (~> 5.0)
121
119
  mocha
122
- oj
123
120
  pry
124
121
  pry-nav
125
122
  rake (>= 12.3.3)
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  <a href="https://codeclimate.com/github/ignacio-chiazzo/ruby_whatsapp_sdk/maintainability"><img src="https://api.codeclimate.com/v1/badges/169cce95450272e4ad7d/maintainability" /></a>
5
5
 
6
6
  The SDK provides a set of operations and classes to use the Whatsapp API.
7
- Send stickers, messages, audio, videos, locations, react to messages or just ask for the phone numbers through this library in a few steps!
7
+ Send stickers, messages, audio, videos, locations, react and reply to messages or just ask for the phone numbers through this library in a few steps!
8
8
 
9
9
 
10
10
  ## Demo
@@ -218,6 +218,13 @@ messages_api.send_reaction(sender_id: 123_123, recipient_number: 56_789, message
218
218
  messages_api.send_reaction(sender_id: 123_123, recipient_number: 56_789, message_id: "12345", emoji: "⛄️")
219
219
  ```
220
220
 
221
+ **Reply to a message**
222
+ To reply to a message, just include the id of the message in the `messages_api` methods. For example, to reply to a text message include the following:
223
+
224
+ ```ruby
225
+ messages_api.send_text(sender_id: 123_123, recipient_number: 56_789, message: "I'm a reply", message_id: "wamid.1234")
226
+ ```
227
+
221
228
  **Send a location message**
222
229
 
223
230
  ```ruby
@@ -343,8 +350,125 @@ Alernative, you could pass a plain json like this:
343
350
  ```ruby
344
351
  @messages_api.send_template(sender_id: 12_345, recipient_number: 12345678, name: "hello_world", language: "en_US", components_json: [{...}])
345
352
  ```
353
+
354
+ **Send interactive messages**
355
+ Visit the [Official API Documentation](https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages#interactive-messages)
356
+
357
+ <details>
358
+ <summary>List Message's example</summary>
359
+
360
+ ```ruby
361
+ interactive_header = WhatsappSdk::Resource::InteractiveHeader.new(
362
+ type: WhatsappSdk::Resource::InteractiveHeader::Type::Text,
363
+ text: "I am the header!"
364
+ )
365
+
366
+ interactive_body = WhatsappSdk::Resource::InteractiveBody.new(
367
+ text: "I am the body!"
368
+ )
369
+
370
+ interactive_footer = WhatsappSdk::Resource::InteractiveFooter.new(
371
+ text: "I am the footer!"
372
+ )
373
+
374
+ interactive_action = WhatsappSdk::Resource::InteractiveAction.new(
375
+ type: WhatsappSdk::Resource::InteractiveAction::Type::ListMessage
376
+ )
377
+
378
+ interactive_action.button = "I am the button CTA"
379
+
380
+ interactive_section_1 = WhatsappSdk::Resource::InteractiveActionSection.new(
381
+ title: "I am the section 1"
382
+ )
383
+ interactive_section_1_row_1 = WhatsappSdk::Resource::InteractiveActionSectionRow.new(
384
+ title: "I am the row 1 title",
385
+ id: "section_1_row_1",
386
+ description: "I am the optional section 1 row 1 description"
387
+ )
388
+ interactive_section_1.add_row(interactive_section_1_row_1)
389
+ interactive_action.add_section(interactive_section_1)
390
+
391
+ interactive_list_messages = WhatsappSdk::Resource::Interactive.new(
392
+ type: WhatsappSdk::Resource::Interactive::Type::ListMessage,
393
+ header: interactive_header,
394
+ body: interactive_body,
395
+ footer: interactive_footer,
396
+ action: interactive_action
397
+ )
398
+
399
+ messages_api.send_interactive_list_messages(
400
+ sender_id: 12_345, recipient_number: 1234567890,
401
+ interactive: interactive_list_messages
402
+ )
403
+ ```
404
+ </details>
405
+
406
+ Alternative, you could pass a plain json like this:
407
+ ```ruby
408
+ messages_api.send_interactive_list_messages(
409
+ sender_id: 12_345, recipient_number: 1234567890
410
+ interactive_json: {...}
411
+ )
412
+ ```
413
+
414
+ <details>
415
+ <summary>Reply Button's example</summary>
416
+
417
+ ```ruby
418
+ interactive_header = WhatsappSdk::Resource::InteractiveHeader.new(
419
+ type: WhatsappSdk::Resource::InteractiveHeader::Type::Text,
420
+ text: "I am the header!"
421
+ )
422
+
423
+ interactive_body = WhatsappSdk::Resource::InteractiveBody.new(
424
+ text: "I am the body!"
425
+ )
426
+
427
+ interactive_footer = WhatsappSdk::Resource::InteractiveFooter.new(
428
+ text: "I am the footer!"
429
+ )
430
+
431
+ interactive_action = WhatsappSdk::Resource::InteractiveAction.new(
432
+ type: WhatsappSdk::Resource::InteractiveAction::Type::ReplyButton
433
+ )
434
+
435
+ interactive_reply_button_1 = WhatsappSdk::Resource::InteractiveActionReplyButton.new(
436
+ title: "I am the reply button 1",
437
+ id: "button_1"
438
+ )
439
+ interactive_action.add_reply_button(interactive_reply_button_1)
440
+
441
+ interactive_reply_button_2 = WhatsappSdk::Resource::InteractiveActionReplyButton.new(
442
+ title: "I am the reply button 2",
443
+ id: "button_2"
444
+ )
445
+ interactive_action.add_reply_button(interactive_reply_button_2)
446
+
447
+ interactive_reply_buttons = WhatsappSdk::Resource::Interactive.new(
448
+ type: WhatsappSdk::Resource::Interactive::Type::ReplyButton,
449
+ header: interactive_header,
450
+ body: interactive_body,
451
+ footer: interactive_footer,
452
+ action: interactive_action
453
+ )
454
+
455
+ messages_api.send_interactive_reply_buttons(
456
+ sender_id: 12_345, recipient_number: 1234567890,
457
+ interactive: interactive_reply_buttons
458
+ )
459
+ ```
346
460
  </details>
347
461
 
462
+ Alternative, you could pass a plain json like this:
463
+ ```ruby
464
+ messages_api.send_interactive_reply_buttons(
465
+ sender_id: 12_345, recipient_number: 1234567890
466
+ interactive_json: {...}
467
+ )
468
+ ```
469
+ </details>
470
+
471
+
348
472
  ## Examples
349
473
 
350
474
  Visit [the example file](/example.rb) with examples to call the API in a single file.
data/example.rb CHANGED
@@ -11,7 +11,7 @@ gemfile(true) do
11
11
 
12
12
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
13
13
 
14
- gem "whatsapp_sdk"
14
+ gem "whatsapp_sdk", path: "../"
15
15
  gem "pry"
16
16
  gem "pry-nav"
17
17
  end
@@ -22,11 +22,11 @@ require "pry-nav"
22
22
 
23
23
  ################# UPDATE CONSTANTS #################
24
24
 
25
- ACCESS_TOKEN = "<TODO replace>"
26
- SENDER_ID = "<TODO replace>"
27
- RECIPIENT_NUMBER = "<TODO replace>"
28
- BUSINESS_ID = "<TODO replace>"
29
- IMAGE_LINK = "<TODO replace>"
25
+ ACCESS_TOKEN = "EAAZAvvr0DZBs0BAIOsVV2FogD1qQhIyIrK9vfM7mmfdTlhbRqFZAZBnS2ciXPD35wb8d69siULaU5cqX9HonDNnZA9YLAbrCLUys1qt1E3n4d69v9RTZCoA8bkz9TZCV2PWzRR9DvBmwUOltCOrZBN0vGQxULlhsJE1mTeUrXlpVfFZCY5sWXCKxe04uyd7dzyK0hMgvkCR97OXi9AI3qJFYo"
26
+ SENDER_ID = 111591145018464
27
+ RECIPIENT_NUMBER = 13437772910
28
+ BUSINESS_ID = 102261539298487
29
+ IMAGE_LINK = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
30
30
 
31
31
  if ACCESS_TOKEN == "<TODO replace>"
32
32
  puts "\n\n**** Please update the ACCESS_TOKEN constant in this file. ****\n\n"
@@ -92,6 +92,11 @@ message_id = message_sent.data.messages.first.id
92
92
  messages_api.send_reaction(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message_id: message_id, emoji: "\u{1f550}")
93
93
  messages_api.send_reaction(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message_id: message_id, emoji: "⛄️")
94
94
 
95
+ ######### Reply to a message
96
+ message_to_reply_id = message_sent.data.messages.first.id
97
+ reply = messages_api.send_text(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message: "I'm a reply", message_id: message_to_reply_id)
98
+ print_message_sent(reply)
99
+
95
100
  ######### Send location
96
101
  location_sent = messages_api.send_location(
97
102
  sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER,
@@ -225,3 +230,47 @@ response_with_json = messages_api.send_template(
225
230
  ]
226
231
  )
227
232
  puts response_with_json
233
+
234
+ ######### SEND INTERACTIVE MESSAGES
235
+ ## with reply buttons
236
+ interactive_header = WhatsappSdk::Resource::InteractiveHeader.new(
237
+ type: WhatsappSdk::Resource::InteractiveHeader::Type::Text,
238
+ text: "I'm the header!"
239
+ )
240
+
241
+ interactive_body = WhatsappSdk::Resource::InteractiveBody.new(
242
+ text: "I'm the body!"
243
+ )
244
+
245
+ interactive_footer = WhatsappSdk::Resource::InteractiveFooter.new(
246
+ text: "I'm the footer!"
247
+ )
248
+
249
+ interactive_action = WhatsappSdk::Resource::InteractiveAction.new(
250
+ type: WhatsappSdk::Resource::InteractiveAction::Type::ReplyButton,
251
+ )
252
+
253
+ interactive_reply_button_1 = WhatsappSdk::Resource::InteractiveActionReplyButton.new(
254
+ title: "I'm a reply button 1",
255
+ id: "button_1"
256
+ )
257
+ interactive_action.add_reply_button(interactive_reply_button_1)
258
+
259
+ interactive_reply_button_2 = WhatsappSdk::Resource::InteractiveActionReplyButton.new(
260
+ title: "I'm a reply button 2",
261
+ id: "button_2"
262
+ )
263
+ interactive_action.add_reply_button(interactive_reply_button_2)
264
+
265
+ interactive_reply_buttons = WhatsappSdk::Resource::Interactive.new(
266
+ type: WhatsappSdk::Resource::Interactive::Type::ReplyButton,
267
+ header: interactive_header,
268
+ body: interactive_body,
269
+ footer: interactive_footer,
270
+ action: interactive_action
271
+ )
272
+
273
+ messages_api.send_interactive_reply_buttons(
274
+ sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER,
275
+ interactive: interactive_reply_buttons
276
+ )
@@ -3,7 +3,6 @@
3
3
 
4
4
  require "faraday"
5
5
  require "faraday/multipart"
6
- require "oj"
7
6
 
8
7
  module WhatsappSdk
9
8
  module Api
@@ -31,7 +30,9 @@ module WhatsappSdk
31
30
 
32
31
  response = faraday_request.public_send(http_method, endpoint, request_params(params, headers), headers)
33
32
 
34
- Oj.load(response.body)
33
+ return nil if response.body == ""
34
+
35
+ JSON.parse(response.body)
35
36
  end
36
37
 
37
38
  sig { params(url: String, path_to_file_name: T.nilable(String)).returns(Net::HTTPResponse) }
@@ -29,9 +29,15 @@ module WhatsappSdk
29
29
  # @param sender_id [Integer] Sender' phone number.
30
30
  # @param recipient_number [Integer] Recipient' Phone number.
31
31
  # @param message [String] Text to send.
32
+ # @param message_id [String] The id of the message to reply to.
32
33
  # @return [WhatsappSdk::Api::Response] Response object.
33
- sig { params(sender_id: Integer, recipient_number: Integer, message: String).returns(WhatsappSdk::Api::Response) }
34
- def send_text(sender_id:, recipient_number:, message:)
34
+ sig do
35
+ params(
36
+ sender_id: Integer, recipient_number: Integer, message: String,
37
+ message_id: T.nilable(String)
38
+ ).returns(WhatsappSdk::Api::Response)
39
+ end
40
+ def send_text(sender_id:, recipient_number:, message:, message_id: nil)
35
41
  params = {
36
42
  messaging_product: "whatsapp",
37
43
  to: recipient_number,
@@ -39,6 +45,7 @@ module WhatsappSdk
39
45
  type: "text",
40
46
  text: { body: message }
41
47
  }
48
+ params[:context] = { message_id: message_id } if message_id
42
49
 
43
50
  response = send_request(
44
51
  endpoint: endpoint(sender_id),
@@ -60,14 +67,18 @@ module WhatsappSdk
60
67
  # @param latitude [Float] Location latitude.
61
68
  # @param name [String] Location name.
62
69
  # @param address [String] Location address.
70
+ # @param message_id [String] The id of the message to reply to.
63
71
  # @return [WhatsappSdk::Api::Response] Response object.
64
72
  sig do
65
73
  params(
66
74
  sender_id: Integer, recipient_number: Integer,
67
- longitude: Float, latitude: Float, name: String, address: String
75
+ longitude: Float, latitude: Float, name: String, address: String,
76
+ message_id: T.nilable(String)
68
77
  ).returns(WhatsappSdk::Api::Response)
69
78
  end
70
- def send_location(sender_id:, recipient_number:, longitude:, latitude:, name:, address:)
79
+ def send_location(
80
+ sender_id:, recipient_number:, longitude:, latitude:, name:, address:, message_id: nil
81
+ )
71
82
  params = {
72
83
  messaging_product: "whatsapp",
73
84
  to: recipient_number,
@@ -80,6 +91,7 @@ module WhatsappSdk
80
91
  address: address
81
92
  }
82
93
  }
94
+ params[:context] = { message_id: message_id } if message_id
83
95
 
84
96
  response = send_request(
85
97
  endpoint: endpoint(sender_id),
@@ -100,14 +112,18 @@ module WhatsappSdk
100
112
  # @param image_id [String] Image ID.
101
113
  # @param link [String] Image link.
102
114
  # @param caption [String] Image caption.
115
+ # @param message_id [String] The id of the message to reply to.
103
116
  # @return [WhatsappSdk::Api::Response] Response object.
104
117
  sig do
105
118
  params(
106
119
  sender_id: Integer, recipient_number: Integer, image_id: T.nilable(String),
107
- link: T.nilable(String), caption: T.nilable(String)
120
+ link: T.nilable(String), caption: T.nilable(String),
121
+ message_id: T.nilable(String)
108
122
  ).returns(WhatsappSdk::Api::Response)
109
123
  end
110
- def send_image(sender_id:, recipient_number:, image_id: nil, link: nil, caption: "")
124
+ def send_image(
125
+ sender_id:, recipient_number:, image_id: nil, link: nil, caption: "", message_id: nil
126
+ )
111
127
  raise MissingArgumentError, "image_id or link is required" if !image_id && !link
112
128
 
113
129
  params = {
@@ -121,6 +137,7 @@ module WhatsappSdk
121
137
  else
122
138
  { id: image_id, caption: caption }
123
139
  end
140
+ params[:context] = { message_id: message_id } if message_id
124
141
 
125
142
  response = send_request(
126
143
  endpoint: endpoint(sender_id),
@@ -140,13 +157,15 @@ module WhatsappSdk
140
157
  # @param recipient_number [Integer] Recipient' Phone number.
141
158
  # @param audio_id [String] Audio ID.
142
159
  # @param link [String] Audio link.
160
+ # @param message_id [String] The id of the message to reply to.
143
161
  # @return [WhatsappSdk::Api::Response] Response object.
144
162
  sig do
145
163
  params(
146
- sender_id: Integer, recipient_number: Integer, audio_id: T.nilable(String), link: T.nilable(String)
164
+ sender_id: Integer, recipient_number: Integer, audio_id: T.nilable(String),
165
+ link: T.nilable(String), message_id: T.nilable(String)
147
166
  ).returns(WhatsappSdk::Api::Response)
148
167
  end
149
- def send_audio(sender_id:, recipient_number:, audio_id: nil, link: nil)
168
+ def send_audio(sender_id:, recipient_number:, audio_id: nil, link: nil, message_id: nil)
150
169
  raise MissingArgumentError, "audio_id or link is required" if !audio_id && !link
151
170
 
152
171
  params = {
@@ -156,6 +175,7 @@ module WhatsappSdk
156
175
  type: "audio"
157
176
  }
158
177
  params[:audio] = link ? { link: link } : { id: audio_id }
178
+ params[:context] = { message_id: message_id } if message_id
159
179
 
160
180
  response = send_request(
161
181
  endpoint: endpoint(sender_id),
@@ -176,14 +196,18 @@ module WhatsappSdk
176
196
  # @param video_id [String] Video ID.
177
197
  # @param link [String] Image link.
178
198
  # @param caption [String] Image caption.
199
+ # @param message_id [String] The id of the message to reply to.
179
200
  # @return [WhatsappSdk::Api::Response] Response object.
180
201
  sig do
181
202
  params(
182
203
  sender_id: Integer, recipient_number: Integer,
183
- video_id: T.nilable(String), link: T.nilable(String), caption: String
204
+ video_id: T.nilable(String), link: T.nilable(String), caption: String,
205
+ message_id: T.nilable(String)
184
206
  ).returns(WhatsappSdk::Api::Response)
185
207
  end
186
- def send_video(sender_id:, recipient_number:, video_id: nil, link: nil, caption: "")
208
+ def send_video(
209
+ sender_id:, recipient_number:, video_id: nil, link: nil, caption: "", message_id: nil
210
+ )
187
211
  raise MissingArgumentError, "video_id or link is required" if !video_id && !link
188
212
 
189
213
  params = {
@@ -197,6 +221,7 @@ module WhatsappSdk
197
221
  else
198
222
  { id: video_id, caption: caption }
199
223
  end
224
+ params[:context] = { message_id: message_id } if message_id
200
225
 
201
226
  response = send_request(
202
227
  endpoint: endpoint(sender_id),
@@ -217,14 +242,18 @@ module WhatsappSdk
217
242
  # @param document_id [String] document ID.
218
243
  # @param link [String] Image link.
219
244
  # @param caption [String] Image caption.
245
+ # @param message_id [String] The id of the message to reply to.
220
246
  # @return [WhatsappSdk::Api::Response] Response object.
221
247
  sig do
222
248
  params(
223
249
  sender_id: Integer, recipient_number: Integer,
224
- document_id: T.nilable(String), link: T.nilable(String), caption: String
250
+ document_id: T.nilable(String), link: T.nilable(String), caption: String,
251
+ message_id: T.nilable(String)
225
252
  ).returns(WhatsappSdk::Api::Response)
226
253
  end
227
- def send_document(sender_id:, recipient_number:, document_id: nil, link: nil, caption: "")
254
+ def send_document(
255
+ sender_id:, recipient_number:, document_id: nil, link: nil, caption: "", message_id: nil
256
+ )
228
257
  raise MissingArgumentError, "document or link is required" if !document_id && !link
229
258
 
230
259
  params = {
@@ -238,6 +267,7 @@ module WhatsappSdk
238
267
  else
239
268
  { id: document_id, caption: caption }
240
269
  end
270
+ params[:context] = { message_id: message_id } if message_id
241
271
 
242
272
  response = send_request(
243
273
  endpoint: endpoint(sender_id),
@@ -257,13 +287,15 @@ module WhatsappSdk
257
287
  # @param recipient_number [Integer] Recipient' Phone number.
258
288
  # @param sticker_id [String] The sticker ID.
259
289
  # @param link [String] Image link.
290
+ # @param message_id [String] The id of the message to reply to.
260
291
  # @return [WhatsappSdk::Api::Response] Response object.
261
292
  sig do
262
293
  params(
263
- sender_id: Integer, recipient_number: Integer, sticker_id: T.nilable(String), link: T.nilable(String)
294
+ sender_id: Integer, recipient_number: Integer, sticker_id: T.nilable(String),
295
+ link: T.nilable(String), message_id: T.nilable(String)
264
296
  ).returns(WhatsappSdk::Api::Response)
265
297
  end
266
- def send_sticker(sender_id:, recipient_number:, sticker_id: nil, link: nil)
298
+ def send_sticker(sender_id:, recipient_number:, sticker_id: nil, link: nil, message_id: nil)
267
299
  raise MissingArgumentError, "sticker or link is required" if !sticker_id && !link
268
300
 
269
301
  params = {
@@ -273,6 +305,7 @@ module WhatsappSdk
273
305
  type: Resource::Media::Type::Sticker
274
306
  }
275
307
  params[:sticker] = link ? { link: link } : { id: sticker_id }
308
+ params[:context] = { message_id: message_id } if message_id
276
309
 
277
310
  response = send_request(
278
311
  endpoint: endpoint(sender_id),
@@ -293,14 +326,18 @@ module WhatsappSdk
293
326
  # @param recipient_number [Integer] Recipient' Phone number.
294
327
  # @param contacts [Array<Contact>] Contacts.
295
328
  # @param contacts_json [Json] Contacts.
329
+ # @param message_id [String] The id of the message to reply to.
296
330
  # @return [WhatsappSdk::Api::Response] Response object.
297
331
  sig do
298
332
  params(
299
333
  sender_id: Integer, recipient_number: Integer,
300
- contacts: T.nilable(T::Array[WhatsappSdk::Resource::Contact]), contacts_json: T::Hash[T.untyped, T.untyped]
334
+ contacts: T.nilable(T::Array[WhatsappSdk::Resource::Contact]),
335
+ contacts_json: T::Hash[T.untyped, T.untyped], message_id: T.nilable(String)
301
336
  ).returns(WhatsappSdk::Api::Response)
302
337
  end
303
- def send_contacts(sender_id:, recipient_number:, contacts: nil, contacts_json: {})
338
+ def send_contacts(
339
+ sender_id:, recipient_number:, contacts: nil, contacts_json: {}, message_id: nil
340
+ )
304
341
  params = {
305
342
  messaging_product: "whatsapp",
306
343
  to: recipient_number,
@@ -308,6 +345,7 @@ module WhatsappSdk
308
345
  type: "contacts"
309
346
  }
310
347
  params[:contacts] = contacts ? contacts.map(&:to_h) : contacts_json
348
+ params[:context] = { message_id: message_id } if message_id
311
349
 
312
350
  response = send_request(
313
351
  endpoint: endpoint(sender_id),
@@ -325,13 +363,57 @@ module WhatsappSdk
325
363
  # # TODO: https://developers.facebook.com/docs/whatsapp_sdk/cloud-api/reference/messages#contacts-object
326
364
  # end
327
365
 
328
- # def send_interactive_reply_buttons
329
- # # TODO: https://developers.facebook.com/docs/whatsapp_sdk/cloud-api/reference/messages#contacts-object
330
- # end
366
+ # Send interactive reply buttons.
367
+ # https://developers.facebook.com/docs/whatsapp/guides/interactive-messages#reply-buttons
368
+ # You can either send interactive object or as JSON.
369
+ #
370
+ # @param sender_id [Integer] Sender' phone number.
371
+ # @param recipient_number [Integer] Recipient' Phone number.
372
+ # @param interactive [Interactive] Interactive.
373
+ # @param interactive_json [Json] The interactive object as a Json.
374
+ # If you pass interactive_json, you can't pass interactive.
375
+ # @param message_id [String] The id of the message to reply to.
376
+ # @return [WhatsappSdk::Api::Response] Response object.
377
+ sig do
378
+ params(
379
+ sender_id: Integer, recipient_number: Integer,
380
+ interactive: T.nilable(WhatsappSdk::Resource::Interactive),
381
+ interactive_json: T.nilable(T::Hash[T.untyped, T.untyped]), message_id: T.nilable(String)
382
+ ).returns(WhatsappSdk::Api::Response)
383
+ end
384
+ def send_interactive_message(
385
+ sender_id:, recipient_number:, interactive: nil, interactive_json: nil, message_id: nil
386
+ )
387
+ raise MissingArgumentError, "interactive or interactive_json is required" if !interactive && !interactive_json
331
388
 
332
- # def send_interactive_section
333
- # # TODO: https://developers.facebook.com/docs/whatsapp_sdk/cloud-api/reference/messages#contacts-object
334
- # end
389
+ params = {
390
+ messaging_product: "whatsapp",
391
+ to: recipient_number,
392
+ recipient_type: "individual",
393
+ type: "interactive"
394
+ }
395
+
396
+ params[:interactive] = if interactive.nil?
397
+ interactive_json
398
+ else
399
+ interactive.to_json
400
+ end
401
+ params[:context] = { message_id: message_id } if message_id
402
+
403
+ response = send_request(
404
+ endpoint: endpoint(sender_id),
405
+ params: params,
406
+ headers: DEFAULT_HEADERS
407
+ )
408
+
409
+ WhatsappSdk::Api::Response.new(
410
+ response: response,
411
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
412
+ )
413
+ end
414
+
415
+ alias :send_interactive_reply_buttons :send_interactive_message
416
+ alias :send_interactive_list_messages :send_interactive_message
335
417
 
336
418
  # Mark a message as read.
337
419
  #
@@ -374,7 +456,9 @@ module WhatsappSdk
374
456
  components_json: T.nilable(T::Array[T::Hash[T.untyped, T.untyped]])
375
457
  ).returns(WhatsappSdk::Api::Response)
376
458
  end
377
- def send_template(sender_id:, recipient_number:, name:, language:, components: nil, components_json: nil)
459
+ def send_template(
460
+ sender_id:, recipient_number:, name:, language:, components: nil, components_json: nil
461
+ )
378
462
  raise MissingArgumentError, "components or components_json is required" if !components && !components_json
379
463
 
380
464
  params = {
@@ -415,7 +499,8 @@ module WhatsappSdk
415
499
  # @return [WhatsappSdk::Api::Response] Response object.
416
500
  sig do
417
501
  params(
418
- sender_id: Integer, recipient_number: Integer, message_id: String, emoji: T.any(String, Integer)
502
+ sender_id: Integer, recipient_number: Integer, message_id: String,
503
+ emoji: T.any(String, Integer)
419
504
  ).returns(WhatsappSdk::Api::Response)
420
505
  end
421
506
  def send_reaction(sender_id:, recipient_number:, message_id:, emoji:)
@@ -0,0 +1,39 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module WhatsappSdk
5
+ module Resource
6
+ module Error
7
+ class MissingValue < WhatsappSdk::Error
8
+ extend T::Sig
9
+
10
+ sig { returns(String) }
11
+ attr_reader :field
12
+
13
+ sig { returns(String) }
14
+ attr_reader :message
15
+
16
+ sig { params(field: String, message: String).void }
17
+ def initialize(field, message)
18
+ @field = field
19
+ @message = message
20
+ super(message)
21
+ end
22
+ end
23
+
24
+ class InvalidField < MissingValue; end
25
+
26
+ class InvalidInteractiveBody < WhatsappSdk::Error; end
27
+
28
+ class InvalidInteractiveActionReplyButton < WhatsappSdk::Error; end
29
+
30
+ class InvalidInteractiveActionButton < WhatsappSdk::Error; end
31
+
32
+ class InvalidInteractiveActionSection < WhatsappSdk::Error; end
33
+
34
+ class InvalidInteractiveActionSectionRow < WhatsappSdk::Error; end
35
+
36
+ class InvalidInteractiveFooter < WhatsappSdk::Error; end
37
+ end
38
+ end
39
+ end