whatsapp_sdk 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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