cloud-waba-ruby-client 0.0.1

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +9 -0
  3. data/.gitignore +2 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +2 -0
  6. data/Gemfile.lock +70 -0
  7. data/README.md +176 -0
  8. data/bin/console +30 -0
  9. data/cloud-waba-ruby-client.gemspec +24 -0
  10. data/lib/api/messages/service.rb +217 -0
  11. data/lib/api/templates/service.rb +108 -0
  12. data/lib/cloud_waba/client.rb +62 -0
  13. data/lib/cloud_waba/http_client.rb +53 -0
  14. data/lib/cloud_waba/models/config.rb +16 -0
  15. data/lib/cloud_waba/models/contact.rb +10 -0
  16. data/lib/cloud_waba/models/enums/contact_phone_type.rb +17 -0
  17. data/lib/cloud_waba/models/enums/messaging_product.rb +13 -0
  18. data/lib/cloud_waba/models/enums/templates/button_type.rb +19 -0
  19. data/lib/cloud_waba/models/enums/templates/category.rb +19 -0
  20. data/lib/cloud_waba/models/enums/templates/component_type.rb +20 -0
  21. data/lib/cloud_waba/models/enums/templates/format.rb +19 -0
  22. data/lib/cloud_waba/models/messages/contact.rb +76 -0
  23. data/lib/cloud_waba/models/messages/contact_name.rb +29 -0
  24. data/lib/cloud_waba/models/messages/contact_phone.rb +28 -0
  25. data/lib/cloud_waba/models/messages/response.rb +40 -0
  26. data/lib/cloud_waba/models/templates/body_component.rb +22 -0
  27. data/lib/cloud_waba/models/templates/button.rb +18 -0
  28. data/lib/cloud_waba/models/templates/buttons/copy_code.rb +15 -0
  29. data/lib/cloud_waba/models/templates/buttons/otp.rb +19 -0
  30. data/lib/cloud_waba/models/templates/buttons/phone_number.rb +16 -0
  31. data/lib/cloud_waba/models/templates/buttons/quick_reply.rb +15 -0
  32. data/lib/cloud_waba/models/templates/buttons/url.rb +17 -0
  33. data/lib/cloud_waba/models/templates/buttons_component.rb +13 -0
  34. data/lib/cloud_waba/models/templates/component.rb +19 -0
  35. data/lib/cloud_waba/models/templates/example.rb +12 -0
  36. data/lib/cloud_waba/models/templates/footer_component.rb +20 -0
  37. data/lib/cloud_waba/models/templates/header_location_component.rb +19 -0
  38. data/lib/cloud_waba/models/templates/header_media_component.rb +22 -0
  39. data/lib/cloud_waba/models/templates/header_text_component.rb +23 -0
  40. data/lib/cloud_waba/models/templates/list.rb +16 -0
  41. data/lib/cloud_waba/models/templates/message_template.rb +14 -0
  42. data/lib/cloud_waba/models/templates/response.rb +34 -0
  43. data/lib/cloud_waba/utils.rb +42 -0
  44. data/spec/cloud_waba_spec.rb +4 -0
  45. data/spec/spec_helper.rb +10 -0
  46. metadata +190 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8b05346a3973d5ce70286253be967af2a3957a89596f25413875dd49aeac108c
