whatsapp_sdk 1.0.5 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +9 -8
- data/README.md +71 -0
- data/example.rb +22 -0
- data/lib/whatsapp_sdk/api/business_account.rb +59 -0
- data/lib/whatsapp_sdk/api/client.rb +16 -6
- data/lib/whatsapp_sdk/api/medias.rb +27 -0
- data/lib/whatsapp_sdk/api/messages.rb +56 -13
- data/lib/whatsapp_sdk/api/responses/generic_error_response.rb +4 -0
- data/lib/whatsapp_sdk/api/responses/message_data_response.rb +3 -1
- data/lib/whatsapp_sdk/api/templates.rb +56 -0
- data/lib/whatsapp_sdk/resource/business_account.rb +39 -0
- data/lib/whatsapp_sdk/resource/contact_response.rb +3 -2
- data/lib/whatsapp_sdk/resource/template_analytic.rb +54 -0
- data/lib/whatsapp_sdk/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6e1bc509c72a21009421ece7489cc79d178abec74db4445d84cf579fe374d5d3
|
|
4
|
+
data.tar.gz: b547704f8654b49e389547d27014089fdf1583583e57c6f567bf1193dbfc72aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f302ce6f5126585be265c8a0bdcc7c7681cd27e6838ce6c961a0b196eb66ba0cc3522c87407cbc69af7d95f8adeca02f7dbcf76ee646fddff49e3e50ba6c62b3
|
|
7
|
+
data.tar.gz: d7a97fa6bc6de65711c1d1698cd38863650dfc7f2dd0ef5ec743d2c938e15bca6511f6481c5fd72ee2972ec258466c9066817a9a3ea378f98c0d2db26a05e186
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# v 1.2.0
|
|
4
|
+
- Expose Graph media upload sessions through the configured client @oitedi [199](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/199)
|
|
5
|
+
- Support BSUID recipients and preserve user IDs in message responses @oitedi [198](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/198)
|
|
6
|
+
- Add voice message support to audio sends @oitedi [197](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/197)
|
|
7
|
+
- Guard `GenericErrorResponse.build_from_response` against non-Hash input @afonso-aguas [195](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/195)
|
|
8
|
+
- Fix false-positive `HttpResponseError` on bodies containing "error" substring @afonso-aguas [194](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/194)
|
|
9
|
+
|
|
10
|
+
# v 1.1.0
|
|
11
|
+
- Add support for pagination in template_analytics with 'after' cursor @osvaldo-santos [190](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/190)
|
|
12
|
+
- Add template_analytics feature @osvaldo-santos [189](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/189)
|
|
13
|
+
- Add Business Account API support @osvaldo-santos [187](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/187)
|
|
14
|
+
|
|
3
15
|
# v 1.0.5
|
|
4
16
|
- Added GET template endpoint. @osvaldo-santos [185](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/185)
|
|
5
17
|
- Adding support for named paremeters in Templates API. @osvaldo-santos [184](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/184)
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
whatsapp_sdk (1.0
|
|
4
|
+
whatsapp_sdk (1.2.0)
|
|
5
5
|
faraday (~> 2.0, > 2.0.1)
|
|
6
6
|
faraday-multipart (~> 1)
|
|
7
7
|
zeitwerk (~> 2)
|
|
@@ -9,14 +9,14 @@ PATH
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
addressable (2.
|
|
13
|
-
public_suffix (>= 2.0.2, <
|
|
12
|
+
addressable (2.9.0)
|
|
13
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
14
14
|
ast (2.4.2)
|
|
15
15
|
base64 (0.2.0)
|
|
16
16
|
coderay (1.1.3)
|
|
17
17
|
crack (0.4.5)
|
|
18
18
|
rexml
|
|
19
|
-
faraday (2.14.
|
|
19
|
+
faraday (2.14.1)
|
|
20
20
|
faraday-net_http (>= 2.0, < 3.5)
|
|
21
21
|
json
|
|
22
22
|
logger
|
|
@@ -25,10 +25,10 @@ GEM
|
|
|
25
25
|
faraday-net_http (3.4.2)
|
|
26
26
|
net-http (~> 0.5)
|
|
27
27
|
hashdiff (1.0.1)
|
|
28
|
-
json (2.
|
|
28
|
+
json (2.19.9)
|
|
29
29
|
logger (1.7.0)
|
|
30
30
|
method_source (1.0.0)
|
|
31
|
-
minitest (5.
|
|
31
|
+
minitest (5.27.0)
|
|
32
32
|
mocha (1.14.0)
|
|
33
33
|
multipart-post (2.4.1)
|
|
34
34
|
net-http (0.9.1)
|
|
@@ -41,7 +41,7 @@ GEM
|
|
|
41
41
|
method_source (~> 1.0)
|
|
42
42
|
pry-nav (1.0.0)
|
|
43
43
|
pry (>= 0.9.10, < 0.15)
|
|
44
|
-
public_suffix (5.
|
|
44
|
+
public_suffix (5.1.1)
|
|
45
45
|
rainbow (3.1.1)
|
|
46
46
|
rake (12.3.3)
|
|
47
47
|
regexp_parser (2.5.0)
|
|
@@ -71,13 +71,14 @@ GEM
|
|
|
71
71
|
addressable (>= 2.8.0)
|
|
72
72
|
crack (>= 0.3.2)
|
|
73
73
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
74
|
-
zeitwerk (2.7.
|
|
74
|
+
zeitwerk (2.7.5)
|
|
75
75
|
|
|
76
76
|
PLATFORMS
|
|
77
77
|
arm64-darwin-21
|
|
78
78
|
arm64-darwin-22
|
|
79
79
|
arm64-darwin-23
|
|
80
80
|
arm64-darwin-24
|
|
81
|
+
arm64-darwin-25
|
|
81
82
|
x86_64-darwin-19
|
|
82
83
|
x86_64-darwin-21
|
|
83
84
|
x86_64-linux
|
data/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Send stickers, messages, audio, videos, locations, react and reply to messages o
|
|
|
17
17
|
- [APIs](#apis)
|
|
18
18
|
- [Templates](#templates)
|
|
19
19
|
- [Business Profile API](#business-profile-api)
|
|
20
|
+
- [Business Account API](#business-account-api)
|
|
20
21
|
- [Phone numbers API](#phone-numbers-api)
|
|
21
22
|
- [Media API](#media-api)
|
|
22
23
|
- [Messages API](#messages-api)
|
|
@@ -207,6 +208,12 @@ client.templates.create(
|
|
|
207
208
|
|
|
208
209
|
# Delete a template
|
|
209
210
|
client.templates.delete(business_id: BUSINESS_ID, name: "my_name") # delete by name
|
|
211
|
+
|
|
212
|
+
# Get templates analytics
|
|
213
|
+
client.templates.template_analytics(
|
|
214
|
+
business_id: BUSINESS_ID, start_timestamp: 1767236400,
|
|
215
|
+
end_timestamp: 1767322799, template_ids: [id]
|
|
216
|
+
)
|
|
210
217
|
```
|
|
211
218
|
</details>
|
|
212
219
|
|
|
@@ -223,6 +230,22 @@ client.business_profiles.update(phone_number_id: SENDER_ID, params: { about: "A
|
|
|
223
230
|
```
|
|
224
231
|
</details>
|
|
225
232
|
|
|
233
|
+
### Business Account API
|
|
234
|
+
<details>
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
# Get the details of your business account
|
|
238
|
+
client.business_accounts.get(BUSINESS_ID)
|
|
239
|
+
|
|
240
|
+
# Get some fields of your business account
|
|
241
|
+
client.business_accounts.get(BUSINESS_ID, fields: ["id", "name"])
|
|
242
|
+
|
|
243
|
+
# Update your business account
|
|
244
|
+
# Note: You can only update the `name` and `timezone_id` fields of your business account.
|
|
245
|
+
client.business_accounts.update(business_id: BUSINESS_ID, params: { name: "My new business name", timezone_id: "1" })
|
|
246
|
+
```
|
|
247
|
+
</details>
|
|
248
|
+
|
|
226
249
|
### Phone numbers API
|
|
227
250
|
|
|
228
251
|
<details>
|
|
@@ -512,6 +535,54 @@ If the API response is still `success`, but the message is not delivered:
|
|
|
512
535
|
|
|
513
536
|
Note: Sometimes the messages are delayed; see [Meta documentation](https://developers.facebook.com/docs/whatsapp/on-premises/guides/send-message-performance#delays).
|
|
514
537
|
|
|
538
|
+
|
|
539
|
+
### Voice messages
|
|
540
|
+
|
|
541
|
+
Pass `voice: true` to `send_audio` with an uploaded `audio_id` or hosted `link`.
|
|
542
|
+
Voice messages require an Ogg file encoded with Opus; the SDK does not transcode media.
|
|
543
|
+
Omitting `voice` (or passing `false`) sends basic audio.
|
|
544
|
+
|
|
545
|
+
```ruby
|
|
546
|
+
client.messages.send_audio(sender_id: sender_id, recipient_number: recipient_number,
|
|
547
|
+
audio_id: media_id, voice: true)
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
See [Meta's audio message documentation](https://developers.facebook.com/documentation/business-messaging/whatsapp/messages/audio-messages/).
|
|
551
|
+
|
|
552
|
+
### Upload handles for templates and profile photos
|
|
553
|
+
|
|
554
|
+
Use Graph upload sessions when an endpoint requires a media handle instead of a WhatsApp media ID:
|
|
555
|
+
|
|
556
|
+
```ruby
|
|
557
|
+
session = client.media.create_upload_session(app_id: app_id, file_path: "header.png", type: "image/png")
|
|
558
|
+
upload = client.media.upload_file_to_session(session_id: session.fetch("id"), file_path: "header.png")
|
|
559
|
+
handle = upload.fetch("h")
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Both methods use the client's configured API version and token. An optional `access_token:`
|
|
563
|
+
overrides the token for that request only. They return the Graph response hashes and raise
|
|
564
|
+
`WhatsappSdk::Api::Responses::HttpResponseError` on Graph errors, like the other APIs.
|
|
565
|
+
Missing files or directories raise `WhatsappSdk::Api::Medias::FileNotFoundError`.
|
|
566
|
+
The upload reads the entire file into memory and starts at offset zero; automatic retries and
|
|
567
|
+
resuming interrupted uploads are not included.
|
|
568
|
+
See [Meta's upload guide](https://developers.facebook.com/docs/graph-api/guides/upload).
|
|
569
|
+
|
|
570
|
+
### Business-scoped user IDs (BSUIDs)
|
|
571
|
+
|
|
572
|
+
All message sends accept `recipient:` as an alternative to `recipient_number:`.
|
|
573
|
+
Use the complete BSUID (or parent BSUID), including its country prefix:
|
|
574
|
+
|
|
575
|
+
```ruby
|
|
576
|
+
response = client.messages.send_text(sender_id: sender_id, recipient: "US.123abc", message: "Hello")
|
|
577
|
+
response.contacts.first.user_id # => "US.123abc"
|
|
578
|
+
response.contacts.first.wa_id # => nil when Meta omits the phone number
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Phone numbers take precedence when both destinations are supplied. Missing or blank
|
|
582
|
+
selected destinations raise `WhatsappSdk::Resource::Errors::MissingArgumentError` before sending.
|
|
583
|
+
Authentication templates require a phone number; the SDK does not infer template category from its name or buttons.
|
|
584
|
+
See [Meta's BSUID documentation](https://developers.facebook.com/documentation/business-messaging/whatsapp/business-scoped-user-ids/).
|
|
585
|
+
|
|
515
586
|
## Development
|
|
516
587
|
|
|
517
588
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
|
data/example.rb
CHANGED
|
@@ -142,6 +142,12 @@ end
|
|
|
142
142
|
|
|
143
143
|
# client.templates.delete(business_id: BUSINESS_ID, name: "name2", hsm_id: "243213188351928") # delete by name and id
|
|
144
144
|
|
|
145
|
+
## Get template analytics
|
|
146
|
+
analytics = client.templates.template_analytics(
|
|
147
|
+
business_id: BUSINESS_ID, start_timestamp: 1767236400,
|
|
148
|
+
end_timestamp: 1767322799, template_ids: [id, new_template.id]
|
|
149
|
+
)
|
|
150
|
+
puts "GET template analytics: #{analytics.records.first}"
|
|
145
151
|
|
|
146
152
|
|
|
147
153
|
# ############################## Business API ##############################
|
|
@@ -158,6 +164,22 @@ run_and_catch_error("Update business profile") do
|
|
|
158
164
|
updated_bp = client.business_profiles.update(phone_number_id: SENDER_ID, params: { about: "A cool business" } )
|
|
159
165
|
end
|
|
160
166
|
|
|
167
|
+
# ############################## Business Account API ##############################
|
|
168
|
+
puts "\n\n\n ------------------ Testing Business Account API -----------------------"
|
|
169
|
+
|
|
170
|
+
business_account = client.business_accounts.get(BUSINESS_ID)
|
|
171
|
+
puts "GET Business Account by id: #{business_account.name}"
|
|
172
|
+
|
|
173
|
+
business_account = client.business_accounts.get(BUSINESS_ID, fields: %w[id name account_review_status message_template_namespace] )
|
|
174
|
+
puts "GET Business Account with fields by id: #{business_account.name}, #{business_account.account_review_status}, #{business_account.message_template_namespace}"
|
|
175
|
+
|
|
176
|
+
updated_ba = client.business_accounts.update(business_id: BUSINESS_ID, params: { name: 'A cool updated business' } )
|
|
177
|
+
puts "UPDATE Business Account by id: #{updated_ba} }"
|
|
178
|
+
|
|
179
|
+
run_and_catch_error("Update business account") do
|
|
180
|
+
# message_template_namespace can't be set
|
|
181
|
+
client.business_accounts.update(business_id: BUSINESS_ID, params: { message_template_namespace: "namespace" } )
|
|
182
|
+
end
|
|
161
183
|
|
|
162
184
|
|
|
163
185
|
############################## Phone Numbers API ##############################
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "request"
|
|
4
|
+
require_relative "../resource/business_account"
|
|
5
|
+
|
|
6
|
+
module WhatsappSdk
|
|
7
|
+
module Api
|
|
8
|
+
class BusinessAccount < Request
|
|
9
|
+
DEFAULT_FIELDS = %w[id name timezone_id message_template_namespace account_review_status
|
|
10
|
+
business_verification_status country ownership_type primary_business_location]
|
|
11
|
+
.join(',')
|
|
12
|
+
.freeze
|
|
13
|
+
|
|
14
|
+
# Get the details of business account.
|
|
15
|
+
#
|
|
16
|
+
# @param business_id [Integer] Business Account Id.
|
|
17
|
+
# @param fields [Array<String>] Optional list of fields to include in the response. Defaults to 'id,name'.
|
|
18
|
+
# @return [Resource::BusinessAccount] Response object.
|
|
19
|
+
def get(business_id, fields: nil)
|
|
20
|
+
fields = if fields
|
|
21
|
+
fields.join(',')
|
|
22
|
+
else
|
|
23
|
+
DEFAULT_FIELDS
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
response = send_request(
|
|
27
|
+
http_method: "get",
|
|
28
|
+
endpoint: "#{business_id}?fields=#{fields}"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
Resource::BusinessAccount.from_hash(response)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Update the details of business account.
|
|
35
|
+
#
|
|
36
|
+
# @param business_id [Integer] Business Account Id.
|
|
37
|
+
# @param params [Hash] Params to update. The possible attributes to update are: `name`, `timezone_id`.
|
|
38
|
+
# @return [Boolean] Whether the update was successful.
|
|
39
|
+
def update(business_id:, params:)
|
|
40
|
+
raise ArgumentError, "Params must be a hash." unless params.is_a?(Hash)
|
|
41
|
+
|
|
42
|
+
# Only name and timezone_id can be updated. If other keys are present, they will be ignored.
|
|
43
|
+
filtered_params = params.transform_keys(&:to_sym).slice(:name, :timezone_id)
|
|
44
|
+
|
|
45
|
+
if filtered_params.empty?
|
|
46
|
+
raise ArgumentError, "No valid parameters provided. Only 'name' and 'timezone_id' can be updated."
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
response = send_request(
|
|
50
|
+
http_method: "post",
|
|
51
|
+
endpoint: business_id.to_s,
|
|
52
|
+
params: filtered_params
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
Api::Responses::SuccessResponse.success_response?(response: response)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -7,7 +7,7 @@ module WhatsappSdk
|
|
|
7
7
|
module Api
|
|
8
8
|
class Client
|
|
9
9
|
API_VERSIONS = [
|
|
10
|
-
'v24.0', 'v23.0', 'v22.0', 'v21.0', 'v20.0', 'v19.0', 'v18.0', 'v17.0', 'v16.0', 'v15.0', 'v14.0',
|
|
10
|
+
'v25.0', 'v24.0', 'v23.0', 'v22.0', 'v21.0', 'v20.0', 'v19.0', 'v18.0', 'v17.0', 'v16.0', 'v15.0', 'v14.0',
|
|
11
11
|
'v13.0', 'v12.0', 'v11.0', 'v10.0', 'v9.0', 'v8.0', 'v7.0', 'v6.0', 'v5.0', 'v4.0',
|
|
12
12
|
'v3.3', 'v3.2', 'v3.1', 'v3.0', 'v2.12', 'v2.11', 'v2.10', 'v2.9', 'v2.8', 'v2.7',
|
|
13
13
|
'v2.6', 'v2.5', 'v2.4', 'v2.3', 'v2.2', 'v2.1'
|
|
@@ -43,6 +43,10 @@ module WhatsappSdk
|
|
|
43
43
|
@business_profiles ||= WhatsappSdk::Api::BusinessProfile.new(self)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
def business_accounts
|
|
47
|
+
@business_accounts ||= WhatsappSdk::Api::BusinessAccount.new(self)
|
|
48
|
+
end
|
|
49
|
+
|
|
46
50
|
def templates
|
|
47
51
|
@templates ||= WhatsappSdk::Api::Templates.new(self)
|
|
48
52
|
end
|
|
@@ -54,13 +58,13 @@ module WhatsappSdk
|
|
|
54
58
|
|
|
55
59
|
response = faraday_request.public_send(http_method, endpoint, request_params(params, headers), headers)
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
raise Api::Responses::HttpResponseError.new(http_status: response.status, body: JSON.parse(response.body))
|
|
59
|
-
end
|
|
61
|
+
parsed_body = parse_response_body(response.body)
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
if response.status > 499 || Api::Responses::GenericErrorResponse.response_error?(response: parsed_body)
|
|
64
|
+
raise Api::Responses::HttpResponseError.new(http_status: response.status, body: parsed_body)
|
|
65
|
+
end
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
parsed_body
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
def download_file(url:, content_type_header:, file_path: nil)
|
|
@@ -81,6 +85,12 @@ module WhatsappSdk
|
|
|
81
85
|
|
|
82
86
|
private
|
|
83
87
|
|
|
88
|
+
def parse_response_body(body)
|
|
89
|
+
return nil if body.nil? || body.empty?
|
|
90
|
+
|
|
91
|
+
JSON.parse(body)
|
|
92
|
+
end
|
|
93
|
+
|
|
84
94
|
def request_params(params, headers)
|
|
85
95
|
return params.to_json if params.is_a?(Hash) && headers['Content-Type'] == 'application/json'
|
|
86
96
|
|
|
@@ -117,6 +117,33 @@ module WhatsappSdk
|
|
|
117
117
|
Api::Responses::SuccessResponse.success_response?(response: response)
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
+
# Create a Graph upload session for template media or a business profile photo.
|
|
121
|
+
# Returns the raw response containing the upload session "id".
|
|
122
|
+
# Uses the client's API version and token unless access_token is supplied.
|
|
123
|
+
def create_upload_session(app_id:, file_path:, type:, access_token: nil)
|
|
124
|
+
raise FileNotFoundError.new(file_path: file_path) unless File.file?(file_path)
|
|
125
|
+
|
|
126
|
+
headers = { 'Content-Type' => 'application/json' }
|
|
127
|
+
headers['Authorization'] = "Bearer #{access_token}" if access_token
|
|
128
|
+
send_request(
|
|
129
|
+
endpoint: "./#{app_id}/uploads",
|
|
130
|
+
params: { file_name: File.basename(file_path), file_length: File.size(file_path), file_type: type },
|
|
131
|
+
headers: headers
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Upload the complete file to a Graph upload session, starting at offset zero.
|
|
136
|
+
# Returns the raw response containing the reusable media handle "h".
|
|
137
|
+
# This does not resume partial uploads or retry failed requests.
|
|
138
|
+
def upload_file_to_session(session_id:, file_path:, access_token: nil)
|
|
139
|
+
raise FileNotFoundError.new(file_path: file_path) unless File.file?(file_path)
|
|
140
|
+
|
|
141
|
+
headers = { 'Content-Type' => 'application/octet-stream', 'file_offset' => '0' }
|
|
142
|
+
headers['Authorization'] = "Bearer #{access_token}" if access_token
|
|
143
|
+
# ponytail: buffers the whole file; stream bytes if large uploads become a requirement.
|
|
144
|
+
send_request(endpoint: "./#{session_id}", params: File.binread(file_path), headers: headers)
|
|
145
|
+
end
|
|
146
|
+
|
|
120
147
|
private
|
|
121
148
|
|
|
122
149
|
def map_media_type_to_content_type_header(media_type)
|
|
@@ -13,8 +13,9 @@ module WhatsappSdk
|
|
|
13
13
|
# @param recipient_number [Integer] Recipient' Phone number.
|
|
14
14
|
# @param message [String] Text to send.
|
|
15
15
|
# @param message_id [String] The id of the message to reply to.
|
|
16
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
16
17
|
# @return [MessageDataResponse] Response object.
|
|
17
|
-
def send_text(sender_id:,
|
|
18
|
+
def send_text(sender_id:, message:, recipient_number: nil, message_id: nil, recipient: nil)
|
|
18
19
|
params = {
|
|
19
20
|
messaging_product: "whatsapp",
|
|
20
21
|
to: recipient_number,
|
|
@@ -23,6 +24,7 @@ module WhatsappSdk
|
|
|
23
24
|
text: { body: message }
|
|
24
25
|
}
|
|
25
26
|
params[:context] = { message_id: message_id } if message_id
|
|
27
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
26
28
|
|
|
27
29
|
response = send_request(
|
|
28
30
|
endpoint: endpoint(sender_id),
|
|
@@ -42,9 +44,10 @@ module WhatsappSdk
|
|
|
42
44
|
# @param name [String] Location name.
|
|
43
45
|
# @param address [String] Location address.
|
|
44
46
|
# @param message_id [String] The id of the message to reply to.
|
|
47
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
45
48
|
# @return [MessageDataResponse] Response object.
|
|
46
49
|
def send_location(
|
|
47
|
-
sender_id:,
|
|
50
|
+
sender_id:, longitude:, latitude:, name:, address:, recipient_number: nil, message_id: nil, recipient: nil
|
|
48
51
|
)
|
|
49
52
|
params = {
|
|
50
53
|
messaging_product: "whatsapp",
|
|
@@ -59,6 +62,7 @@ module WhatsappSdk
|
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
params[:context] = { message_id: message_id } if message_id
|
|
65
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
62
66
|
|
|
63
67
|
response = send_request(
|
|
64
68
|
endpoint: endpoint(sender_id),
|
|
@@ -77,9 +81,10 @@ module WhatsappSdk
|
|
|
77
81
|
# @param link [String] Image link.
|
|
78
82
|
# @param caption [String] Image caption.
|
|
79
83
|
# @param message_id [String] The id of the message to reply to.
|
|
84
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
80
85
|
# @return [MessageDataResponse] Response object.
|
|
81
86
|
def send_image(
|
|
82
|
-
sender_id:, recipient_number
|
|
87
|
+
sender_id:, recipient_number: nil, image_id: nil, link: nil, caption: "", message_id: nil, recipient: nil
|
|
83
88
|
)
|
|
84
89
|
raise Resource::Errors::MissingArgumentError, "image_id or link is required" if !image_id && !link
|
|
85
90
|
|
|
@@ -95,6 +100,7 @@ module WhatsappSdk
|
|
|
95
100
|
{ id: image_id, caption: caption }
|
|
96
101
|
end
|
|
97
102
|
params[:context] = { message_id: message_id } if message_id
|
|
103
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
98
104
|
|
|
99
105
|
response = send_request(
|
|
100
106
|
endpoint: endpoint(sender_id),
|
|
@@ -112,8 +118,12 @@ module WhatsappSdk
|
|
|
112
118
|
# @param audio_id [String] Audio ID.
|
|
113
119
|
# @param link [String] Audio link.
|
|
114
120
|
# @param message_id [String] The id of the message to reply to.
|
|
121
|
+
# @param voice [Boolean] Send an Ogg/Opus voice message instead of basic audio. Defaults to false.
|
|
122
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
115
123
|
# @return [MessageDataResponse] Response object.
|
|
116
|
-
def send_audio(
|
|
124
|
+
def send_audio(
|
|
125
|
+
sender_id:, recipient_number: nil, audio_id: nil, link: nil, message_id: nil, voice: false, recipient: nil
|
|
126
|
+
)
|
|
117
127
|
raise Resource::Errors::MissingArgumentError, "audio_id or link is required" if !audio_id && !link
|
|
118
128
|
|
|
119
129
|
params = {
|
|
@@ -122,8 +132,9 @@ module WhatsappSdk
|
|
|
122
132
|
recipient_type: "individual",
|
|
123
133
|
type: "audio"
|
|
124
134
|
}
|
|
125
|
-
params[:audio] = link ? { link: link } : { id: audio_id }
|
|
135
|
+
params[:audio] = link ? { link: link, voice: voice } : { id: audio_id, voice: voice }
|
|
126
136
|
params[:context] = { message_id: message_id } if message_id
|
|
137
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
127
138
|
|
|
128
139
|
response = send_request(
|
|
129
140
|
endpoint: endpoint(sender_id),
|
|
@@ -143,9 +154,10 @@ module WhatsappSdk
|
|
|
143
154
|
# @param link [String] Image link.
|
|
144
155
|
# @param caption [String] Image caption.
|
|
145
156
|
# @param message_id [String] The id of the message to reply to.
|
|
157
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
146
158
|
# @return [MessageDataResponse] Response object.
|
|
147
159
|
def send_video(
|
|
148
|
-
sender_id:, recipient_number
|
|
160
|
+
sender_id:, recipient_number: nil, video_id: nil, link: nil, caption: "", message_id: nil, recipient: nil
|
|
149
161
|
)
|
|
150
162
|
raise Resource::Errors::MissingArgumentError, "video_id or link is required" if !video_id && !link
|
|
151
163
|
|
|
@@ -161,6 +173,7 @@ module WhatsappSdk
|
|
|
161
173
|
{ id: video_id, caption: caption }
|
|
162
174
|
end
|
|
163
175
|
params[:context] = { message_id: message_id } if message_id
|
|
176
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
164
177
|
|
|
165
178
|
response = send_request(
|
|
166
179
|
endpoint: endpoint(sender_id),
|
|
@@ -179,9 +192,11 @@ module WhatsappSdk
|
|
|
179
192
|
# @param link [String] Image link.
|
|
180
193
|
# @param caption [String] Image caption.
|
|
181
194
|
# @param message_id [String] The id of the message to reply to.
|
|
195
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
182
196
|
# @return [MessageDataResponse] Response object.
|
|
183
197
|
def send_document(
|
|
184
|
-
sender_id:, recipient_number
|
|
198
|
+
sender_id:, recipient_number: nil, document_id: nil, link: nil, caption: "", message_id: nil,
|
|
199
|
+
filename: nil, recipient: nil
|
|
185
200
|
)
|
|
186
201
|
if !document_id && !link
|
|
187
202
|
raise Resource::Errors::MissingArgumentError,
|
|
@@ -201,6 +216,7 @@ module WhatsappSdk
|
|
|
201
216
|
end
|
|
202
217
|
params[:document] = params[:document].merge({ filename: filename }) if filename
|
|
203
218
|
params[:context] = { message_id: message_id } if message_id
|
|
219
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
204
220
|
|
|
205
221
|
response = send_request(
|
|
206
222
|
endpoint: endpoint(sender_id),
|
|
@@ -211,15 +227,16 @@ module WhatsappSdk
|
|
|
211
227
|
Api::Responses::MessageDataResponse.build_from_response(response: response)
|
|
212
228
|
end
|
|
213
229
|
|
|
214
|
-
# Send a
|
|
230
|
+
# Send a sticker.
|
|
215
231
|
#
|
|
216
232
|
# @param sender_id [Integer] Sender' phone number.
|
|
217
233
|
# @param recipient_number [Integer] Recipient' Phone number.
|
|
218
234
|
# @param sticker_id [String] The sticker ID.
|
|
219
235
|
# @param link [String] Image link.
|
|
220
236
|
# @param message_id [String] The id of the message to reply to.
|
|
237
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
221
238
|
# @return [MessageDataResponse] Response object.
|
|
222
|
-
def send_sticker(sender_id:, recipient_number
|
|
239
|
+
def send_sticker(sender_id:, recipient_number: nil, sticker_id: nil, link: nil, message_id: nil, recipient: nil)
|
|
223
240
|
raise Resource::Errors::MissingArgumentError, "sticker or link is required" if !sticker_id && !link
|
|
224
241
|
|
|
225
242
|
params = {
|
|
@@ -230,6 +247,7 @@ module WhatsappSdk
|
|
|
230
247
|
}
|
|
231
248
|
params[:sticker] = link ? { link: link } : { id: sticker_id }
|
|
232
249
|
params[:context] = { message_id: message_id } if message_id
|
|
250
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
233
251
|
|
|
234
252
|
response = send_request(
|
|
235
253
|
endpoint: endpoint(sender_id),
|
|
@@ -248,9 +266,10 @@ module WhatsappSdk
|
|
|
248
266
|
# @param contacts [Array<Contact>] Contacts.
|
|
249
267
|
# @param contacts_json [Json] Contacts.
|
|
250
268
|
# @param message_id [String] The id of the message to reply to.
|
|
269
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
251
270
|
# @return [MessageDataResponse] Response object.
|
|
252
271
|
def send_contacts(
|
|
253
|
-
sender_id:, recipient_number
|
|
272
|
+
sender_id:, recipient_number: nil, contacts: nil, contacts_json: {}, message_id: nil, recipient: nil
|
|
254
273
|
)
|
|
255
274
|
params = {
|
|
256
275
|
messaging_product: "whatsapp",
|
|
@@ -260,6 +279,7 @@ module WhatsappSdk
|
|
|
260
279
|
}
|
|
261
280
|
params[:contacts] = contacts ? contacts.map(&:to_h) : contacts_json
|
|
262
281
|
params[:context] = { message_id: message_id } if message_id
|
|
282
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
263
283
|
|
|
264
284
|
response = send_request(
|
|
265
285
|
endpoint: endpoint(sender_id),
|
|
@@ -284,9 +304,10 @@ module WhatsappSdk
|
|
|
284
304
|
# @param interactive_json [Json] The interactive object as a Json.
|
|
285
305
|
# If you pass interactive_json, you can't pass interactive.
|
|
286
306
|
# @param message_id [String] The id of the message to reply to.
|
|
307
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
287
308
|
# @return [MessageDataResponse] Response object.
|
|
288
309
|
def send_interactive_message(
|
|
289
|
-
sender_id:, recipient_number
|
|
310
|
+
sender_id:, recipient_number: nil, interactive: nil, interactive_json: nil, message_id: nil, recipient: nil
|
|
290
311
|
)
|
|
291
312
|
if !interactive && !interactive_json
|
|
292
313
|
raise Resource::Errors::MissingArgumentError,
|
|
@@ -306,6 +327,7 @@ module WhatsappSdk
|
|
|
306
327
|
interactive.to_json
|
|
307
328
|
end
|
|
308
329
|
params[:context] = { message_id: message_id } if message_id
|
|
330
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
309
331
|
|
|
310
332
|
response = send_request(
|
|
311
333
|
endpoint: endpoint(sender_id),
|
|
@@ -348,9 +370,11 @@ module WhatsappSdk
|
|
|
348
370
|
# @param language [String] template language.
|
|
349
371
|
# @param components [Component] Component.
|
|
350
372
|
# @param components_json [Json] The component as a Json. If you pass components_json, you can't pass components.
|
|
373
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
374
|
+
# Not allowed for authentication templates.
|
|
351
375
|
# @return [MessageDataResponse] Response object.
|
|
352
376
|
def send_template(
|
|
353
|
-
sender_id:,
|
|
377
|
+
sender_id:, name:, language:, recipient_number: nil, components: nil, components_json: nil, recipient: nil
|
|
354
378
|
)
|
|
355
379
|
if !components && !components_json
|
|
356
380
|
raise Resource::Errors::MissingArgumentError,
|
|
@@ -373,6 +397,7 @@ module WhatsappSdk
|
|
|
373
397
|
else
|
|
374
398
|
components.map(&:to_json)
|
|
375
399
|
end
|
|
400
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
376
401
|
|
|
377
402
|
response = send_request(
|
|
378
403
|
endpoint: endpoint(sender_id),
|
|
@@ -389,8 +414,9 @@ module WhatsappSdk
|
|
|
389
414
|
# @param recipient_number [Integer] Recipient' Phone number.
|
|
390
415
|
# @param message_id [String] the id of the message to reaction.
|
|
391
416
|
# @param emoji [String] unicode of the emoji to send.
|
|
417
|
+
# @param recipient [String] Recipient' Business-Scoped User ID (BSUID). Optional alternative to recipient_number.
|
|
392
418
|
# @return [MessageDataResponse] Response object.
|
|
393
|
-
def send_reaction(sender_id:,
|
|
419
|
+
def send_reaction(sender_id:, message_id:, emoji:, recipient_number: nil, recipient: nil)
|
|
394
420
|
params = {
|
|
395
421
|
messaging_product: "whatsapp",
|
|
396
422
|
recipient_type: "individual",
|
|
@@ -401,6 +427,7 @@ module WhatsappSdk
|
|
|
401
427
|
emoji: emoji
|
|
402
428
|
}
|
|
403
429
|
}
|
|
430
|
+
apply_recipient!(params, recipient_number, recipient)
|
|
404
431
|
|
|
405
432
|
response = send_request(
|
|
406
433
|
endpoint: endpoint(sender_id),
|
|
@@ -441,6 +468,22 @@ module WhatsappSdk
|
|
|
441
468
|
def endpoint(sender_id)
|
|
442
469
|
"#{sender_id}/messages"
|
|
443
470
|
end
|
|
471
|
+
|
|
472
|
+
# Applies the destination to the payload.
|
|
473
|
+
# - Phone send (recipient_number present): keeps `to`, never adds `recipient` — payload is
|
|
474
|
+
# identical to the pre-BSUID behavior.
|
|
475
|
+
# - BSUID send (recipient_number absent, recipient present): drops `to` and sets `recipient`
|
|
476
|
+
# (the field Meta uses to address a Business-Scoped User ID).
|
|
477
|
+
# Requires at least one destination.
|
|
478
|
+
def apply_recipient!(params, recipient_number, recipient)
|
|
479
|
+
if (recipient_number.nil? ? recipient : recipient_number).to_s.strip.empty?
|
|
480
|
+
raise Resource::Errors::MissingArgumentError, "recipient_number or recipient is required"
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
params.delete(:to) if recipient_number.nil?
|
|
484
|
+
params[:recipient] = recipient if recipient_number.nil? && recipient
|
|
485
|
+
params
|
|
486
|
+
end
|
|
444
487
|
end
|
|
445
488
|
end
|
|
446
489
|
end
|
|
@@ -16,10 +16,14 @@ module WhatsappSdk
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def self.response_error?(response:)
|
|
19
|
+
return false unless response.is_a?(Hash)
|
|
20
|
+
|
|
19
21
|
response["error"]
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
def self.build_from_response(response:)
|
|
25
|
+
return unless response.is_a?(Hash)
|
|
26
|
+
|
|
23
27
|
error_response = response["error"]
|
|
24
28
|
return unless error_response
|
|
25
29
|
|
|
@@ -27,7 +27,9 @@ module WhatsappSdk
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def parse_contact(contact_json)
|
|
30
|
-
Resource::ContactResponse.new(
|
|
30
|
+
Resource::ContactResponse.new(
|
|
31
|
+
input: contact_json["input"], wa_id: contact_json["wa_id"], user_id: contact_json["user_id"]
|
|
32
|
+
)
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
end
|
|
@@ -175,6 +175,50 @@ module WhatsappSdk
|
|
|
175
175
|
Api::Responses::SuccessResponse.success_response?(response: response)
|
|
176
176
|
end
|
|
177
177
|
|
|
178
|
+
# Get Template Analytics
|
|
179
|
+
#
|
|
180
|
+
# Get analytics data for message templates over a specified time range.
|
|
181
|
+
# @param business_id [Integer] The business ID.
|
|
182
|
+
# @param start_timestamp [Integer] The start of the time range to retrieve analytics data, in Unix timestamp.
|
|
183
|
+
# @param end_timestamp [Integer] The end of the time range to retrieve analytics data, in Unix timestamp.
|
|
184
|
+
# @param template_ids [Array<String>] An array of template IDs for which to retrieve analytics data.
|
|
185
|
+
# @param metric_types [Array<String>] An array of metric types to retrieve.
|
|
186
|
+
def template_analytics(
|
|
187
|
+
business_id:, start_timestamp:, end_timestamp:, template_ids:, metric_types: [],
|
|
188
|
+
granularity: WhatsappSdk::Resource::TemplateAnalytic::Granularity::DAILY,
|
|
189
|
+
after: nil
|
|
190
|
+
)
|
|
191
|
+
if !metric_types.empty? && !valid_metric_types?(metric_types)
|
|
192
|
+
valid_types = WhatsappSdk::Resource::TemplateAnalytic::MetricType::METRIC_TYPES.join(', ')
|
|
193
|
+
|
|
194
|
+
raise ArgumentError, "Invalid metric type. Valid types are: #{valid_types}."
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
if granularity != WhatsappSdk::Resource::TemplateAnalytic::Granularity::DAILY
|
|
198
|
+
raise ArgumentError, "Invalid granularity. The only supported granularity is DAILY."
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
query_params = {
|
|
202
|
+
start: start_timestamp,
|
|
203
|
+
end: end_timestamp,
|
|
204
|
+
template_ids: template_ids.join(","),
|
|
205
|
+
metric_types: metric_types.join(","),
|
|
206
|
+
granularity: granularity
|
|
207
|
+
}
|
|
208
|
+
query_params[:after] = after if after
|
|
209
|
+
|
|
210
|
+
response = send_request(
|
|
211
|
+
endpoint: "#{business_id}/template_analytics?#{URI.encode_www_form(query_params)}",
|
|
212
|
+
http_method: "get"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
Api::Responses::PaginationRecords.new(
|
|
216
|
+
records: parse_template_analytics(response['data']),
|
|
217
|
+
before: response.dig('paging', 'cursors', 'before'),
|
|
218
|
+
after: response.dig('paging', 'cursors', 'after')
|
|
219
|
+
)
|
|
220
|
+
end
|
|
221
|
+
|
|
178
222
|
private
|
|
179
223
|
|
|
180
224
|
def parse_templates(templates_data)
|
|
@@ -182,6 +226,18 @@ module WhatsappSdk
|
|
|
182
226
|
Resource::Template.from_hash(template)
|
|
183
227
|
end
|
|
184
228
|
end
|
|
229
|
+
|
|
230
|
+
def parse_template_analytics(analytics_data)
|
|
231
|
+
analytics_data.map do |analytic|
|
|
232
|
+
Resource::TemplateAnalytic.from_hash(analytic)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def valid_metric_types?(metric_types)
|
|
237
|
+
metric_types.all? do |type|
|
|
238
|
+
WhatsappSdk::Resource::TemplateAnalytic::MetricType.valid?(type)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
185
241
|
end
|
|
186
242
|
end
|
|
187
243
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module WhatsappSdk
|
|
4
|
+
module Resource
|
|
5
|
+
class BusinessAccount
|
|
6
|
+
attr_accessor :id, :name, :timezone_id, :message_template_namespace, :account_review_status,
|
|
7
|
+
:business_verification_status, :country, :ownership_type, :primary_business_location,
|
|
8
|
+
:analytics, :conversation_analytics, :pricing_analytics, :call_analytics
|
|
9
|
+
|
|
10
|
+
def self.from_hash(hash)
|
|
11
|
+
business_account = BusinessAccount.new
|
|
12
|
+
business_account.id = hash["id"]
|
|
13
|
+
business_account.name = hash["name"]
|
|
14
|
+
business_account.timezone_id = hash["timezone_id"]
|
|
15
|
+
business_account.message_template_namespace = hash["message_template_namespace"]
|
|
16
|
+
business_account.account_review_status = hash["account_review_status"]
|
|
17
|
+
business_account.business_verification_status = hash["business_verification_status"]
|
|
18
|
+
business_account.country = hash["country"]
|
|
19
|
+
business_account.ownership_type = hash["ownership_type"]
|
|
20
|
+
business_account.primary_business_location = hash["primary_business_location"]
|
|
21
|
+
business_account.analytics = hash["analytics"]
|
|
22
|
+
business_account.conversation_analytics = hash["conversation_analytics"]
|
|
23
|
+
business_account.pricing_analytics = hash["pricing_analytics"]
|
|
24
|
+
business_account.call_analytics = hash["call_analytics"]
|
|
25
|
+
|
|
26
|
+
business_account
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def ==(other)
|
|
30
|
+
return false unless other.is_a?(WhatsappSdk::Resource::BusinessAccount)
|
|
31
|
+
|
|
32
|
+
%i[id name timezone_id message_template_namespace account_review_status
|
|
33
|
+
business_verification_status country ownership_type primary_business_location].all? do |field|
|
|
34
|
+
send(field) == other.send(field)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
module WhatsappSdk
|
|
4
4
|
module Resource
|
|
5
5
|
class ContactResponse
|
|
6
|
-
attr_accessor :wa_id, :input
|
|
6
|
+
attr_accessor :wa_id, :input, :user_id
|
|
7
7
|
|
|
8
|
-
def initialize(input:, wa_id:)
|
|
8
|
+
def initialize(input:, wa_id: nil, user_id: nil)
|
|
9
9
|
@input = input
|
|
10
10
|
@wa_id = wa_id
|
|
11
|
+
@user_id = user_id
|
|
11
12
|
end
|
|
12
13
|
end
|
|
13
14
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module WhatsappSdk
|
|
4
|
+
module Resource
|
|
5
|
+
class TemplateAnalytic
|
|
6
|
+
module Granularity
|
|
7
|
+
DAILY = "DAILY"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module MetricType
|
|
11
|
+
COST = "COST"
|
|
12
|
+
CLICKED = "CLICKED"
|
|
13
|
+
DELIVERED = "DELIVERED"
|
|
14
|
+
READ = "READ"
|
|
15
|
+
SENT = "SENT"
|
|
16
|
+
|
|
17
|
+
# (MM API for WhatsApp only)
|
|
18
|
+
APP_ACTIVATIONS = "APP_ACTIVATIONS"
|
|
19
|
+
APP_ADD_TO_CART = "APP_ADD_TO_CART"
|
|
20
|
+
APP_CHECKOUTS_INITIATED = "APP_CHECKOUTS_INITIATED"
|
|
21
|
+
APP_PURCHASES = "APP_PURCHASES"
|
|
22
|
+
APP_PURCHASES_CONVERSION_VALUE = "APP_PURCHASES_CONVERSION_VALUE"
|
|
23
|
+
WEBSITE_ADD_TO_CART = "WEBSITE_ADD_TO_CART"
|
|
24
|
+
WEBSITE_CHECKOUTS_INITIATED = "WEBSITE_CHECKOUTS_INITIATED"
|
|
25
|
+
WEBSITE_PURCHASES = "WEBSITE_PURCHASES"
|
|
26
|
+
WEBSITE_PURCHASES_CONVERSION_VALUE = "WEBSITE_PURCHASES_CONVERSION_VALUE"
|
|
27
|
+
|
|
28
|
+
METRIC_TYPES = [COST, CLICKED, DELIVERED, READ, SENT, APP_ACTIVATIONS, APP_ADD_TO_CART, APP_CHECKOUTS_INITIATED,
|
|
29
|
+
APP_PURCHASES, APP_PURCHASES_CONVERSION_VALUE, WEBSITE_ADD_TO_CART, WEBSITE_CHECKOUTS_INITIATED,
|
|
30
|
+
WEBSITE_PURCHASES, WEBSITE_PURCHASES_CONVERSION_VALUE].freeze
|
|
31
|
+
|
|
32
|
+
def self.valid?(metric_type)
|
|
33
|
+
METRIC_TYPES.include?(metric_type)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
attr_accessor :granularity, :product_type, :data_points
|
|
38
|
+
|
|
39
|
+
def initialize(granularity:, product_type:, data_points:)
|
|
40
|
+
@granularity = granularity
|
|
41
|
+
@product_type = product_type
|
|
42
|
+
@data_points = data_points
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.from_hash(hash)
|
|
46
|
+
new(
|
|
47
|
+
granularity: hash["granularity"],
|
|
48
|
+
product_type: hash["product_type"],
|
|
49
|
+
data_points: hash["data_points"]
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/whatsapp_sdk/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: whatsapp_sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ignacio-chiazzo
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -134,6 +133,7 @@ files:
|
|
|
134
133
|
- example.rb
|
|
135
134
|
- lib/whatsapp_sdk.rb
|
|
136
135
|
- lib/whatsapp_sdk/api/api_configuration.rb
|
|
136
|
+
- lib/whatsapp_sdk/api/business_account.rb
|
|
137
137
|
- lib/whatsapp_sdk/api/business_profile.rb
|
|
138
138
|
- lib/whatsapp_sdk/api/client.rb
|
|
139
139
|
- lib/whatsapp_sdk/api/medias.rb
|
|
@@ -151,6 +151,7 @@ files:
|
|
|
151
151
|
- lib/whatsapp_sdk/error.rb
|
|
152
152
|
- lib/whatsapp_sdk/resource/address.rb
|
|
153
153
|
- lib/whatsapp_sdk/resource/address_type.rb
|
|
154
|
+
- lib/whatsapp_sdk/resource/business_account.rb
|
|
154
155
|
- lib/whatsapp_sdk/resource/business_profile.rb
|
|
155
156
|
- lib/whatsapp_sdk/resource/button_parameter.rb
|
|
156
157
|
- lib/whatsapp_sdk/resource/component.rb
|
|
@@ -181,6 +182,7 @@ files:
|
|
|
181
182
|
- lib/whatsapp_sdk/resource/phone_number.rb
|
|
182
183
|
- lib/whatsapp_sdk/resource/phone_number_component.rb
|
|
183
184
|
- lib/whatsapp_sdk/resource/template.rb
|
|
185
|
+
- lib/whatsapp_sdk/resource/template_analytic.rb
|
|
184
186
|
- lib/whatsapp_sdk/resource/url.rb
|
|
185
187
|
- lib/whatsapp_sdk/version.rb
|
|
186
188
|
- tmp/whatsapp.png
|
|
@@ -193,7 +195,6 @@ metadata:
|
|
|
193
195
|
source_code_uri: https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk
|
|
194
196
|
changelog_uri: https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/blob/main/CHANGELOG.md
|
|
195
197
|
rubygems_mfa_required: 'true'
|
|
196
|
-
post_install_message:
|
|
197
198
|
rdoc_options: []
|
|
198
199
|
require_paths:
|
|
199
200
|
- lib
|
|
@@ -208,8 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
208
209
|
- !ruby/object:Gem::Version
|
|
209
210
|
version: '0'
|
|
210
211
|
requirements: []
|
|
211
|
-
rubygems_version:
|
|
212
|
-
signing_key:
|
|
212
|
+
rubygems_version: 4.0.20
|
|
213
213
|
specification_version: 4
|
|
214
214
|
summary: Use the Ruby Whatsapp SDK to communicate with Whatsapp API using the Cloud
|
|
215
215
|
API
|