whatsapp_sdk 1.0.5 → 1.1.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: 17de6b59f97c39b0d49c911d4e153d241f60d7f92727a10ec895ff4dc4d9822b
4
- data.tar.gz: f2f25357ffa9d35972e157f57abfaa4a3ac2b2a9debb0f86fdb15230581c6ce6
3
+ metadata.gz: 5a1704465f5fbbe203905c5d63ac14944838fb6617ffb24f7ca6727dba2cdd49
4
+ data.tar.gz: 2359c3c077eab75ac9281a70134744eaf7703e765a4932ac6fa677287a143669
5
5
  SHA512:
6
- metadata.gz: 1ef8af8f454441f188633dab7295b20da476d8692af1bf6602032b7504c08d1931bc9fbb9544452f981b3b58111ed0bec034de6138540c3445d6379a50f813ac
7
- data.tar.gz: ead1a38b14a8d5d16539e61ba4b65c36c6652525ca10d7aab554dd3b83a8cd1b11fff52dc38e0c121f574db108ce3ea64546bf62a386b46078dfc369dd559710
6
+ metadata.gz: 067f3899b14284af61f426b1cf7f04d1e5fda2d3abb135a51bdac9fe1060427b270a2c4a2796855ed222c96a8794513377878b7bed56021bed2fe81eafc7c93c
7
+ data.tar.gz: 1789fd6e89f858e0a60996d462af11fcad70dfd48cf4bf6c76bacf736be725f3cf255b72d6cd731f959bf1715becac6a4fb4668f08c020e0004ae60aefda9db1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Unreleased
2
2
 
3
+ # v 1.1.0
4
+ - Add support for pagination in template_analytics with 'after' cursor @osvaldo-santos [190](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/190)
5
+ - Add template_analytics feature @osvaldo-santos [189](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/189)
6
+ - Add Business Account API support @osvaldo-santos [187](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/187)
7
+
3
8
  # v 1.0.5
4
9
  - Added GET template endpoint. @osvaldo-santos [185](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/185)
5
10
  - 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.5)
4
+ whatsapp_sdk (1.1.0)
5
5
  faraday (~> 2.0, > 2.0.1)
6
6
  faraday-multipart (~> 1)
7
7
  zeitwerk (~> 2)
@@ -16,7 +16,7 @@ GEM
16
16
  coderay (1.1.3)
17
17
  crack (0.4.5)
18
18
  rexml
19
- faraday (2.14.0)
19
+ faraday (2.14.1)
20
20
  faraday-net_http (>= 2.0, < 3.5)
21
21
  json
22
22
  logger
@@ -25,7 +25,7 @@ GEM
25
25
  faraday-net_http (3.4.2)
26
26
  net-http (~> 0.5)
27
27
  hashdiff (1.0.1)
28
- json (2.18.0)
28
+ json (2.18.1)
29
29
  logger (1.7.0)
30
30
  method_source (1.0.0)
31
31
  minitest (5.16.1)
@@ -71,7 +71,7 @@ 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.4)
74
+ zeitwerk (2.7.5)
75
75
 
76
76
  PLATFORMS
77
77
  arm64-darwin-21
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>
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
@@ -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
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WhatsappSdk
4
- VERSION = "1.0.5"
4
+ VERSION = "1.1.0"
5
5
  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: 1.0.5
4
+ version: 1.1.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: 2026-01-22 00:00:00.000000000 Z
11
+ date: 2026-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -134,6 +134,7 @@ files:
134
134
  - example.rb
135
135
  - lib/whatsapp_sdk.rb
136
136
  - lib/whatsapp_sdk/api/api_configuration.rb
137
+ - lib/whatsapp_sdk/api/business_account.rb
137
138
  - lib/whatsapp_sdk/api/business_profile.rb
138
139
  - lib/whatsapp_sdk/api/client.rb
139
140
  - lib/whatsapp_sdk/api/medias.rb
@@ -151,6 +152,7 @@ files:
151
152
  - lib/whatsapp_sdk/error.rb
152
153
  - lib/whatsapp_sdk/resource/address.rb
153
154
  - lib/whatsapp_sdk/resource/address_type.rb
155
+ - lib/whatsapp_sdk/resource/business_account.rb
154
156
  - lib/whatsapp_sdk/resource/business_profile.rb
155
157
  - lib/whatsapp_sdk/resource/button_parameter.rb
156
158
  - lib/whatsapp_sdk/resource/component.rb
@@ -181,6 +183,7 @@ files:
181
183
  - lib/whatsapp_sdk/resource/phone_number.rb
182
184
  - lib/whatsapp_sdk/resource/phone_number_component.rb
183
185
  - lib/whatsapp_sdk/resource/template.rb
186
+ - lib/whatsapp_sdk/resource/template_analytic.rb
184
187
  - lib/whatsapp_sdk/resource/url.rb
185
188
  - lib/whatsapp_sdk/version.rb
186
189
  - tmp/whatsapp.png