4
+ data.tar.gz: d18f9be6b156d2a653847285261547471de8c6669d9e8b6099a5ccd165f59bb7
5
+ SHA512:
6
+ metadata.gz: 493698b05d953833438948afb46209c02dec9eef058954708c4dc24fb7f2b0c6abd742582c8da349915ed011cc501f9cf1cf15f936180c3cab2a99e47c25230b
7
+ data.tar.gz: 9667f440fb7309e02f2bbd7f5a92e408f2a59dd8a8de29f62fb386a4456499b7c7a6233d51ea52b89ea37bb50b5cd40c425dafbf106f6aa2cc6d0a24ffc36fd7
data/.env.example ADDED
@@ -0,0 +1,9 @@
1
+ WA_BASE_URL=
2
+ M4D_APP_ID=
3
+ M4D_APP_SECRET=
4
+ WA_PHONE_NUMBER_ID=
5
+ WA_BUSINESS_ACCOUNT_ID=
6
+ CLOUD_API_ACCESS_TOKEN=
7
+ CLOUD_API_VERSION=v16.0
8
+ WEBHOOK_ENDPOINT=
9
+ WEBHOOK_VERIFICATION_TOKEN=
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .env
2
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cloud-waba-ruby-client (0.0.0)
5
+ dotenv (~> 2.8.0)
6
+ http (~> 4.0.0)
7
+ sorbet-runtime (~> 0.5.1)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.8.5)
13
+ public_suffix (>= 2.0.2, < 6.0)
14
+ byebug (9.1.0)
15
+ crack (0.4.5)
16
+ rexml
17
+ diff-lcs (1.5.0)
18
+ domain_name (0.5.20190701)
19
+ unf (>= 0.0.5, < 1.0.0)
20
+ dotenv (2.8.1)
21
+ hashdiff (1.0.1)
22
+ http (4.0.5)
23
+ addressable (~> 2.3)
24
+ http-cookie (~> 1.0)
25
+ http-form_data (~> 2.0)
26
+ http_parser.rb (~> 0.6.0)
27
+ http-cookie (1.0.5)
28
+ domain_name (~> 0.5)
29
+ http-form_data (2.3.0)
30
+ http_parser.rb (0.6.0)
31
+ public_suffix (4.0.7)
32
+ rexml (3.2.6)
33
+ rspec (3.4.0)
34
+ rspec-core (~> 3.4.0)
35
+ rspec-expectations (~> 3.4.0)
36
+ rspec-mocks (~> 3.4.0)
37
+ rspec-core (3.4.4)
38
+ rspec-support (~> 3.4.0)
39
+ rspec-expectations (3.4.0)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.4.0)
42
+ rspec-mocks (3.4.1)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.4.0)
45
+ rspec-support (3.4.1)
46
+ sorbet (0.5.10461)
47
+ sorbet-static (= 0.5.10461)
48
+ sorbet-runtime (0.5.10461)
49
+ sorbet-static (0.5.10461-universal-darwin-14)
50
+ unf (0.1.4)
51
+ unf_ext
52
+ unf_ext (0.0.8.2)
53
+ webmock (3.17.1)
54
+ addressable (>= 2.8.0)
55
+ crack (>= 0.3.2)
56
+ hashdiff (>= 0.4.0, < 2.0.0)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ byebug (~> 9.0, >= 9.0.5)
63
+ cloud-waba-ruby-client!
64
+ rspec (~> 3.4.0)
65
+ sorbet
66
+ sorbet-runtime
67
+ webmock (~> 3.17.0)
68
+
69
+ BUNDLED WITH
70
+ 2.1.4
data/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # cloud-waba-ruby-client
2
+
3
+ Ruby wrapper for [Cloud WhatsApp Business API](https://developers.facebook.com/docs/whatsapp/cloud-api).
4
+
5
+ ## Installation
6
+
7
+ Add following line to your Gemfile:
8
+
9
+ ```ruby
10
+ gem 'cloud-waba-ruby-client', '~> 0.0.0'
11
+ ```
12
+
13
+ then run
14
+
15
+ ```shell
16
+ bundle
17
+ ```
18
+
19
+ or install it yourself as:
20
+
21
+ ```shell
22
+ gem install cloud-waba-ruby-client
23
+ ```
24
+
25
+ ## Setup
26
+ 1. Make sure you have
27
+ - Meta business app
28
+ - WhatsApp Business account
29
+ - A phone number added to your WhatsApp business account
30
+ - Meta developer app
31
+ 2. Add following environment variables to your `.env` file:
32
+ ```shell
33
+ WA_BASE_URL=https://graph.facebook.com
34
+ CLOUD_API_VERSION=v16.0
35
+ M4D_APP_ID=
36
+ M4D_APP_SECRET=
37
+ WA_PHONE_NUMBER_ID=
38
+ WA_BUSINESS_ACCOUNT_ID=
39
+ CLOUD_API_ACCESS_TOKEN=
40
+ ```
41
+ Fill credentials for your meta developer app, business account and phone number ids.
42
+
43
+ ## Usage
44
+ ### Sending template message
45
+ ```ruby
46
+ require "cloud_waba/client"
47
+
48
+ client = CloudWaba::Client.new
49
+ client.messages.send_template(recipient: "+201XXXXXXXXX", template_name: "hello_world", template_lang: "en_US", components: [])
50
+ ```
51
+
52
+ ### Sending text message
53
+ ```ruby
54
+ require "cloud_waba/client"
55
+
56
+ client = CloudWaba::Client.new
57
+ client.messages.send_text(body: "Hello World!", recipient: "+201XXXXXXXXX")
58
+ ```
59
+
60
+ ### Sending image message
61
+ ```ruby
62
+ require "cloud_waba/client"
63
+
64
+ client = CloudWaba::Client.new
65
+ client.messages.send_image(caption: "Nice caption for image!", link: "https://picsum.photos/200/300",recipient: "+201XXXXXXXXX")
66
+ ```
67
+
68
+ ### Sending audio message
69
+ ```ruby
70
+ require "cloud_waba/client"
71
+
72
+ client = CloudWaba::Client.new
73
+ client.messages.send_audio(link: "https://samplelib.com/lib/preview/mp3/sample-3s.mp3",recipient: "+201XXXXXXXXX")
74
+ ```
75
+
76
+ ### Sending video message
77
+ ```ruby
78
+ require "cloud_waba/client"
79
+
80
+ client = CloudWaba::Client.new
81
+ client.messages.send_video(caption: "Nice caption for video!", link: "https://samplelib.com/lib/preview/mp4/sample-5s.mp4",recipient: "+201XXXXXXXXX")
82
+ ```
83
+
84
+ ### Sending document message
85
+ ```ruby
86
+ require "cloud_waba/client"
87
+
88
+ client = CloudWaba::Client.new
89
+ client.messages.send_document(caption: "Nice caption for doc!", link: "https://download.samplelib.com/xls/sample-empty.xls",recipient: "+201XXXXXXXXX")
90
+ ```
91
+
92
+ ### Sending location message
93
+ ```ruby
94
+ require "cloud_waba/client"
95
+
96
+ client = CloudWaba::Client.new
97
+ client.messages.send_location(longitude: 30.0849643, latitude: 31.2913638, name: "Cairo University", address: "1 شارع الجامعة, Giza Governorate 12613", recipient: "+201XXXXXXXXX")
98
+ ```
99
+
100
+ ### Sending contact message
101
+ ```ruby
102
+ require "cloud_waba/client"
103
+
104
+ client = CloudWaba::Client.new
105
+ name = ::CloudWaba::Models::Messages::ContactName.new(formatted_name: "Ahmed Ali", first_name: "Ashley")
106
+ phone_1 = ::CloudWaba::Models::Messages::ContactPhone.new(type: ::CloudWaba::Models::Enums::ContactPhoneType::Cell, phone: "+201XXXXXXXXX")
107
+ contacts = [::CloudWaba::Models::Messages::Contact.new(name: name, phones: [phone_1])]
108
+ client.messages.send_contact(contacts: contacts,recipient: "+201XXXXXXXXX")
109
+ ```
110
+ <!-- ### Sending template with header, body, footer and buttons
111
+
112
+ ### Sending template with header, body, footer and buttons (variables)
113
+ -->
114
+
115
+
116
+
117
+
118
+ ### Listing templates
119
+ ```ruby
120
+ require "cloud_waba/client"
121
+ client = CloudWaba::Client.new
122
+ client.templates.list(limit: 5)
123
+ ```
124
+ ### Creating a template
125
+ ```ruby
126
+ require "cloud_waba/client"
127
+
128
+ client = CloudWaba::Client.new
129
+ client.templates.create(name: "welcome", category: ::CloudWaba::Models::Enums::Templates::Category::Utility, language: "en", components: [::CloudWaba::Models::Templates::BodyComponent.new(text: "Welcome to our store!, how can we help?")])
130
+ ```
131
+
132
+ ### Creating a template with header, body and footer components with variables
133
+ ```ruby
134
+ require "cloud_waba/client"
135
+
136
+ client = CloudWaba::Client.new
137
+ category = ::CloudWaba::Models::Enums::Templates::Category::Marketing
138
+ language = "en"
139
+
140
+ header_text = "Hi {{1}}!"
141
+ header_example = ::CloudWaba::Models::Templates::Example.new(values: ["ahmed"])
142
+ header_component = ::CloudWaba::Models::Templates::HeaderTextComponent.new(text: header_text, example: header_example)
143
+
144
+ body_text = "We offer {{1}} discount!"
145
+ body_example = ::CloudWaba::Models::Templates::Example.new(values: ["20%"])
146
+ body_component = ::CloudWaba::Models::Templates::BodyComponent.new(text: body_text, example: body_example)
147
+
148
+ footer_text = "Petitux Team"
149
+ footer_component = ::CloudWaba::Models::Templates::FooterComponent.new(text: footer_text)
150
+
151
+ client.templates.create(name: "discount", category: category, language: language, components: [header_component, body_component, footer_component])
152
+ ```
153
+
154
+ ### Update Template
155
+ ```ruby
156
+ client = CloudWaba::Client.new
157
+
158
+ category = ::CloudWaba::Models::Enums::Templates::Category::Utility
159
+ body_text = "Your order no. {{1}} has been placed!"
160
+ body_example = ::CloudWaba::Models::Templates::Example.new(values: ["500"])
161
+ body_component = ::CloudWaba::Models::Templates::BodyComponent.new(text: body_text, example: body_example)
162
+
163
+ client.templates.update(template_id: "1027873614915405", category: category, components: [body_component])
164
+ ```
165
+
166
+ ### Delete Template
167
+ ```ruby
168
+ client = CloudWaba::Client.new
169
+ client.templates.delete(name: "discount")
170
+ ```
171
+
172
+ <!-- ### Creating a template with header, body, footer and buttons
173
+
174
+ ### Sending template with header, body, footer and buttons
175
+
176
+ ### Sending template with header, body, footer and buttons (variables) -->
data/bin/console ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "dotenv/load"
5
+ require "cloud_waba/client"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+
16
+ def reload!(print = true)
17
+ puts 'Reloading ...' if print
18
+ # Main project directory.
19
+ root_dir = File.expand_path('..', __dir__)
20
+ # Directories within the project that should be reloaded.
21
+ reload_dirs = %w{lib}
22
+ # Loop through and reload every file in all relevant project directories.
23
+ reload_dirs.each do |dir|
24
+ Dir.glob("#{root_dir}/#{dir}/**/*.rb").each { |f| load(f) }
25
+ end
26
+ # Return true when complete.
27
+ true
28
+ end
29
+
30
+ IRB.start(__FILE__)
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "cloud-waba-ruby-client"
3
+ s.version = "0.0.1"
4
+ s.summary = "Cloud Waba Client for Ruby."
5
+ s.description = "A simple API wrapper for Cloud Whatsapp Business API"
6
+ s.authors = ["Ahmed Bassell"]
7
+ s.email = "ahmedbassell@gmail.com"
8
+ # s.platform = Gem::Platform::RUBY
9
+ s.files = `git ls-files`.split("\n")
10
+ s.homepage =
11
+ "https://rubygems.org/gems/cloud_waba"
12
+ s.license = "MIT"
13
+
14
+ # Runtime dependencies
15
+ s.add_dependency 'dotenv', '~>2.8.0' # env variable
16
+ s.add_dependency 'http', '~> 4.0.0'
17
+
18
+ # Development dependencies
19
+ s.add_development_dependency "rspec", '~>3.4.0' # testing
20
+ s.add_development_dependency 'webmock', '~>3.17.0'
21
+ s.add_development_dependency 'byebug', '~> 9.0', '>= 9.0.5'
22
+ s.add_development_dependency 'sorbet', '~> 0.5.1'
23
+ s.add_runtime_dependency 'sorbet-runtime', '~>0.5.1'
24
+ end
@@ -0,0 +1,217 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ # require 'pry'
5
+
6
+ module API
7
+ module Messages
8
+ class Service
9
+ extend ::T::Sig
10
+ extend ::T::Helpers
11
+
12
+ MESSAGING_PRODUCT = ::T.let("whatsapp", ::String)
13
+ RECIPIENT_TYPE = ::T.let("individual", ::String)
14
+
15
+ def initialize(config:)
16
+ @config = config
17
+ end
18
+
19
+
20
+ sig do
21
+ params(recipient: ::String, body: ::String, reply_message_id: ::T.nilable(::String)).returns(::CloudWaba::Models::Messages::Response)
22
+ end
23
+ def send_text(recipient:, body:, reply_message_id: nil)
24
+ text_type = "text"
25
+ enable_preview = false
26
+
27
+ payload = {
28
+ "messaging_product": MESSAGING_PRODUCT,
29
+ "recipient_type": RECIPIENT_TYPE,
30
+ "to": recipient,
31
+ "type": text_type,
32
+ "text": {
33
+ "preview_url": enable_preview,
34
+ "body": body
35
+ }
36
+ }
37
+
38
+ payload["context"] = { "message_id": reply_message_id } unless reply_message_id.nil?
39
+
40
+ response = http_client.post(body: payload, headers: {})
41
+ parsed_response = JSON.parse(response.body.to_s)
42
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
43
+ end
44
+
45
+ sig do
46
+ params(recipient: ::String, caption: ::T.nilable(::String), link: ::String, reply_message_id: ::T.nilable(::String)).returns(::CloudWaba::Models::Messages::Response)
47
+ end
48
+ def send_image(recipient:, caption:, link:, reply_message_id: nil)
49
+ image_type = "image"
50
+
51
+ payload = {
52
+ "messaging_product": MESSAGING_PRODUCT,
53
+ "recipient_type": RECIPIENT_TYPE,
54
+ "to": recipient,
55
+ "type": image_type,
56
+ }
57
+
58
+ payload["image"] = { link: link, caption: caption }
59
+ payload["context"] = { "message_id": reply_message_id } unless reply_message_id.nil?
60
+
61
+ response = http_client.post(body: payload, headers: {})
62
+ parsed_response = JSON.parse(response.body.to_s)
63
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
64
+ end
65
+
66
+ sig do
67
+ params(recipient: ::String, link: ::String, reply_message_id: ::T.nilable(::String)).returns(::CloudWaba::Models::Messages::Response)
68
+ end
69
+ def send_audio(recipient:, link:, reply_message_id: nil)
70
+ audio_type = "audio"
71
+
72
+ payload = {
73
+ "messaging_product": MESSAGING_PRODUCT,
74
+ "recipient_type": RECIPIENT_TYPE,
75
+ "to": recipient,
76
+ "type": audio_type,
77
+ }
78
+
79
+ payload["audio"] = { link: link }
80
+ payload["context"] = { "message_id": reply_message_id } unless reply_message_id.nil?
81
+
82
+ response = http_client.post(body: payload, headers: {})
83
+ parsed_response = JSON.parse(response.body.to_s)
84
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
85
+ end
86
+
87
+ sig do
88
+ params(recipient: ::String, caption: ::T.nilable(::String), link: ::String, reply_message_id: ::T.nilable(::String)).returns(::CloudWaba::Models::Messages::Response)
89
+ end
90
+ def send_video(recipient:, caption:, link:, reply_message_id: nil)
91
+ video_type = "video"
92
+
93
+ payload = {
94
+ "messaging_product": MESSAGING_PRODUCT,
95
+ "recipient_type": RECIPIENT_TYPE,
96
+ "to": recipient,
97
+ "type": video_type,
98
+ }
99
+
100
+ payload["video"] = { link: link, caption: caption }
101
+ payload["context"] = { "message_id": reply_message_id } unless reply_message_id.nil?
102
+
103
+ response = http_client.post(body: payload, headers: {})
104
+ parsed_response = JSON.parse(response.body.to_s)
105
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
106
+ end
107
+
108
+ sig do
109
+ params(recipient: ::String, caption: ::T.nilable(::String), link: ::String, reply_message_id: ::T.nilable(::String)).returns(::CloudWaba::Models::Messages::Response)
110
+ end
111
+ def send_document(recipient:, caption:, link:, reply_message_id: nil)
112
+ document_type = "document"
113
+
114
+ payload = {
115
+ "messaging_product": MESSAGING_PRODUCT,
116
+ "recipient_type": RECIPIENT_TYPE,
117
+ "to": recipient,
118
+ "type": document_type,
119
+ }
120
+
121
+ payload["document"] = { link: link, caption: caption }
122
+ payload["context"] = { "message_id": reply_message_id } unless reply_message_id.nil?
123
+
124
+ response = http_client.post(body: payload, headers: {})
125
+ parsed_response = JSON.parse(response.body.to_s)
126
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
127
+ end
128
+
129
+ sig do
130
+ params(recipient: ::String, longitude: ::Float, latitude: ::Float, name: ::String, address: ::String, reply_message_id: ::T.nilable(::String)).returns(::CloudWaba::Models::Messages::Response)
131
+ end
132
+ def send_location(recipient:, longitude:, latitude:, name:, address:, reply_message_id: nil)
133
+ location_type = "location"
134
+
135
+ payload = {
136
+ "messaging_product": MESSAGING_PRODUCT,
137
+ "recipient_type": RECIPIENT_TYPE,
138
+ "to": recipient,
139
+ "type": location_type,
140
+ }
141
+
142
+ payload["location"] = {
143
+ "longitude": longitude,
144
+ "latitude": latitude,
145
+ "name": name,
146
+ "address": address
147
+ }
148
+ payload["context"] = { "message_id": reply_message_id } unless reply_message_id.nil?
149
+
150
+ response = http_client.post(body: payload, headers: {})
151
+ parsed_response = JSON.parse(response.body.to_s)
152
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
153
+ end
154
+
155
+ sig do
156
+ params(recipient: ::String, contacts: ::T::Array[::CloudWaba::Models::Messages::Contact], reply_message_id: ::T.nilable(::String)).returns(::CloudWaba::Models::Messages::Response)
157
+ end
158
+ def send_contact(recipient:, contacts:, reply_message_id: nil)
159
+ contacts_type = "contacts"
160
+
161
+ payload = {
162
+ "messaging_product": MESSAGING_PRODUCT,
163
+ "recipient_type": RECIPIENT_TYPE,
164
+ "to": recipient,
165
+ "type": contacts_type,
166
+ }
167
+
168
+ payload["contacts"] = contacts.map(&:serialize)
169
+ payload["context"] = { "message_id": reply_message_id } unless reply_message_id.nil?
170
+
171
+ response = http_client.post(body: payload, headers: {})
172
+ parsed_response = JSON.parse(response.body.to_s)
173
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
174
+ end
175
+
176
+ sig do
177
+ params(
178
+ recipient: ::String,
179
+ template_name: ::String,
180
+ template_lang: ::String,
181
+ components: ::T::Array[::CloudWaba::Models::Templates::Component]
182
+ ).returns(::CloudWaba::Models::Messages::Response)
183
+ end
184
+ def send_template(recipient:, template_name:, template_lang:, components:)
185
+ template_type = "template"
186
+
187
+ payload = {
188
+ "messaging_product": MESSAGING_PRODUCT,
189
+ "recipient_type": RECIPIENT_TYPE,
190
+ "to": recipient,
191
+ "type": template_type,
192
+ "template": {
193
+ "name": template_name,
194
+ "language": {
195
+ "code": template_lang
196
+ },
197
+ "components": []
198
+ }
199
+ }
200
+
201
+ response = http_client.post(body: payload, headers: {})
202
+ parsed_response = JSON.parse(response.body.to_s)
203
+ ::CloudWaba::Models::Messages::Response.parse(hash: parsed_response)
204
+ end
205
+
206
+ private
207
+
208
+ def http_client
209
+ ::CloudWaba::HttpClient.new(base_url: messages_endpoint, auth_token: @config.access_token)
210
+ end
211
+
212
+ def messages_endpoint
213
+ "#{@config.base_url}/#{@config.api_version}/#{@config.phone_number_id}/messages"
214
+ end
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,108 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ # require 'pry'
5
+
6
+ module API
7
+ module Templates
8
+ class Service
9
+ extend ::T::Sig
10
+ extend ::T::Helpers
11
+
12
+ MESSAGE_TEMPLATES_PATH = T.let("message_templates", ::String)
13
+
14
+ def initialize(config:)
15
+ @config = config
16
+ end
17
+
18
+
19
+ sig do
20
+ params(limit: T.nilable(::Integer)).returns(::CloudWaba::Models::Templates::List)
21
+ end
22
+ def list(limit: 20)
23
+ fields = "id,name,category,language,status"
24
+ response = templates_client.get(params: { fields: fields, limit: limit })
25
+
26
+ parsed_response = JSON.parse(response.body.to_s)
27
+ templates = parsed_response["data"].map{|hash| ::CloudWaba::Models::Templates::Response.parse(template_hash: hash)}
28
+ ::CloudWaba::Models::Templates::List.new(templates: templates, paging: parsed_response["paging"])
29
+ end
30
+
31
+ sig do
32
+ params(
33
+ name: ::String,
34
+ category: ::CloudWaba::Models::Enums::Templates::Category,
35
+ language: ::String,
36
+ components: ::T::Array[::CloudWaba::Models::Templates::Component]
37
+ ).returns(::CloudWaba::Models::Templates::Response)
38
+ end
39
+ def create(name:, category:, language:, components:)
40
+ allow_category_change = true
41
+
42
+ payload = {
43
+ "name": name,
44
+ "category": category.serialize,
45
+ "allow_category_change": allow_category_change,
46
+ "language": language,
47
+ "components": components.map(&:serialize)
48
+ }
49
+
50
+ response = templates_client.post(body: payload)
51
+ ::CloudWaba::Models::Templates::Response.parse(response: response)
52
+ end
53
+
54
+ sig do
55
+ params(
56
+ template_id: ::String,
57
+ category: ::CloudWaba::Models::Enums::Templates::Category,
58
+ components: ::T::Array[::CloudWaba::Models::Templates::Component]
59
+ ).returns(::T::Boolean)
60
+ end
61
+ def update(template_id:, category:, components:)
62
+ template_client = template_endpoint(template_id: template_id)
63
+ payload = {
64
+ "category": category.serialize,
65
+ "components": components.map(&:serialize)
66
+ }
67
+ response = client.post(body: payload)
68
+ parsed_response = JSON.parse(response.body.to_s)
69
+
70
+ parsed_response["success"] || false
71
+ end
72
+
73
+ sig do
74
+ params(
75
+ name: ::String,
76
+ template_id: ::T.nilable(::String)
77
+ ).returns(::T::Boolean)
78
+ end
79
+ def delete(name:, template_id: nil)
80
+ params = { name: name }
81
+ params[:hsm_id] = template_id unless template_id.nil?
82
+
83
+ response = templates_client.delete(params: params)
84
+ parsed_response = JSON.parse(response.body.to_s)
85
+
86
+ parsed_response["success"] || false
87
+ end
88
+
89
+ private
90
+
91
+ def templates_client
92
+ ::CloudWaba::HttpClient.new(base_url: templates_endpoint, auth_token: @config.access_token)
93
+ end
94
+
95
+ def template_endpoint(template_id:)
96
+ ::CloudWaba::HttpClient.new(base_url: template_endpoint(template_id: template_id), auth_token: @config.access_token)
97
+ end
98
+
99
+ def templates_endpoint
100
+ "#{@config.base_url}/#{@config.api_version}/#{@config.business_account_id}/#{MESSAGE_TEMPLATES_PATH}"
101
+ end
102
+
103
+ def template_endpoint(template_id:)
104
+ "#{@config.base_url}/#{@config.api_version}/#{template_id}"
105
+ end
106
+ end
107
+ end
108
+ end