whatsapp_sdk 0.11.0 → 0.12.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: 3afc828e9c913c0aa1988b1ec75dcbd6453f13f67d46f3a25c77ef2558aacf8c
4
- data.tar.gz: 64d8ea9e6c36c6d37c8dad014ee1dab10d906df4dcb7777206f6fc7300af44b6
3
+ metadata.gz: 53c16bc6791e7862e5e35d1324792e0c0cea54a171e2f861f3e834ec3751e196
4
+ data.tar.gz: 610c042ac0cf2c095251c2bef1768776260a1d47e93898dd69c410609e6e722a
5
5
  SHA512:
6
- metadata.gz: 4c4e910413ddf8366abd12b1aaed78e8a47d69b1cc979f7afaae00fc644ff9f735f6c1f594749de242fc87c70f6c2c7c9ccf6c215c2e85bda40f0f6540fc3a55
7
- data.tar.gz: 5a2bac9b5b4f416af7abbfbdf07c91717b517f7c030fcb47c767c4d2863c538e2b03402ff3a0968b7a889b4748f3c5a14d1e4b75f1cbc75f238a1888d5cc78d1
6
+ metadata.gz: 8fdce7569dbb71b96744ee296feb1e90ee5c5300e82ce860550d0e1c3c4c9521ddc88c2ce7f5924c41f0559b17e7d301e9b81c1c0a78e881abc42bcae8102bd1
7
+ data.tar.gz: cab5e1753ee9ef35b05f7409ceb42af407cd6242dffa4a975a9f511bef417b05cc0cb221b7195508fcb53e7e912c9c5a24ff49eaa4c3df65cda199d16567a11e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Unreleased
2
2
 
3
+ # v 0.12.0
4
+ - Added ability to specify logger @chahmedejaz [#129](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/129)
5
+ - Allow download of unsupported media types @dvuckovic [#128](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/128)
6
+ - Allow users to specify the API version. @conr [#126](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/126)
7
+ - Use http multipart only when is needed. @ignacio-chiazzo [#123](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/123)
8
+ - Validate Vertical on BusinessProfile update API. @ignacio-chiazzo [#120](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/120)
9
+ - Added ability to specify fields param in the busines profile API. @ignacio-chiazzo [#119](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/119)
10
+
3
11
  # v 0.11.0
4
12
  - Bumped API version to v19. @paulomcnally https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/116
5
13
 
data/CONTRIBUTING.MD ADDED
@@ -0,0 +1,30 @@
1
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk) This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
2
+
3
+ If you want a feature implemented in the gem, please open an issue, and we will look as soon as we can.
4
+
5
+ Do you want to contribute and are unsure where to start? Ping me on Twitter, and I will help you!
6
+
7
+ ### Getting started
8
+
9
+ Clone the project and ensure tests are passing locally.
10
+
11
+ ```console
12
+ bundle install
13
+ bundle exec rake test
14
+ ```
15
+
16
+ #### Configure an App and enable WhatsApp
17
+
18
+ Follow the steps in the [Readme#set-up-a-meta-app](/README.md#set-up-a-meta-app)
19
+
20
+ #### Architecture
21
+
22
+ The main logic lives under `/lib`. There, you can find API classes (Medias, Messages, PhoneNumbers, etc.) and Resources (Button, Address, etc.).
23
+ Each API class inherits from `Request`, which contains the helper methods to make HTTP requests to Meta.
24
+
25
+ If you are new to the code, a good place to start is looking at [closed PRs](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pulls?q=is%3Apr+is%3Aclosed). Here are some helpful PRs:
26
+ - [Added a new Templates API](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/90)
27
+ - [Added an error when the user entered a bad input](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/89/files)
28
+ - [Change on Faraday configuration](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/123/files).
29
+
30
+ Do you want to contribute and are unsure where to start? Ping me on Twitter, and I will help you!
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- whatsapp_sdk (0.11.0)
4
+ whatsapp_sdk (0.12.0)
5
5
  faraday (~> 2)
6
6
  faraday-multipart (~> 1)
7
7
  sorbet-runtime (~> 0.5)
@@ -17,8 +17,7 @@ GEM
17
17
  coderay (1.1.3)
18
18
  crack (0.4.5)
19
19
  rexml
20
- diff-lcs (1.5.0)
21
- faraday (2.7.12)
20
+ faraday (2.8.1)
22
21
  base64
23
22
  faraday-net_http (>= 2.0, < 3.1)
24
23
  ruby2_keywords (>= 0.0.4)
@@ -29,8 +28,7 @@ GEM
29
28
  method_source (1.0.0)
30
29
  minitest (5.16.1)
31
30
  mocha (1.14.0)
32
- multipart-post (2.3.0)
33
- netrc (0.11.0)
31
+ multipart-post (2.4.0)
34
32
  parallel (1.22.1)
35
33
  parser (3.1.2.0)
36
34
  ast (~> 2.4.1)
@@ -42,11 +40,6 @@ GEM
42
40
  public_suffix (5.0.0)
43
41
  rainbow (3.1.1)
44
42
  rake (12.3.3)
45
- rbi (0.0.15)
46
- ast
47
- parser (>= 2.6.4.0)
48
- sorbet-runtime (>= 0.5.9204)
49
- unparser
50
43
  regexp_parser (2.5.0)
51
44
  rexml (3.2.5)
52
45
  rubocop (1.30.1)
@@ -75,39 +68,18 @@ GEM
75
68
  sorbet-static (0.5.10346-universal-darwin-19)
76
69
  sorbet-static (0.5.10346-universal-darwin-21)
77
70
  sorbet-static (0.5.10346-x86_64-linux)
78
- sorbet-static-and-runtime (0.5.10346)
79
- sorbet (= 0.5.10346)
80
- sorbet-runtime (= 0.5.10346)
81
71
  spoom (1.1.12)
82
72
  sorbet (>= 0.5.9204)
83
73
  sorbet-runtime (>= 0.5.9204)
84
74
  thor (>= 0.19.2)
85
- tapioca (0.9.4)
86
- bundler (>= 1.17.3)
87
- netrc (>= 0.11.0)
88
- parallel (>= 1.21.0)
89
- pry (>= 0.12.2)
90
- rbi (~> 0.0.0, >= 0.0.14)
91
- sorbet-static-and-runtime (>= 0.5.9204)
92
- spoom (~> 1.1.0, >= 1.1.11)
93
- thor (>= 1.2.0)
94
- yard-sorbet
75
+ tapioca (0.0.1)
95
76
  thor (1.2.1)
96
77
  unicode-display_width (2.2.0)
97
- unparser (0.6.5)
98
- diff-lcs (~> 1.3)
99
- parser (>= 3.1.0)
100
78
  webmock (3.18.1)
101
79
  addressable (>= 2.8.0)
102
80
  crack (>= 0.3.2)
103
81
  hashdiff (>= 0.4.0, < 2.0.0)
104
- webrick (1.7.0)
105
- yard (0.9.28)
106
- webrick (~> 1.7.0)
107
- yard-sorbet (0.7.0)
108
- sorbet-runtime (>= 0.5)
109
- yard (>= 0.9)
110
- zeitwerk (2.6.12)
82
+ zeitwerk (2.6.13)
111
83
 
112
84
  PLATFORMS
113
85
  arm64-darwin-21
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Ruby Whatsapp SDK
2
+
2
3
  [![Gem Version](https://badge.fury.io/rb/whatsapp_sdk.svg)](https://badge.fury.io/rb/whatsapp_sdk)
3
4
  [![CircleCI](https://circleci.com/gh/circleci/circleci-docs.svg?style=svg)](https://circleci.com/gh/ignacio-chiazzo/ruby_whatsapp_sdk)
4
5
  <a href="https://codeclimate.com/github/ignacio-chiazzo/ruby_whatsapp_sdk/maintainability"><img src="https://api.codeclimate.com/v1/badges/169cce95450272e4ad7d/maintainability" /></a>
@@ -6,7 +7,6 @@
6
7
  The SDK provides a set of operations and classes to use the Whatsapp API.
7
8
  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
9
 
9
-
10
10
  ## Demo
11
11
 
12
12
  https://user-images.githubusercontent.com/11672878/173238826-6fc0a6f8-d0ee-4eae-8947-7dfd3b8b3446.mov
@@ -35,21 +35,37 @@ There are three primary resources, `Messages`, `Media` and `PhoneNumbers`. `Mess
35
35
 
36
36
  To use `Messages`, `Media` or `PhoneNumbers`, you need to initialize the `Client` that contains auth information. There are two ways to do it.
37
37
 
38
- 1) Use an initializer
39
-
38
+ 1. Use an initializer
39
+
40
+ Note:
41
+ Optionally, you can specify the desired API version to use (defaults to the latest version if omitted).
42
+ Available API version can be found [here](https://developers.facebook.com/docs/graph-api/changelog/versions).
43
+
40
44
  ```ruby
41
45
  # config/initializers/whatsapp_sdk.rb
42
46
  WhatsappSdk.configure do |config|
43
47
  config.access_token = ACCESS_TOKEN
48
+ config.api_version = API_VERSION
49
+ config.logger = Logger.new(STDOUT) # optional, Faraday logger to attach
50
+ config.logger_options = { bodies: true } # optional, they are all valid logger_options for Faraday
44
51
  end
45
52
  ```
53
+ More Details on Faraday Logger Options are [here](https://lostisland.github.io/faraday/#/middleware/included/logging?id=logging).
54
+
46
55
  OR 2) Create a `Client` instance and pass it to the `Messages`, `Medias` or `PhoneNumbers` instance like this:
47
56
 
57
+ **Without Logger:**
48
58
  ```ruby
49
59
  client = WhatsappSdk::Api::Client.new("<ACCESS TOKEN>") # replace this with a valid access token
50
60
  messages_api = WhatsappSdk::Api::Messages.new(client)
51
61
  ```
52
-
62
+ **With Logger:**
63
+ ```ruby
64
+ logger = Logger.new(STDOUT)
65
+ logger_options = { bodies: true }
66
+ client = WhatsappSdk::Api::Client.new("<ACCESS TOKEN>", "<API VERSION>", logger, logger_options) # replace this with a valid access token
67
+ messages_api = WhatsappSdk::Api::Messages.new(client)
68
+ ```
53
69
  Each API operation returns a `WhatsappSdk::Api::Response` that contains `data` and `error` and a couple of helpful functions such as `ok?` and `error?`. There are three types of responses `WhatsappSdk::Api::MessageDataResponse`, `WhatsappSdk::Api::PhoneNumberDataResponse` and `WhatsappSdk::Api::PhoneNumbersDataResponse`. Each of them contains different attributes.
54
70
 
55
71
  ## Set up a Meta app
@@ -68,7 +84,7 @@ Each API operation returns a `WhatsappSdk::Api::Response` that contains `data` a
68
84
 
69
85
  Try sending a message to your phone in the UI.
70
86
 
71
- <details><summary>4) Copy the ACCESS_TOKEN, the SENDER_ID, the BUSINESS_ID and the RECEIPIENT_NUMBER</summary>
87
+ <details><summary>4) Copy the ACCESS_TOKEN, the SENDER_ID, the BUSINESS_ID and the RECIPIENT_NUMBER</summary>
72
88
  <img width="1010" alt="Screen Shot 2022-09-05 at 11 13 24 AM" src="https://user-images.githubusercontent.com/11672878/188480634-369f8de1-b851-4735-86de-f49e96f78d8c.png">
73
89
  </details>
74
90
 
@@ -76,11 +92,12 @@ Try sending a message to your phone in the UI.
76
92
 
77
93
  <details><summary>5) Use the GEM to interact with Whatsapp</summary>
78
94
 
79
- Example:
80
- 1) Install the gem by running `gem install whatsapp_sdk` in the gem.
81
- 2) Open the irb terminal by running `irb`
82
- 3) `require "whatsapp_sdk"`
83
- 4) Set up the `ACCESS_TOKEN`, the `SENDER_ID`, the `BUSINESS_ID` and the `RECEIPIENT_NUMBER` in variables.
95
+ Example:
96
+
97
+ 1. Install the gem by running `gem install whatsapp_sdk` in the gem.
98
+ 2. Open the irb terminal by running `irb`
99
+ 3. `require "whatsapp_sdk"`
100
+ 4. Set up the `ACCESS_TOKEN`, the `SENDER_ID`, the `BUSINESS_ID` and the `RECIPIENT_NUMBER` in variables.
84
101
 
85
102
  ```ruby
86
103
  ACCESS_TOKEN = "EAAZAvvr0DZBs0BABRLF8zohP5Epc6pyNu"
@@ -89,7 +106,7 @@ SENDER_ID = 1234567891011
89
106
  RECIPIENT_NUMBER = 12398765432
90
107
  ```
91
108
 
92
- 5) Configure the Client by running
109
+ 5. Configure the Client by running
93
110
 
94
111
  ```ruby
95
112
  WhatsappSdk.configure do |config|
@@ -97,15 +114,17 @@ WhatsappSdk.configure do |config|
97
114
  end
98
115
  ```
99
116
 
100
- 6) Try the Phone Numbers API or Messages API
117
+ 6. Try the Phone Numbers API or Messages API
101
118
 
102
119
  Phone Numbers API
120
+
103
121
  ```ruby
104
122
  phone_numbers_api = WhatsappSdk::Api::PhoneNumbers.new
105
123
  registered_number = phone_numbers_api.registered_number(SENDER_ID)
106
124
  ```
107
125
 
108
126
  Messages API
127
+
109
128
  ```ruby
110
129
  messages_api = WhatsappSdk::Api::Messages.new
111
130
  message_sent = messages_api.send_text(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER,
@@ -117,6 +136,7 @@ Check the [example.rb file](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk
117
136
  </details>
118
137
 
119
138
  ## Operations
139
+
120
140
  First, create the client and then create an instance `WhatsappSdk::Api::Messages` that requires a client as a param like this:
121
141
 
122
142
  ```ruby
@@ -132,6 +152,7 @@ Note: Remember to initialize the client first!
132
152
  ## APIs
133
153
 
134
154
  ### Templates
155
+
135
156
  <details>
136
157
 
137
158
  ```ruby
@@ -142,25 +163,30 @@ templates_api.templates(business_id: BUSINESS_ID)
142
163
  new_template = templates_api.create(
143
164
  business_id: BUSINESS_ID, name: "seasonal_promotion", language: "en_US", category: "MARKETING",
144
165
  components_json: components_json, allow_category_change: true
145
- )
166
+ )
146
167
 
147
168
  # Delete a template
148
169
  templates_api.delete(business_id: BUSINESS_ID, name: "my_name") # delete by name
149
170
  ```
171
+
150
172
  </details>
151
173
 
152
174
  ### Business Profile API
175
+
153
176
  <details>
154
177
 
155
178
  Get the details of your business
179
+
156
180
  ```ruby
157
181
  business_profile = business_profile_api.details(123456)
158
182
  ```
159
183
 
160
184
  Update the details of your business
185
+
161
186
  ```ruby
162
187
  business_profile_api.update(phone_number_id: SENDER_ID, params: { about: "A very cool business" } )
163
188
  ```
189
+
164
190
  </details>
165
191
 
166
192
  ### Phone numbers API
@@ -168,45 +194,55 @@ business_profile_api.update(phone_number_id: SENDER_ID, params: { about: "A very
168
194
  <details>
169
195
 
170
196
  Get the list of phone numbers registered
197
+
171
198
  ```ruby
172
199
  phone_numbers_api.registered_numbers(123456) # accepts a business_id
173
200
  ```
174
201
 
175
202
  Get the a phone number by id
203
+
176
204
  ```ruby
177
205
  phone_numbers_api.registered_numbers(123456) # accepts a phone_number_id
178
206
  ```
179
207
 
180
208
  Register a phone number
209
+
181
210
  ```ruby
182
211
  phone_numbers_api.register_number(phone_number_id, pin)
183
212
  ```
184
213
 
185
214
  Deregister a phone number
215
+
186
216
  ```ruby
187
217
  phone_numbers_api.deregister_number(phone_number_id)
188
218
  ```
219
+
189
220
  </details>
190
221
 
191
222
  ### Media API
223
+
192
224
  <details>
193
225
 
194
226
  Upload a media
227
+
195
228
  ```ruby
196
229
  medias_api.upload(sender_id: SENDER_ID, file_path: "tmp/whatsapp.png", type: "image/png")
197
230
  ```
198
231
 
199
232
  Get a media
233
+
200
234
  ```ruby
201
235
  media = medias_api.media(media_id: MEDIA_ID)
202
236
  ```
203
237
 
204
238
  Download media
239
+
205
240
  ```ruby
206
241
  medias_api.download(url: MEDIA_URL, file_path: 'tmp/downloaded_whatsapp.png', media_type: "image/png")
207
242
  ```
208
243
 
209
244
  Delete a media
245
+
210
246
  ```ruby
211
247
  medias_api.delete(media_id: MEDIA_ID)
212
248
  ```
@@ -214,6 +250,7 @@ medias_api.delete(media_id: MEDIA_ID)
214
250
  </details>
215
251
 
216
252
  ### Messages API
253
+
217
254
  <details>
218
255
 
219
256
  **Send a text message**
@@ -223,6 +260,7 @@ messages_api.send_text(sender_id: 1234, recipient_number: 112345678, message: "h
223
260
  ```
224
261
 
225
262
  **Read a message**
263
+
226
264
  ```ruby
227
265
  messages_api.read_message(sender_id: 1234, message_id: "wamid.HBgLMTM0M12345678910=")
228
266
  ```
@@ -230,7 +268,7 @@ messages_api.read_message(sender_id: 1234, message_id: "wamid.HBgLMTM0M123456789
230
268
  Note: To get the `message_id` you can set up [Webhooks](https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components) that will listen and fire an event when a message is received.
231
269
 
232
270
  **Send a reaction to message**
233
- To send a reaction to a message, you need to obtain the mssage id and look for the emoji's unicode you want to use.
271
+ To send a reaction to a message, you need to obtain the message id and look for the emoji's unicode you want to use.
234
272
 
235
273
  ```ruby
236
274
  messages_api.send_reaction(sender_id: 123_123, recipient_number: 56_789, message_id: "12345", emoji: "\u{1f550}")
@@ -256,6 +294,7 @@ messages_api.send_location(
256
294
 
257
295
  **Send an image message**
258
296
  It could use a link or an image_id.
297
+
259
298
  ```ruby
260
299
  # with a link
261
300
  messages_api.send_image(
@@ -270,6 +309,7 @@ messages_api.send_image(
270
309
 
271
310
  **Send an audio message**
272
311
  It could use a link or an audio_id.
312
+
273
313
  ```ruby
274
314
  # with a link
275
315
  messages_api.send_audio(sender_id: 123123, recipient_number: 56789, link: "audio_link")
@@ -280,6 +320,7 @@ messages_api.send_audio(sender_id: 123123, recipient_number: 56789, audio_id: "1
280
320
 
281
321
  **Send a document message**
282
322
  It could use a link or a document_id.
323
+
283
324
  ```ruby
284
325
  # with a link
285
326
  messages_api.send_document(
@@ -294,6 +335,7 @@ messages_api.send_document(
294
335
 
295
336
  **Send a sticker message**
296
337
  It could use a link or a sticker_id.
338
+
297
339
  ```ruby
298
340
  # with a link
299
341
  messages_api.send_sticker(sender_id: 123123, recipient_number: 56789, link: "link")
@@ -310,7 +352,8 @@ contacts = [create_contact(params)]
310
352
  messages_api.send_contacts(sender_id: 123123, recipient_number: 56789, contacts: contacts)
311
353
  ```
312
354
 
313
- Alernative, you could pass a plain json like this:
355
+ Alternatively, you could pass a plain json like this:
356
+
314
357
  ```ruby
315
358
  messages_api.send_contacts(sender_id: 123123, recipient_number: 56789, contacts_json: {...})
316
359
  ```
@@ -328,7 +371,7 @@ date_time = WhatsappSdk::Resource::DateTime.new(fallback_value: "2020-01-01T00:0
328
371
  image = WhatsappSdk::Resource::Media.new(type: "image", link: "http(s)://URL")
329
372
 
330
373
  parameter_image = WhatsappSdk::Resource::ParameterObject.new(type: WhatsappSdk::Resource::ParameterObject::Type::Image, image: image)
331
- # You can also use a plain string as type e.g.
374
+ # You can also use a plain string as type e.g.
332
375
  # parameter_image = WhatsappSdk::Resource::ParameterObject.new(type: "image", image: image)
333
376
  parameter_text = WhatsappSdk::Resource::ParameterObject.new(type: WhatsappSdk::Resource::ParameterObject::Type::Text, text: "TEXT_STRING")
334
377
  parameter_currency = WhatsappSdk::Resource::ParameterObject.new(type: WhatsappSdk::Resource::ParameterObject::Type::Currency, currency: currency)
@@ -366,7 +409,8 @@ button_component2 = WhatsappSdk::Resource::Component.new(
366
409
 
367
410
  </details>
368
411
 
369
- Alernative, you could pass a plain json like this:
412
+ Alternatively, you could pass a plain json like this:
413
+
370
414
  ```ruby
371
415
  @messages_api.send_template(sender_id: 12_345, recipient_number: 12345678, name: "hello_world", language: "en_US", components_json: [{...}])
372
416
  ```
@@ -421,9 +465,11 @@ messages_api.send_interactive_list_messages(
421
465
  interactive: interactive_list_messages
422
466
  )
423
467
  ```
468
+
424
469
  </details>
425
470
 
426
- Alternative, you could pass a plain json like this:
471
+ Alternatively, you could pass a plain json like this:
472
+
427
473
  ```ruby
428
474
  messages_api.send_interactive_list_messages(
429
475
  sender_id: 12_345, recipient_number: 1234567890
@@ -477,17 +523,19 @@ messages_api.send_interactive_reply_buttons(
477
523
  interactive: interactive_reply_buttons
478
524
  )
479
525
  ```
526
+
480
527
  </details>
481
528
 
482
529
  Alternative, you could pass a plain json like this:
530
+
483
531
  ```ruby
484
532
  messages_api.send_interactive_reply_buttons(
485
533
  sender_id: 12_345, recipient_number: 1234567890
486
534
  interactive_json: {...}
487
535
  )
488
536
  ```
489
- </details>
490
537
 
538
+ </details>
491
539
 
492
540
  ## Examples
493
541
 
@@ -500,11 +548,11 @@ Visit [the example file](/example.rb) with examples to call the API in a single
500
548
 
501
549
  ## Troubleshooting
502
550
 
503
- - If the API response is `success`, but the message is not delivered, ensure the device you're sending the message to is using a supported Whatsapp version. [Check documentation](https://developers.facebook.com/docs/whatsapp/cloud-api/support/troubleshooting#message-not-delivered). Try also replying a message to the number you are registered on your Whatsapp.
551
+ - If the API response is `success`, but the message is not delivered, ensure the device you're sending the message to is using a supported Whatsapp version. [Check documentation](https://developers.facebook.com/docs/whatsapp/cloud-api/support/troubleshooting#message-not-delivered). Try also replying a message to the number you are registered on your Whatsapp.
504
552
  - Ensure your Meta App uses an API version greater than or equal to `v.14`.
505
553
  - Ensure that the Panel in the Facebook dashboard doesn't display any errors.
506
554
 
507
- Note: Sometimes the messages are delayed; see [Meta documentation](https://developers.facebook.com/docs/whatsapp/on-premises/guides/send-message-performance#delays).
555
+ Note: Sometimes the messages are delayed; see [Meta documentation](https://developers.facebook.com/docs/whatsapp/on-premises/guides/send-message-performance#delays).
508
556
 
509
557
  ## Development
510
558
 
@@ -513,22 +561,23 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
513
561
  Run ' bundle exec rake install ' to install this gem onto your local machine. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
514
562
 
515
563
  ### Run all the tests
564
+
516
565
  - **Unit tests:** Run `rake test`
517
566
  - **Sorbet Typecheck:** run `srb tc`
518
567
  - **Linters:** `bundle exec rubocop`
519
568
 
520
-
521
569
  To update the Cloud API version update the version in `lib/whatsapp_sdk/api/api_configuration.rb`. Check the [Cloud API changelog for API udpates](https://developers.facebook.com/docs/whatsapp/business-platform/changelog#api-error-response-behavior).
522
570
 
523
571
  ## Contributing
524
572
 
525
573
  Bug reports and pull requests are welcome on GitHub at [https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk) This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
526
574
 
527
- If you want a feature to be implemented in the gem, please, open an issue and we will take a look as soon as we can.
528
-
575
+ If you want a feature to be implemented in the gem, please, open an issue and we will take a look as soon as we can.
529
576
 
530
577
  Do you want to contribute and are unsure where to start? Ping me on Twitter, and I will help you!
531
578
 
579
+ Check [Contributing](/CONTRIBUTING.MD) file.
580
+
532
581
  ## License
533
582
 
534
583
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,32 @@
1
+ - v19.0
2
+ - v18.0
3
+ - v17.0
4
+ - v16.0
5
+ - v15.0
6
+ - v14.0
7
+ - v13.0
8
+ - v12.0
9
+ - v11.0
10
+ - v10.0
11
+ - v9.0
12
+ - v8.0
13
+ - v7.0
14
+ - v6.0
15
+ - v5.0
16
+ - v4.0
17
+ - v3.3
18
+ - v3.2
19
+ - v3.1
20
+ - v3.0
21
+ - v2.12
22
+ - v2.11
23
+ - v2.10
24
+ - v2.9
25
+ - v2.8
26
+ - v2.7
27
+ - v2.6
28
+ - v2.5
29
+ - v2.4
30
+ - v2.3
31
+ - v2.2
32
+ - v2.1
data/example.rb CHANGED
@@ -33,6 +33,8 @@ if ACCESS_TOKEN == "<TODO replace>"
33
33
  exit
34
34
  end
35
35
 
36
+ puts "\n\n\n\n\n\n *************** Starting calling the Cloud API *************** \n"
37
+
36
38
  ################# Initialize Client #################
37
39
  WhatsappSdk.configure do |config|
38
40
  config.access_token = ACCESS_TOKEN
@@ -46,6 +48,14 @@ def print_message_sent(message_response)
46
48
  puts "Error: #{message_response.error&.to_s}"
47
49
  end
48
50
  end
51
+
52
+ def print_data_or_error(response, identifier)
53
+ if response.error?
54
+ return "Error: #{response.error&.to_s}"
55
+ end
56
+
57
+ return identifier
58
+ end
49
59
  ##################################################
50
60
 
51
61
 
@@ -56,12 +66,13 @@ business_profile_api = WhatsappSdk::Api::BusinessProfile.new
56
66
  templates_api = WhatsappSdk::Api::Templates.new
57
67
 
58
68
  ############################## Templates API ##############################
59
-
60
69
  ## Get list of templates
61
- templates_api.templates(business_id: BUSINESS_ID)
70
+ templates = templates_api.templates(business_id: BUSINESS_ID)
71
+ puts "GET Templates list : #{print_data_or_error(templates, templates.data&.templates.map { |r| r.template.name })}"
62
72
 
63
73
  ## Get message templates namespace
64
- templates_api.get_message_template_namespace(business_id: BUSINESS_ID)
74
+ template_namespace = templates_api.get_message_template_namespace(business_id: BUSINESS_ID)
75
+ puts "GET template by namespace: #{print_data_or_error(template_namespace, template_namespace.data&.id)}"
65
76
 
66
77
  # Create a template
67
78
  components_json = [
@@ -97,6 +108,7 @@ new_template = templates_api.create(
97
108
  business_id: BUSINESS_ID, name: "seasonal_promotion", language: "ka", category: "MARKETING",
98
109
  components_json: components_json, allow_category_change: true
99
110
  )
111
+ puts "GET template by namespace: #{print_data_or_error(template_namespace, template_namespace.data&.id)}"
100
112
 
101
113
  # Update a template
102
114
  components_json = [
@@ -112,66 +124,83 @@ components_json = [
112
124
  ]
113
125
  }
114
126
  ]
115
- templates_api.update(template_id: "1624560287967996", category: "UTILITY")
127
+ updated_template = templates_api.update(template_id: "1624560287967996", category: "UTILITY")
128
+ puts "UPDATE template by id: #{print_data_or_error(updated_template, updated_template.data&.id)}"
116
129
 
117
130
  ## Delete a template
118
- templates_api.delete(business_id: BUSINESS_ID, name: "seasonal_promotion") # delete by name
131
+ delete_template = templates_api.delete(business_id: BUSINESS_ID, name: "seasonal_promotion") # delete by name
132
+ puts "DELETE template by id: #{print_data_or_error(delete_template, delete_template.data&.id) }"
119
133
  # templates_api.delete(business_id: BUSINESS_ID, name: "name2", hsm_id: "243213188351928") # delete by name and id
120
134
 
121
135
  ############################## Business API ##############################
122
136
  business_profile = business_profile_api.details(SENDER_ID)
123
- business_profile_api.update(phone_number_id: SENDER_ID, params: { about: "A very cool business" } )
137
+ puts "DELETE Business Profile by id: #{print_data_or_error(delete_template, business_profile.data&.id) }"
138
+
139
+ updated_bp = business_profile_api.update(phone_number_id: SENDER_ID, params: { about: "A very cool business" } )
140
+ puts "UPDATE Business Profile by id: #{print_data_or_error(updated_bp, updated_bp.data&.id) }"
124
141
 
125
142
  ############################## Phone Numbers API ##############################
126
143
  registered_number = phone_numbers_api.registered_number(SENDER_ID)
144
+ puts "GET Registered number: #{print_data_or_error(registered_number, registered_number.data&.id)}"
145
+
127
146
  registered_numbers = phone_numbers_api.registered_numbers(BUSINESS_ID)
147
+ puts "GET Registered numbers: #{print_data_or_error(registered_number, registered_numbers.data&.phone_numbers.map(&:id))}"
128
148
 
129
149
  ############################## Media API ##############################
130
150
 
131
151
  ##### Image #####
132
152
  # upload a Image
133
153
  uploaded_media = medias_api.upload(sender_id: SENDER_ID, file_path: "tmp/whatsapp.png", type: "image/png")
134
- media_id = uploaded_media.data&.id
135
- puts "Uploaded media id: #{media_id}"
154
+ puts "Uploaded media id: #{print_data_or_error(uploaded_media, uploaded_media.data&.id)}"
136
155
 
137
156
  # get a media Image
138
- media = medias_api.media(media_id: media_id).data
139
- puts "Media info: #{media.raw_data_response}"
157
+ if uploaded_media.data&.id
158
+ media = medias_api.media(media_id: uploaded_media.data&.id)
159
+ puts "GET Media id: #{print_data_or_error(media, media.data&.id)}"
140
160
 
141
- # download media Image
142
- download_image = medias_api.download(url: media.url, file_path: 'tmp/downloaded_image.png', media_type: "image/png")
143
- puts "Downloaded: #{download_image.data.success?}"
161
+ # download media Image
162
+ download_image = medias_api.download(url: media.data.url, file_path: 'tmp/downloaded_image.png', media_type: "image/png")
163
+ puts "Downloaded: #{print_data_or_error(download_image, download_image.data.success?)}"
144
164
 
145
- # delete a media
146
- deleted_media = medias_api.delete(media_id: media&.id)
147
- puts "Deleted: #{deleted_media.data.success?}"
165
+ # delete a media
166
+ deleted_media = medias_api.delete(media_id: media.data.id)
167
+ puts "DELETE: #{print_data_or_error(deleted_media, deleted_media.data.success?)}"
168
+ end
148
169
 
149
170
  #### Audio ####
150
171
  # upload an audio
151
172
  uploaded_media = medias_api.upload(sender_id: SENDER_ID, file_path: "tmp/downloaded_audio.ogg", type: "audio/ogg")
173
+ puts "Uploaded media id: #{print_data_or_error(uploaded_media, uploaded_media.data&.id)}"
174
+
175
+ if uploaded_media.data&.id
176
+ media_id = uploaded_media.data&.id
152
177
  media_id = uploaded_media.data&.id
178
+ puts "Uploaded media id: #{media_id}"
179
+ media_id = uploaded_media.data&.id
153
180
  puts "Uploaded media id: #{media_id}"
154
181
 
155
- # get a media audio
156
- media = medias_api.media(media_id: media_id).data
157
- puts "Media info: #{media.raw_data_response}"
182
+ # get a media audio
183
+ media = medias_api.media(media_id: media_id)
184
+ puts "GET Media id: #{print_data_or_error(media, media.data&.id)}"
158
185
 
159
- # get a media audio
160
- audio_link = media.url
161
- download_image = medias_api.download(url: audio_link, file_path: 'tmp/downloaded_audio2.ogg', media_type: "audio/ogg")
162
- puts "Downloaded: #{download_image.data.success?}"
186
+ # get a media audio
187
+ audio_link = media.data.url
188
+ download_image = medias_api.download(url: audio_link, file_path: 'tmp/downloaded_audio2.ogg', media_type: "audio/ogg")
189
+ puts "Download Media Audio: #{print_data_or_error(download_image, download_image.data.success?)}"
190
+ end
163
191
 
164
192
  ############################## Messages API ##############################
165
193
 
166
194
  ######### SEND A TEXT MESSAGE
167
- message_sent = messages_api.send_text(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER,
168
- message: "Hey there! it's Whatsapp Ruby SDK")
195
+ message_sent = messages_api.send_text(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message: "Hey there! it's Whatsapp Ruby SDK")
169
196
  print_message_sent(message_sent)
170
197
 
171
198
  ######### React to a message
172
199
  message_id = message_sent.data.messages.first.id
173
- messages_api.send_reaction(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message_id: message_id, emoji: "\u{1f550}")
174
- messages_api.send_reaction(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message_id: message_id, emoji: "⛄️")
200
+ reaction_1_sent = messages_api.send_reaction(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message_id: message_id, emoji: "\u{1f550}")
201
+ reaction_2_sent = messages_api.send_reaction(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message_id: message_id, emoji: "⛄️")
202
+ puts "Message Reaction 1: #{print_data_or_error(reaction_1_sent, reaction_1_sent.data&.messages.first&.id)}"
203
+ puts "Message Reaction 2: #{print_data_or_error(reaction_2_sent, reaction_2_sent.data&.messages.first&.id)}"
175
204
 
176
205
  ######### Reply to a message
177
206
  message_to_reply_id = message_sent.data.messages.first.id
@@ -190,40 +219,49 @@ print_message_sent(location_sent)
190
219
 
191
220
  ######### SEND AN IMAGE
192
221
  # Send an image with a link
193
- image_sent = messages_api.send_image(
194
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: media.url, caption: "Ignacio Chiazzo Profile"
195
- )
196
- print_message_sent(image_sent)
197
-
198
- # Send an image with an id
199
- messages_api.send_image(
200
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, image_id: media.id, caption: "Ignacio Chiazzo Profile"
201
- )
222
+ if media.data&.id
223
+ image_sent = messages_api.send_image(
224
+ sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: media.data.url, caption: "Ignacio Chiazzo Profile"
225
+ )
226
+ print_message_sent(image_sent)
227
+
228
+ # Send an image with an id
229
+ messages_api.send_image(
230
+ sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, image_id: media.data.id, caption: "Ignacio Chiazzo Profile"
231
+ )
232
+ print_message_sent(image_sent)
233
+ end
202
234
 
203
235
  ######### SEND AUDIOS
204
236
  ## with a link
205
- messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "audio_link")
237
+ audio_sent = messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "audio_link")
238
+ print_message_sent(audio_sent)
206
239
 
207
240
  ## with an audio id
208
- messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, audio_id: "1234")
241
+ audio_sent = messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, audio_id: "1234")
242
+ print_message_sent(audio_sent)
209
243
 
210
244
  ######### SEND DOCUMENTS
211
245
  ## with a link
212
- messages_api.send_document(
246
+ document_sent = messages_api.send_document(
213
247
  sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "document_link", caption: "Ignacio Chiazzo"
214
248
  )
249
+ print_message_sent(document_sent)
215
250
 
216
251
  ## with a document id
217
- messages_api.send_document(
252
+ document_sent = messages_api.send_document(
218
253
  sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, document_id: "1234", caption: "Ignacio Chiazzo"
219
254
  )
255
+ print_message_sent(document_sent)
220
256
 
221
257
  ######### SEND STICKERS
222
258
  ## with a link
223
- messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "link")
259
+ sticker_sent = messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "link")
260
+ print_message_sent(sticker_sent)
224
261
 
225
262
  ## with a sticker_id
226
- messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, sticker_id: "1234")
263
+ sticker_sent = messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, sticker_id: "1234")
264
+ print_message_sent(sticker_sent)
227
265
 
228
266
  ######### SEND A TEMPLATE
229
267
  # Note: The template must have been created previously.
@@ -6,8 +6,8 @@ module WhatsappSdk
6
6
  module ApiConfiguration
7
7
  extend T::Sig
8
8
 
9
- API_VERSION = T.let("v19.0", String)
10
- API_URL = T.let("https://graph.facebook.com/#{API_VERSION}/", String)
9
+ DEFAULT_API_VERSION = T.let("v19.0", String)
10
+ API_URL = T.let("https://graph.facebook.com", String)
11
11
  end
12
12
  end
13
13
  end
@@ -3,21 +3,42 @@
3
3
 
4
4
  require_relative "request"
5
5
  require_relative "response"
6
+ require_relative "../resource/business_profile"
6
7
 
7
8
  module WhatsappSdk
8
9
  module Api
9
10
  class BusinessProfile < Request
10
11
  DEFAULT_FIELDS = 'about,address,description,email,profile_picture_url,websites,vertical'
11
12
 
13
+ class InvalidVertical < StandardError
14
+ extend T::Sig
15
+
16
+ sig { returns(String) }
17
+ attr_accessor :message
18
+
19
+ sig { params(vertical: String).void }
20
+ def initialize(vertical:)
21
+ @message = "invalid vertical #{vertical}. See the supported types in the official documentation " \
22
+ "https://developers.facebook.com/docs/whatsapp/cloud-api/reference/business-profiles"
23
+ super
24
+ end
25
+ end
26
+
12
27
  # Get the details of business profile.
13
28
  #
14
29
  # @param phone_number_id [Integer] Phone Number Id.
15
30
  # @return [Api::Response] Response object.
16
- sig { params(phone_number_id: Integer).returns(Api::Response) }
17
- def details(phone_number_id)
31
+ sig { params(phone_number_id: Integer, fields: T.nilable(T::Array[String])).returns(Api::Response) }
32
+ def details(phone_number_id, fields: nil)
33
+ fields = if fields
34
+ fields.join(',')
35
+ else
36
+ DEFAULT_FIELDS
37
+ end
38
+
18
39
  response = send_request(
19
40
  http_method: "get",
20
- endpoint: "#{phone_number_id}/whatsapp_business_profile?fields=#{DEFAULT_FIELDS}"
41
+ endpoint: "#{phone_number_id}/whatsapp_business_profile?fields=#{fields}"
21
42
  )
22
43
 
23
44
  Api::Response.new(
@@ -39,6 +60,7 @@ module WhatsappSdk
39
60
  def update(phone_number_id:, params:)
40
61
  # this is a required field
41
62
  params[:messaging_product] = 'whatsapp'
63
+ return raise InvalidVertical.new(vertical: params[:vertical]) unless valid_vertical?(params)
42
64
 
43
65
  response = send_request(
44
66
  http_method: "post",
@@ -51,6 +73,15 @@ module WhatsappSdk
51
73
  data_class_type: Api::Responses::SuccessResponse
52
74
  )
53
75
  end
76
+
77
+ private
78
+
79
+ sig { params(params: T::Hash[T.untyped, T.untyped]).returns(T::Boolean) }
80
+ def valid_vertical?(params)
81
+ return true unless params[:vertical]
82
+
83
+ WhatsappSdk::Resource::BusinessProfile::VERTICAL_VALUES.include?(params[:vertical])
84
+ end
54
85
  end
55
86
  end
56
87
  end
@@ -3,15 +3,35 @@
3
3
 
4
4
  require "faraday"
5
5
  require "faraday/multipart"
6
+ require "yaml"
6
7
 
7
8
  module WhatsappSdk
8
9
  module Api
9
10
  class Client
10
11
  extend T::Sig
11
12
 
12
- sig { params(access_token: String).void }
13
- def initialize(access_token)
13
+ API_VERSIONS = T.let(YAML.load_file("config/api_versions.yml"), T::Array[String])
14
+
15
+ sig do
16
+ params(
17
+ access_token: String,
18
+ api_version: String,
19
+ logger: T.nilable(T.any(Logger, T.class_of(Logger))),
20
+ logger_options: Hash
21
+ ).void
22
+ end
23
+ def initialize(
24
+ access_token,
25
+ api_version = ApiConfiguration::DEFAULT_API_VERSION,
26
+ logger = nil,
27
+ logger_options = {}
28
+ )
14
29
  @access_token = access_token
30
+ @logger = logger
31
+ @logger_options = logger_options
32
+
33
+ validate_api_version(api_version)
34
+ @api_version = api_version
15
35
  end
16
36
 
17
37
  sig do
@@ -20,13 +40,14 @@ module WhatsappSdk
20
40
  full_url: T.nilable(String),
21
41
  http_method: String,
22
42
  params: T::Hash[T.untyped, T.untyped],
23
- headers: T::Hash[T.untyped, T.untyped]
43
+ headers: T::Hash[T.untyped, T.untyped],
44
+ multipart: T::Boolean
24
45
  ).returns(T.nilable(T::Hash[T.untyped, T.untyped]))
25
46
  end
26
- def send_request(endpoint: "", full_url: nil, http_method: "post", params: {}, headers: {})
27
- url = full_url || ApiConfiguration::API_URL
47
+ def send_request(endpoint: "", full_url: nil, http_method: "post", params: {}, headers: {}, multipart: false)
48
+ url = full_url || "#{ApiConfiguration::API_URL}/#{@api_version}/"
28
49
 
29
- faraday_request = T.unsafe(faraday(url))
50
+ faraday_request = T.unsafe(faraday(url: url, multipart: multipart))
30
51
 
31
52
  response = faraday_request.public_send(http_method, endpoint, request_params(params, headers), headers)
32
53
 
@@ -69,15 +90,21 @@ module WhatsappSdk
69
90
  params
70
91
  end
71
92
 
72
- sig { params(url: String).returns(Faraday::Connection) }
73
- def faraday(url)
93
+ sig { params(url: String, multipart: T::Boolean).returns(Faraday::Connection) }
94
+ def faraday(url:, multipart: false)
74
95
  ::Faraday.new(url) do |client|
75
- client.request :multipart
76
- client.request :url_encoded
77
- client.adapter ::Faraday.default_adapter
96
+ client.request(:multipart) if multipart
97
+ client.request(:url_encoded)
98
+ client.adapter(::Faraday.default_adapter)
78
99
  client.headers['Authorization'] = "Bearer #{@access_token}" unless @access_token.nil?
100
+ client.response(:logger, @logger, @logger_options) unless @logger.nil?
79
101
  end
80
102
  end
103
+
104
+ sig { params(api_version: String).void }
105
+ def validate_api_version(api_version)
106
+ raise ArgumentError, "Invalid API version: #{api_version}" unless API_VERSIONS.include?(api_version)
107
+ end
81
108
  end
82
109
  end
83
110
  end
@@ -64,12 +64,15 @@ module WhatsappSdk
64
64
  #
65
65
  # @param url URL.
66
66
  # @param file_path [String] The file_path to download the media e.g. "tmp/downloaded_image.png".
67
- # @param media_type [String] The media type e.g. "audio/mp4". See the supported types in the official
68
- # documentation https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types.
67
+ # @param media_type [String] The media type e.g. "audio/mp4". See possible types in the official
68
+ # documentation https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types,
69
+ # but note that the API may allow more depending on the client.
69
70
  # @return [Api::Response] Response object.
70
71
  sig { params(url: String, file_path: String, media_type: String).returns(Api::Response) }
71
72
  def download(url:, file_path:, media_type:)
72
- raise InvalidMediaTypeError.new(media_type: media_type) unless valid_media_type?(media_type)
73
+ # Allow download of unsupported media types, since Cloud API may decide to let it through.
74
+ # https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/discussions/127
75
+ # raise InvalidMediaTypeError.new(media_type: media_type) unless valid_media_type?(media_type)
73
76
 
74
77
  content_type_header = map_media_type_to_content_type_header(media_type)
75
78
 
@@ -104,7 +107,7 @@ module WhatsappSdk
104
107
  type: type
105
108
  }
106
109
 
107
- response = send_request(http_method: "post", endpoint: "#{sender_id}/media", params: params)
110
+ response = send_request(http_method: "post", endpoint: "#{sender_id}/media", params: params, multipart: true)
108
111
 
109
112
  Api::Response.new(
110
113
  response: response,
@@ -167,7 +167,8 @@ module WhatsappSdk
167
167
  response = send_request(
168
168
  endpoint: endpoint(sender_id),
169
169
  params: params,
170
- headers: DEFAULT_HEADERS
170
+ headers: DEFAULT_HEADERS,
171
+ multipart: true
171
172
  )
172
173
 
173
174
  Api::Response.new(
@@ -14,9 +14,14 @@ module WhatsappSdk
14
14
  @client.download_file(url: url, content_type_header: content_type_header, file_path: file_path)
15
15
  end
16
16
 
17
- def send_request(endpoint: nil, full_url: nil, http_method: "post", params: {}, headers: {})
17
+ def send_request(endpoint: nil, full_url: nil, http_method: "post", params: {}, headers: {}, multipart: false)
18
18
  @client.send_request(
19
- http_method: http_method, full_url: full_url, endpoint: endpoint, params: params, headers: headers
19
+ http_method: http_method,
20
+ full_url: full_url,
21
+ endpoint: endpoint,
22
+ params: params,
23
+ headers: headers,
24
+ multipart: multipart
20
25
  )
21
26
  end
22
27
  end
@@ -5,23 +5,51 @@ module WhatsappSdk
5
5
  # This module allows client instantiating the client as a singleton like the following example:
6
6
  # WhatsappSdk.configure do |config|
7
7
  # config.access_token = ACCESS_TOKEN
8
+ # config.api_version = API_VERSION
8
9
  # end
9
10
  #
10
11
  # The gem have access to the client through WhatsappSdk.configuration.client
11
12
  class Configuration
12
13
  extend T::Sig
13
14
 
15
+ logger_or_subclass_or_nil = T.nilable(T.any(Logger, T.class_of(Logger)))
16
+
14
17
  sig { returns(String) }
15
18
  attr_accessor :access_token
16
19
 
17
- sig { params(access_token: String).void }
18
- def initialize(access_token = "")
20
+ sig { returns(String) }
21
+ attr_accessor :api_version
22
+
23
+ # loggers like ActiveSupport::Logger (Rails.logger) is a subclass of Logger
24
+ sig { returns(logger_or_subclass_or_nil) }
25
+ attr_accessor :logger
26
+
27
+ sig { returns(Hash) }
28
+ attr_accessor :logger_options
29
+
30
+ sig do
31
+ params(
32
+ access_token: String,
33
+ api_version: String,
34
+ logger: logger_or_subclass_or_nil,
35
+ logger_options: Hash
36
+ ).void
37
+ end
38
+ def initialize(
39
+ access_token = "",
40
+ api_version = Api::ApiConfiguration::DEFAULT_API_VERSION,
41
+ logger = nil,
42
+ logger_options = {}
43
+ )
19
44
  @access_token = access_token
45
+ @api_version = api_version
46
+ @logger = logger
47
+ @logger_options = logger_options
20
48
  end
21
49
 
22
50
  sig { returns(Api::Client) }
23
51
  def client
24
- Api::Client.new(access_token)
52
+ Api::Client.new(access_token, api_version, logger, logger_options)
25
53
  end
26
54
  end
27
55
  end
@@ -0,0 +1,15 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module WhatsappSdk
5
+ module Resource
6
+ class BusinessProfile
7
+ extend T::Sig
8
+
9
+ VERTICAL_VALUES = %w[
10
+ UNDEFINED OTHER AUTO BEAUTY APPAREL EDU ENTERTAIN EVENT_PLAN FINANCE GROCERY
11
+ GOVT HOTEL HEALTH NONPROFIT PROF_SERVICES RETAIL TRAVEL RESTAURANT NOT_A_BIZ
12
+ ].freeze
13
+ end
14
+ end
15
+ end
@@ -13,6 +13,8 @@ module WhatsappSdk
13
13
  # The content-type header matches with the media type using Internet Assigned Numbers Authority (IANA).
14
14
  # Media type list defined by IANA https://www.iana.org/assignments/media-types/media-types.xhtml
15
15
  #
16
+ # NOTE: Cloud API may decide to allow more media types to be downloaded, since the support differs depending on
17
+ # the used client.
16
18
 
17
19
  AUDIO_TYPES = %w[audio/aac audio/mp4 audio/mpeg audio/amr audio/ogg].freeze
18
20
  DOCUMENT_TYPES = %w[
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module WhatsappSdk
5
- VERSION = "0.11.0"
5
+ VERSION = "0.12.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whatsapp_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ignacio-chiazzo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-31 00:00:00.000000000 Z
11
+ date: 2024-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -142,6 +142,7 @@ files:
142
142
  - ".travis.yml"
143
143
  - CHANGELOG.md
144
144
  - CODE_OF_CONDUCT.md
145
+ - CONTRIBUTING.MD
145
146
  - Gemfile
146
147
  - Gemfile.lock
147
148
  - LICENSE.txt
@@ -150,6 +151,7 @@ files:
150
151
  - bin/console
151
152
  - bin/setup
152
153
  - bin/tapioca
154
+ - config/api_versions.yml
153
155
  - example.rb
154
156
  - lib/whatsapp_sdk.rb
155
157
  - lib/whatsapp_sdk/api/api_configuration.rb
@@ -179,6 +181,7 @@ files:
179
181
  - lib/whatsapp_sdk/error.rb
180
182
  - lib/whatsapp_sdk/resource/address.rb
181
183
  - lib/whatsapp_sdk/resource/address_type.rb
184
+ - lib/whatsapp_sdk/resource/business_profile.rb
182
185
  - lib/whatsapp_sdk/resource/button_parameter.rb
183
186
  - lib/whatsapp_sdk/resource/component.rb
184
187
  - lib/whatsapp_sdk/resource/contact.rb
@@ -249,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
252
  - !ruby/object:Gem::Version
250
253
  version: '0'
251
254
  requirements: []
252
- rubygems_version: 3.3.3
255
+ rubygems_version: 3.1.6
253
256
  signing_key:
254
257
  specification_version: 4
255
258
  summary: Use the Ruby Whatsapp SDK to communicate with Whatsapp API using the Cloud