whatsapp_sdk 0.1.0 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4f5058be0fce569741f60508e508ec0b1cba2eccffbc5f510d7312cb023847b
4
- data.tar.gz: 0af25be3aad6fdb5ffc60b014745294a0fa5cf496ce11ce68ebb886a774dfca4
3
+ metadata.gz: f68cc009fe9fd27e79ac8e7f1a128204c66a565f055bce04bf4338f63ccb4f63
4
+ data.tar.gz: 49c4b5891624196c2557166cce8587e645a12e16716ccbc216c19f048cf2ab41
5
5
  SHA512:
6
- metadata.gz: 6f1ede78aafc6391e5de55ac4aa338a3286d5a9eb634a6afac22bf28cf39afa2f8e8356db2f266aa1bb7101ca122497b6036b843146fb77890c6f10d7460f7f8
7
- data.tar.gz: 4b7524e665d2c13e4b8561e125b1cdbccbdfc1f95c49b7b465ce0e368918ce239a17afb58d83625b28a3288d803b25680b78167a967e69f3575d27071f7d9d2c
6
+ metadata.gz: 91204e0864c369777ff18f63c95f846acbcfa6248ed52fa0db6d05f43784be704e124edffcc73f4d3e0d565269b1784058ede119bdd862d067f75a49550d67df
7
+ data.tar.gz: 606a0b4ab9601388c2c737e47306cbc2432ef763efd82a869dd92be7d23d8fc2a6877573f1db5119b20ff8135523469a47ed02e2f75f857f33b238b6e7e23be5
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
+ AllCops:
2
+ NewCops: enable
3
+
1
4
  Style/StringLiterals:
2
5
  Enabled: false
3
6
 
@@ -24,4 +27,4 @@ Metrics/AbcSize:
24
27
 
25
28
  # Wait until https://github.com/rubocop/rubocop/issues/8761 is fixed
26
29
  Gemspec/RequiredRubyVersion:
27
- Enabled: false
30
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
1
  # Unreleased
2
+
3
+ # v 0.2.0
4
+ - Added Media API
5
+ - Update Facebook API to v14
6
+ - Added error and sucess responses
7
+ - Added faraday-multiplart as part of the library
8
+
2
9
  # v 0.1.0
3
10
  - Added Message Template API.
4
11
  - Added Currency and Datetime resources.
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  # Specify your gem's dependencies in whatsapp_sdk.gemspec
8
8
  gem("faraday")
9
+ gem("faraday-multipart")
9
10
  gem("oj")
10
11
 
11
12
  group(:test) do
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- whatsapp_sdk (0.0.1)
4
+ whatsapp_sdk (0.2.0)
5
5
  faraday (~> 2.3.0)
6
+ faraday-multipart (~> 1.0.4)
6
7
  oj (~> 3.13.13)
7
8
 
8
9
  GEM
@@ -13,10 +14,13 @@ GEM
13
14
  faraday (2.3.0)
14
15
  faraday-net_http (~> 2.0)
15
16
  ruby2_keywords (>= 0.0.4)
17
+ faraday-multipart (1.0.4)
18
+ multipart-post (~> 2)
16
19
  faraday-net_http (2.0.3)
17
20
  method_source (1.0.0)
18
21
  minitest (5.15.0)
19
22
  mocha (1.14.0)
23
+ multipart-post (2.2.2)
20
24
  oj (3.13.13)
21
25
  parallel (1.22.1)
22
26
  parser (3.1.2.0)
@@ -51,6 +55,7 @@ PLATFORMS
51
55
  DEPENDENCIES
52
56
  bundler (~> 2.3)
53
57
  faraday
58
+ faraday-multipart
54
59
  minitest (~> 5.0)
55
60
  mocha
56
61
  oj
data/README.md CHANGED
@@ -38,6 +38,7 @@ First, create the client and then create an instance `WhatsappSdk::Api::Messages
38
38
  client = WhatsappSdk::Api::Client.new("<ACCESS TOKEN>") # replace this with a valid access_token
39
39
  messages_api = WhatsappSdk::Api::Messages.new(client)
40
40
  phone_numbers_api = WhatsappSdk::Api::PhoneNumbers.new(client)
41
+ medias_api = WhatsappSdk::Api::Medias.new(client)
41
42
  ```
42
43
 
43
44
  ### Phone numbers API
@@ -51,6 +52,28 @@ Get the a phone number by id
51
52
  phone_numbers_api.registered_numbers("123456") # accepts a phone_number_id
52
53
  ```
53
54
 
55
+ ### Media API
56
+
57
+ Upload a media
58
+ ```ruby
59
+ medias_api.upload(sender_id: SENDER_ID, file_path: "tmp/whatsapp.png", type: "image/png")
60
+ ```
61
+
62
+ Get a media
63
+ ```ruby
64
+ media = medias_api.media(media_id: MEDIA_ID)
65
+ ```
66
+
67
+ Download media
68
+ ```ruby
69
+ medias_api.download(url: MEDIA_URL, file_path: 'tmp/downloaded_whatsapp.png')
70
+ ```
71
+
72
+ Delete a media
73
+ ```ruby
74
+ medias_api.delete(media_id: MEDIA_ID)
75
+ ```
76
+
54
77
  ### Messages API
55
78
 
56
79
  **Send a text message**
@@ -193,6 +216,10 @@ Visit [the example file](/example.rb) with examples to call the API in a single
193
216
  - See the [official documentation](https://developers.facebook.com/docs/whatsapp/cloud-api) for the Whatsapp Cloud API.
194
217
  - For pricing, refer to the [official documentation](https://developers.facebook.com/docs/whatsapp/pricing/). As of today, Whatsapp offers have 1000 conversations free per month.
195
218
 
219
+ ## Troubleshooting
220
+
221
+ - If the API response is success but the message is not delivered, make sure 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)
222
+
196
223
  ## Development
197
224
 
198
225
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
data/example.rb CHANGED
@@ -11,7 +11,7 @@ gemfile(true) do
11
11
 
12
12
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
13
13
 
14
- gem "whatsapp_sdk"
14
+ gem "whatsapp_sdk", github: "ignacio-chiazzo/whatsapp_sdk", branch: "main"
15
15
  gem "pry"
16
16
  gem "pry-nav"
17
17
  end
@@ -20,141 +20,181 @@ require 'whatsapp_sdk'
20
20
  require "pry"
21
21
  require "pry-nav"
22
22
 
23
- ACCESS_TOKEN = "foo" # replace this with a valid access_token
24
- SENDER_ID = 123
25
- RECIPIENT_NUMBER = "456"
23
+ ################# UPDATE CONSTANTS #################
24
+
25
+ ACCESS_TOKEN = "<TODO replace>"
26
+ SENDER_ID = "<TODO replace>"
27
+ RECIPIENT_NUMBER = "<TODO replace>"
28
+ BUSINESS_ID = "<TODO replace>"
29
+ IMAGE_LINK = "<TODO replace>"
30
+
31
+ ################# HELPERS ########################
32
+ def print_message_sent(message_response)
33
+ if message_response.ok?
34
+ puts "Message sent to: #{message_response.data.contacts.first.input}"
35
+ else
36
+ puts "Error: #{message_response.error&.to_s}"
37
+ end
38
+ end
39
+ ##################################################
26
40
 
27
- client = WhatsappSdk::Api::Client.new(ACCESS_TOKEN) # replace this with a valid access_token
41
+ client = WhatsappSdk::Api::Client.new(ACCESS_TOKEN)
42
+ medias_api = WhatsappSdk::Api::Medias.new(client)
28
43
  messages_api = WhatsappSdk::Api::Messages.new(client)
29
44
  phone_numbers_api = WhatsappSdk::Api::PhoneNumbers.new(client)
30
45
 
31
- phone_numbers_api.registered_number("123")
32
- phone_numbers_api.registered_numbers("457")
46
+ ############################## Phone Numbers API ##############################
47
+ phone_numbers_api.registered_number(SENDER_ID)
48
+ phone_numbers_api.registered_numbers(BUSINESS_ID)
49
+ ############################## Media API ##############################
50
+
51
+ # upload a media
52
+ uploaded_media = medias_api.upload(sender_id: SENDER_ID, file_path: "tmp/whatsapp.png", type: "image/png")
53
+ puts "Uploaded media id: #{uploaded_media.data&.id}"
54
+
55
+ # get a media
56
+ media = medias_api.media(media_id: uploaded_media.data&.id).data
57
+ puts "Media info: #{media.raw_data_response}"
58
+
59
+ # download media
60
+ download_image = medias_api.download(url: media&.url, file_path: 'tmp/downloaded_whatsapp.png')
61
+ puts "Downloaded: #{download_image.data.success?}"
62
+
63
+ # delete a media
64
+ deleted_media = medias_api.delete(media_id: media&.id)
65
+ puts "Deleted: #{deleted_media.data.success?}"
33
66
 
34
- messages_api.send_text(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, message: "hola")
35
- messages_api.send_location(
67
+ ############################## Messages API ##############################
68
+
69
+ ######### SEND A TEXT MESSAGE
70
+ message_sent = messages_api.send_text(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER,
71
+ message: "Hey there! it's Whatsapp Ruby SDK")
72
+ print_message_sent(message_sent)
73
+
74
+ location_sent = messages_api.send_location(
36
75
  sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER,
37
- longitude: 45.4215, latitude: 75.6972, name: "nacho", address: "141 cooper street"
76
+ longitude: -75.6898604, latitude: 45.4192206, name: "Ignacio", address: "My house"
38
77
  )
78
+ print_message_sent(location_sent)
39
79
 
40
- # Send images
41
-
42
- ## with a link
43
- messages_api.send_image(
44
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "image_link", caption: "Ignacio Chiazzo Profile"
80
+ ######### SEND AN IMAGE
81
+ # Send an image with a link
82
+ image_sent = messages_api.send_image(
83
+ sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: media.url, caption: "Ignacio Chiazzo Profile"
45
84
  )
85
+ print_message_sent(image_sent)
46
86
 
47
- ## with an image id
87
+ # Send an image with an id
48
88
  messages_api.send_image(
49
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, image_id: "1234", caption: "Ignacio Chiazzo Profile"
89
+ sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, image_id: media.id, caption: "Ignacio Chiazzo Profile"
50
90
  )
51
91
 
52
- # Send audios
92
+ ######### SEND AUDIOS
53
93
  ## with a link
54
- messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "audio_link")
94
+ # messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "audio_link")
55
95
 
56
96
  ## with an audio id
57
- messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, audio_id: "1234")
97
+ # messages_api.send_audio(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, audio_id: "1234")
58
98
 
59
- # Send documents
99
+ ######### SEND DOCUMENTS
60
100
  ## with a link
61
- messages_api.send_document(
62
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "document_link", caption: "Ignacio Chiazzo"
63
- )
101
+ # messages_api.send_document(
102
+ # sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "document_link", caption: "Ignacio Chiazzo"
103
+ # )
64
104
 
65
105
  ## with a document id
66
- messages_api.send_document(
67
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, document_id: "1234", caption: "Ignacio Chiazzo"
68
- )
106
+ # messages_api.send_document(
107
+ # sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, document_id: "1234", caption: "Ignacio Chiazzo"
108
+ # )
69
109
 
70
- # send stickers
110
+ ######### SEND STICKERS
71
111
  ## with a link
72
- messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "link")
112
+ # messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, link: "link")
73
113
 
74
114
  ## with a sticker_id
75
- messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, sticker_id: "1234")
115
+ # messages_api.send_sticker(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, sticker_id: "1234")
76
116
 
77
- # Send a template.
117
+ ######### SEND A TEMPLATE
78
118
  # Note: The template must have been created previously.
79
119
 
80
- header_component = WhatsappSdk::Resource::Component.new(
81
- type: WhatsappSdk::Resource::Component::Type::HEADER
82
- )
83
-
84
- image = WhatsappSdk::Resource::Media.new(type: "image", link: "http(s)://URL", caption: "caption")
85
- document = WhatsappSdk::Resource::Media.new(type: "document", link: "http(s)://URL", filename: "txt.rb")
86
- video = WhatsappSdk::Resource::Media.new(type: "video", id: 123)
87
-
88
- parameter_image = WhatsappSdk::Resource::ParameterObject.new(
89
- type: "image",
90
- image: image
91
- )
92
-
93
- parameter_document = WhatsappSdk::Resource::ParameterObject.new(
94
- type: "document",
95
- document: document
96
- )
97
-
98
- parameter_video = WhatsappSdk::Resource::ParameterObject.new(
99
- type: "video",
100
- video: video
101
- )
102
-
103
- parameter_text = WhatsappSdk::Resource::ParameterObject.new(
104
- type: "text",
105
- text: "I am a text"
106
- )
107
-
108
- header_component.add_parameter(parameter_text)
109
- header_component.add_parameter(parameter_image)
110
- header_component.add_parameter(parameter_video)
111
- header_component.add_parameter(parameter_document)
112
- header_component.to_json
113
-
114
- body_component = WhatsappSdk::Resource::Component.new(
115
- type: WhatsappSdk::Resource::Component::Type::BODY
116
- )
117
- body_component.add_parameter(parameter_text)
118
- body_component.add_parameter(parameter_image)
119
- body_component.add_parameter(parameter_video)
120
- body_component.add_parameter(parameter_document)
121
- body_component.to_json
122
-
123
- button_component_1 = WhatsappSdk::Resource::Component.new(
124
- type: WhatsappSdk::Resource::Component::Type::BUTTON,
125
- index: 0,
126
- sub_type: WhatsappSdk::Resource::Component::Subtype::QUICK_REPLY,
127
- parameters: [WhatsappSdk::Resource::ButtonParameter.new(type: "payload", payload: "payload")]
128
- )
129
-
130
- button_component_2 = WhatsappSdk::Resource::Component.new(
131
- type: WhatsappSdk::Resource::Component::Type::BUTTON,
132
- index: 1,
133
- sub_type: WhatsappSdk::Resource::Component::Subtype::QUICK_REPLY,
134
- parameters: [WhatsappSdk::Resource::ButtonParameter.new(type: "payload", payload: "payload")]
135
- )
136
-
137
- # make sure that the template was created
138
- response_with_json = messages_api.send_template(
139
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, name: "hello_world", language: "en_US",
140
- components_json: [
141
- {
142
- "type": "header",
143
- "parameters": [
144
- {
145
- "type": "image",
146
- "image": {
147
- "link": "https://www.google.com/imgres?imgurl=https%3A%2F%2Fqph.cf2.quoracdn.net%2Fmain-qimg-6d977408fdd90a09a1fee7ba9e2f777c-lq&imgrefurl=https%3A%2F%2Fwww.quora.com%2FHow-can-I-find-my-WhatsApp-ID&tbnid=lDAx1vzXwqCakM&vet=12ahUKEwjKupLviJX4AhVrrHIEHQpGD9MQMygAegUIARC9AQ..i&docid=s-DNQVCrZmhJYM&w=602&h=339&q=example%20whatsapp%20image%20id&ved=2ahUKEwjKupLviJX4AhVrrHIEHQpGD9MQMygAegUIARC9AQ"
148
- }
149
- }
150
- ]
151
- }
152
- ]
153
- )
154
- puts response_with_json
155
-
156
- response_with_object = messages_api.send_template(
157
- sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, name: "hello_world", language: "en_US",
158
- components: [header_component, body_component, button_component_1, button_component_2]
159
- )
120
+ # Send a template with no component
121
+ response_with_object = messages_api.send_template(sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER,
122
+ name: "hello_world", language: "en_US", components: [])
160
123
  puts response_with_object
124
+
125
+ # Send a template with components. Remember to create the template first.
126
+ # header_component = WhatsappSdk::Resource::Component.new(
127
+ # type: WhatsappSdk::Resource::Component::Type::HEADER
128
+ # )
129
+
130
+ # image = WhatsappSdk::Resource::Media.new(type: "image", link: "http(s)://URL", caption: "caption")
131
+ # document = WhatsappSdk::Resource::Media.new(type: "document", link: "http(s)://URL", filename: "txt.rb")
132
+ # video = WhatsappSdk::Resource::Media.new(type: "video", id: 123)
133
+
134
+ # parameter_image = WhatsappSdk::Resource::ParameterObject.new(
135
+ # type: "image",
136
+ # image: image
137
+ # )
138
+
139
+ # parameter_document = WhatsappSdk::Resource::ParameterObject.new(
140
+ # type: "document",
141
+ # document: document
142
+ # )
143
+
144
+ # parameter_video = WhatsappSdk::Resource::ParameterObject.new(
145
+ # type: "video",
146
+ # video: video
147
+ # )
148
+
149
+ # parameter_text = WhatsappSdk::Resource::ParameterObject.new(
150
+ # type: "text",
151
+ # text: "I am a text"
152
+ # )
153
+
154
+ # header_component.add_parameter(parameter_text)
155
+ # header_component.add_parameter(parameter_image)
156
+ # header_component.add_parameter(parameter_video)
157
+ # header_component.add_parameter(parameter_document)
158
+ # header_component.to_json
159
+
160
+ # body_component = WhatsappSdk::Resource::Component.new(
161
+ # type: WhatsappSdk::Resource::Component::Type::BODY
162
+ # )
163
+ # body_component.add_parameter(parameter_text)
164
+ # body_component.add_parameter(parameter_image)
165
+ # body_component.add_parameter(parameter_video)
166
+ # body_component.add_parameter(parameter_document)
167
+ # body_component.to_json
168
+
169
+ # button_component_1 = WhatsappSdk::Resource::Component.new(
170
+ # type: WhatsappSdk::Resource::Component::Type::BUTTON,
171
+ # index: 0,
172
+ # sub_type: WhatsappSdk::Resource::Component::Subtype::QUICK_REPLY,
173
+ # parameters: [WhatsappSdk::Resource::ButtonParameter.new(type: "payload", payload: "payload")]
174
+ # )
175
+
176
+ # button_component_2 = WhatsappSdk::Resource::Component.new(
177
+ # type: WhatsappSdk::Resource::Component::Type::BUTTON,
178
+ # index: 1,
179
+ # sub_type: WhatsappSdk::Resource::Component::Subtype::QUICK_REPLY,
180
+ # parameters: [WhatsappSdk::Resource::ButtonParameter.new(type: "payload", payload: "payload")]
181
+ # )
182
+
183
+ # # Send a template with component_json
184
+ # response_with_json = messages_api.send_template(
185
+ # sender_id: SENDER_ID, recipient_number: RECIPIENT_NUMBER, name: "hello_world", language: "en_US",
186
+ # components_json: [
187
+ # {
188
+ # "type" => "header",
189
+ # "parameters" => [
190
+ # {
191
+ # "type" => "image",
192
+ # "image" => {
193
+ # "link" => "https://www.google.com/imgres?imgurl=https%3A%2F%2Fqph.cf2.quoracdn.net%2Fmain-qimg-6d977408fdd90a09a1fee7ba9e2f777c-lq&imgrefurl=https%3A%2F%2Fwww.quora.com%2FHow-can-I-find-my-WhatsApp-ID&tbnid=lDAx1vzXwqCakM&vet=12ahUKEwjKupLviJX4AhVrrHIEHQpGD9MQMygAegUIARC9AQ..i&docid=s-DNQVCrZmhJYM&w=602&h=339&q=example%20whatsapp%20image%20id&ved=2ahUKEwjKupLviJX4AhVrrHIEHQpGD9MQMygAegUIARC9AQ"
194
+ # }
195
+ # }
196
+ # ]
197
+ # }
198
+ # ]
199
+ # )
200
+ # puts response_with_json
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WhatsappSdk
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -6,25 +6,45 @@ require "oj"
6
6
  module WhatsappSdk
7
7
  module Api
8
8
  class Client
9
- API_VERSION = "v13.0"
9
+ API_VERSION = "v14.0"
10
10
  API_CLIENT = "https://graph.facebook.com/#{API_VERSION}/"
11
11
 
12
12
  def initialize(access_token)
13
13
  @access_token = access_token
14
14
  end
15
15
 
16
- def client
17
- @client ||= ::Faraday.new(API_CLIENT) do |client|
16
+ def send_request(endpoint: "", full_url: nil, http_method: "post", params: {})
17
+ url = full_url || API_CLIENT
18
+
19
+ response = faraday(url).public_send(http_method, endpoint, params)
20
+ Oj.load(response.body)
21
+ end
22
+
23
+ def download_file(url, path_to_file_name = nil)
24
+ uri = URI.parse(url)
25
+ request = Net::HTTP::Get.new(uri)
26
+ request["Authorization"] = "Bearer #{@access_token}"
27
+ req_options = { use_ssl: uri.scheme == "https" }
28
+
29
+ response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
30
+ http.request(request)
31
+ end
32
+
33
+ File.write(path_to_file_name, response.body) if response.code == "200" && path_to_file_name
34
+
35
+ response
36
+ end
37
+
38
+ private
39
+
40
+ def faraday(url)
41
+ ::Faraday.new(url) do |client|
42
+ client.request :multipart
18
43
  client.request :url_encoded
19
44
  client.adapter ::Faraday.default_adapter
20
45
  client.headers['Authorization'] = "Bearer #{@access_token}" unless @access_token.nil?
21
46
  end
22
47
  end
23
-
24
- def send_request(endpoint:, http_method: "post", params: {})
25
- response = client.public_send(http_method, endpoint, params)
26
- Oj.load(response.body)
27
- end
28
48
  end
29
49
  end
30
50
  end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "faraday/multipart"
5
+
6
+ require_relative "request"
7
+ require_relative "response"
8
+ require_relative '../../../lib/whatsapp_sdk/api/responses/media_data_response'
9
+ require_relative '../../../lib/whatsapp_sdk/api/responses/success_response'
10
+
11
+ module WhatsappSdk
12
+ module Api
13
+ class Medias < Request
14
+ class FileNotFoundError < StandardError
15
+ attr_reader :file_path
16
+
17
+ def initialize(file_path)
18
+ @file_path = file_path
19
+ super("Couldn't find file_path: #{file_path}")
20
+ end
21
+ end
22
+
23
+ # Get Media by ID.
24
+ #
25
+ # @param media_id [Integer] Media Id.
26
+ # @return [WhatsappSdk::Api::Response] Response object.
27
+ def media(media_id:)
28
+ response = send_request(
29
+ http_method: "get",
30
+ endpoint: "/#{media_id}"
31
+ )
32
+
33
+ WhatsappSdk::Api::Response.new(
34
+ response: response,
35
+ data_class_type: WhatsappSdk::Api::Responses::MediaDataResponse
36
+ )
37
+ end
38
+
39
+ # Download Media by URL.
40
+ #
41
+ # @param media_id [Integer] Media Id.
42
+ # @param file_path [String] The file_path to download the media e.g. "tmp/downloaded_image.png".
43
+ # @return [WhatsappSdk::Api::Response] Response object.
44
+ def download(url:, file_path:)
45
+ response = download_file(url, file_path)
46
+
47
+ response = if response.code.to_i == 200
48
+ { "success" => true }
49
+ else
50
+ { "error" => true, "status" => response.code }
51
+ end
52
+
53
+ WhatsappSdk::Api::Response.new(
54
+ response: response,
55
+ data_class_type: WhatsappSdk::Api::Responses::SuccessResponse,
56
+ error_class_type: WhatsappSdk::Api::Responses::ErrorResponse
57
+ )
58
+ end
59
+
60
+ # Upload a media.
61
+ # @param sender_id [Integer] Sender' phone number.
62
+ # @param file_path [String] Path to the file stored in your local directory. For example: "tmp/whatsapp.png".
63
+ # @param type [String] Media type e.g. text/plain, video/3gp, image/jpeg, image/png. For more information,
64
+ # see the official documentation https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types.
65
+ #
66
+ # @return [WhatsappSdk::Api::Response] Response object.
67
+ def upload(sender_id:, file_path:, type:)
68
+ raise FileNotFoundError, file_path unless File.file?(file_path)
69
+
70
+ params = {
71
+ messaging_product: "whatsapp",
72
+ file: Faraday::FilePart.new(file_path, type),
73
+ type: type
74
+ }
75
+
76
+ response = send_request(http_method: "post", endpoint: "#{sender_id}/media", params: params)
77
+
78
+ WhatsappSdk::Api::Response.new(
79
+ response: response,
80
+ data_class_type: WhatsappSdk::Api::Responses::MediaDataResponse
81
+ )
82
+ end
83
+
84
+ # Delete a Media by ID.
85
+ #
86
+ # @param media_id [Integer] Media Id.
87
+ # @return [WhatsappSdk::Api::Response] Response object.
88
+ def delete(media_id:)
89
+ response = send_request(
90
+ http_method: "delete",
91
+ endpoint: "/#{media_id}"
92
+ )
93
+
94
+ WhatsappSdk::Api::Response.new(
95
+ response: response,
96
+ data_class_type: WhatsappSdk::Api::Responses::SuccessResponse
97
+ )
98
+ end
99
+ end
100
+ end
101
+ end
@@ -27,7 +27,7 @@ module WhatsappSdk
27
27
  to: recipient_number,
28
28
  recipient_type: "individual",
29
29
  type: "text",
30
- "text": { body: message }
30
+ text: { body: message }
31
31
  }
32
32
 
33
33
  response = send_request(
@@ -35,7 +35,10 @@ module WhatsappSdk
35
35
  params: params
36
36
  )
37
37
 
38
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
38
+ WhatsappSdk::Api::Response.new(
39
+ response: response,
40
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
41
+ )
39
42
  end
40
43
 
41
44
  # Send location.
@@ -53,11 +56,11 @@ module WhatsappSdk
53
56
  to: recipient_number,
54
57
  recipient_type: "individual",
55
58
  type: "location",
56
- "location": {
57
- "longitude": longitude,
58
- "latitude": latitude,
59
- "name": name,
60
- "address": address
59
+ location: {
60
+ longitude: longitude,
61
+ latitude: latitude,
62
+ name: name,
63
+ address: address
61
64
  }
62
65
  }
63
66
 
@@ -66,7 +69,10 @@ module WhatsappSdk
66
69
  params: params
67
70
  )
68
71
 
69
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
72
+ WhatsappSdk::Api::Response.new(
73
+ response: response,
74
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
75
+ )
70
76
  end
71
77
 
72
78
  # Send an image.
@@ -97,7 +103,10 @@ module WhatsappSdk
97
103
  params: params
98
104
  )
99
105
 
100
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
106
+ WhatsappSdk::Api::Response.new(
107
+ response: response,
108
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
109
+ )
101
110
  end
102
111
 
103
112
  # Send an audio.
@@ -123,7 +132,10 @@ module WhatsappSdk
123
132
  params: params
124
133
  )
125
134
 
126
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
135
+ WhatsappSdk::Api::Response.new(
136
+ response: response,
137
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
138
+ )
127
139
  end
128
140
 
129
141
  # Send a video.
@@ -154,7 +166,10 @@ module WhatsappSdk
154
166
  params: params
155
167
  )
156
168
 
157
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
169
+ WhatsappSdk::Api::Response.new(
170
+ response: response,
171
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
172
+ )
158
173
  end
159
174
 
160
175
  # Send a document.
@@ -185,7 +200,10 @@ module WhatsappSdk
185
200
  params: params
186
201
  )
187
202
 
188
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
203
+ WhatsappSdk::Api::Response.new(
204
+ response: response,
205
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
206
+ )
189
207
  end
190
208
 
191
209
  # Send a document.
@@ -210,7 +228,10 @@ module WhatsappSdk
210
228
  params: params
211
229
  )
212
230
 
213
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
231
+ WhatsappSdk::Api::Response.new(
232
+ response: response,
233
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
234
+ )
214
235
  end
215
236
 
216
237
  # Send contacts.
@@ -235,7 +256,10 @@ module WhatsappSdk
235
256
  params: params
236
257
  )
237
258
 
238
- WhatsappSdk::Api::Response.new(response: response, class_type: WhatsappSdk::Api::Responses::MessageDataResponse)
259
+ WhatsappSdk::Api::Response.new(
260
+ response: response,
261
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
262
+ )
239
263
  end
240
264
 
241
265
  def send_interactive_button
@@ -269,7 +293,7 @@ module WhatsappSdk
269
293
 
270
294
  WhatsappSdk::Api::Response.new(
271
295
  response: response,
272
- class_type: WhatsappSdk::Api::Responses::ReadMessageDataResponse
296
+ data_class_type: WhatsappSdk::Api::Responses::ReadMessageDataResponse
273
297
  )
274
298
  end
275
299
 
@@ -309,7 +333,7 @@ module WhatsappSdk
309
333
 
310
334
  WhatsappSdk::Api::Response.new(
311
335
  response: response,
312
- class_type: WhatsappSdk::Api::Responses::MessageDataResponse
336
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
313
337
  )
314
338
  end
315
339
 
@@ -16,8 +16,10 @@ module WhatsappSdk
16
16
  endpoint: "#{business_id}/phone_numbers"
17
17
  )
18
18
 
19
- WhatsappSdk::Api::Response.new(response: response,
20
- class_type: WhatsappSdk::Api::Responses::PhoneNumbersDataResponse)
19
+ WhatsappSdk::Api::Response.new(
20
+ response: response,
21
+ data_class_type: WhatsappSdk::Api::Responses::PhoneNumbersDataResponse
22
+ )
21
23
  end
22
24
 
23
25
  # Get the registered number id.
@@ -30,8 +32,10 @@ module WhatsappSdk
30
32
  endpoint: phone_number_id.to_s
31
33
  )
32
34
 
33
- WhatsappSdk::Api::Response.new(response: response,
34
- class_type: WhatsappSdk::Api::Responses::PhoneNumberDataResponse)
35
+ WhatsappSdk::Api::Response.new(
36
+ response: response,
37
+ data_class_type: WhatsappSdk::Api::Responses::PhoneNumberDataResponse
38
+ )
35
39
  end
36
40
  end
37
41
  end
@@ -10,8 +10,14 @@ module WhatsappSdk
10
10
  @client = client
11
11
  end
12
12
 
13
- def send_request(endpoint:, http_method: "post", params: {})
14
- @client.send_request(http_method: http_method, endpoint: endpoint, params: params)
13
+ def download_file(url, path_to_file_name = nil)
14
+ @client.download_file(url, path_to_file_name)
15
+ end
16
+
17
+ def send_request(endpoint: nil, full_url: nil, http_method: "post", params: {})
18
+ @client.send_request(
19
+ http_method: http_method, full_url: full_url, endpoint: endpoint, params: params
20
+ )
15
21
  end
16
22
  end
17
23
  end
@@ -4,31 +4,24 @@ require_relative "responses/message_data_response"
4
4
  require_relative "responses/phone_number_data_response"
5
5
  require_relative "responses/phone_numbers_data_response"
6
6
  require_relative "responses/read_message_data_response"
7
- require_relative "responses/error_response"
7
+ require_relative "responses/message_error_response"
8
8
 
9
9
  module WhatsappSdk
10
10
  module Api
11
11
  class Response
12
12
  attr_accessor :error, :data
13
13
 
14
- CLASS_TYPE = {
15
- message_data_response: Responses::MessageDataResponse,
16
- phone_number_data_response: Responses::PhoneNumberDataResponse,
17
- phone_numbers_data_response: Responses::PhoneNumbersDataResponse,
18
- read_message_data_response: Responses::ReadMessageDataResponse
19
- }.freeze
20
-
21
- def initialize(response:, class_type:)
22
- @data = class_type.build_from_response(response: response)
23
- @error = Responses::ErrorResponse.build_from_response(response: response)
14
+ def initialize(response:, data_class_type:, error_class_type: Responses::MessageErrorResponse)
15
+ @data = data_class_type.build_from_response(response: response)
16
+ @error = error_class_type.build_from_response(response: response)
24
17
  end
25
18
 
26
- # Whether or not the response is successful.
19
+ # @return [Boolean] Whether or not the response is successful.
27
20
  def ok?
28
21
  @error.nil?
29
22
  end
30
23
 
31
- # Whether or not the response has an error.
24
+ # @return [Boolean] Whether or not the response has an error.
32
25
  def error?
33
26
  !!@error
34
27
  end
@@ -1,32 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "data_response"
4
+
3
5
  module WhatsappSdk
4
6
  module Api
5
7
  module Responses
6
- class ErrorResponse
7
- attr_reader :code, :subcode, :message, :type, :data, :fbtrace_id
8
+ class ErrorResponse < DataResponse
9
+ attr_accessor :error, :status
8
10
 
9
- def initialize(code:, subcode:, message:, type:, data:, fbtrace_id:)
10
- @code = code
11
- @subcode = subcode
12
- @message = message
13
- @type = type
14
- @data = data
15
- @fbtrace_id = fbtrace_id
11
+ def initialize(response:)
12
+ @error = response["error"]
13
+ @status = response["status"]
14
+ super(response)
16
15
  end
17
16
 
18
17
  def self.build_from_response(response:)
19
- error_response = response["error"]
20
- return unless error_response
18
+ return unless response["error"]
21
19
 
22
- new(
23
- code: error_response["code"],
24
- subcode: error_response["error_subcode"],
25
- message: error_response["message"],
26
- type: error_response["type"],
27
- data: error_response["data"],
28
- fbtrace_id: error_response["fbtrace_id"]
29
- )
20
+ new(response: response)
30
21
  end
31
22
  end
32
23
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "data_response"
4
+
5
+ module WhatsappSdk
6
+ module Api
7
+ module Responses
8
+ class MediaDataResponse < DataResponse
9
+ attr_accessor :id, :url, :mime_type, :sha256, :file_size, :messaging_product
10
+
11
+ def initialize(response)
12
+ @id = response["id"]
13
+ @messaging_product = response["messaging_product"]
14
+ @url = response["url"]
15
+ @mime_type = response["mime_type"]
16
+ @sha256 = response["sha256"]
17
+ @file_size = response["file_size"]
18
+ super(response)
19
+ end
20
+
21
+ def self.build_from_response(response:)
22
+ return unless response["id"]
23
+
24
+ new(response)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "error_response"
4
+
5
+ module WhatsappSdk
6
+ module Api
7
+ module Responses
8
+ class MessageErrorResponse < ErrorResponse
9
+ attr_reader :code, :subcode, :message, :type, :data, :fbtrace_id
10
+
11
+ def initialize(response:)
12
+ @code = response["code"]
13
+ @subcode = response["error_subcode"]
14
+ @message = response["message"]
15
+ @type = response["type"]
16
+ @data = response["data"]
17
+ @fbtrace_id = response["fbtrace_id"]
18
+ super(response: response)
19
+ end
20
+
21
+ def self.build_from_response(response:)
22
+ error_response = response["error"]
23
+ return unless error_response
24
+
25
+ new(response: error_response)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -9,10 +9,10 @@ module WhatsappSdk
9
9
  module Api
10
10
  module Responses
11
11
  class ReadMessageDataResponse < DataResponse
12
- attr_reader :sucess
12
+ attr_reader :success
13
13
 
14
14
  def initialize(response:)
15
- @sucess = response["sucess"]
15
+ @success = response["success"]
16
16
  super(response)
17
17
  end
18
18
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "data_response"
4
+
5
+ module WhatsappSdk
6
+ module Api
7
+ module Responses
8
+ class SuccessResponse < DataResponse
9
+ def initialize(response:)
10
+ @success = response["success"]
11
+ super(response)
12
+ end
13
+
14
+ def self.build_from_response(response:)
15
+ return unless response["success"]
16
+
17
+ new(response: response)
18
+ end
19
+
20
+ def success?
21
+ @success
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
data/lib/whatsapp_sdk.rb CHANGED
@@ -3,15 +3,19 @@
3
3
  # APIs
4
4
  require_relative "whatsapp_sdk/api/phone_numbers"
5
5
  require_relative "whatsapp_sdk/api/messages"
6
+ require_relative "whatsapp_sdk/api/medias"
6
7
  require_relative "whatsapp_sdk/api/client"
7
8
 
8
9
  # APIs responses
9
10
  require_relative "whatsapp_sdk/api/responses/message_data_response"
10
11
  require_relative "whatsapp_sdk/api/responses/phone_number_data_response"
11
12
  require_relative "whatsapp_sdk/api/responses/phone_numbers_data_response"
12
- require_relative "whatsapp_sdk/api/responses/error_response"
13
+ require_relative "whatsapp_sdk/api/responses/message_error_response"
13
14
  require_relative "whatsapp_sdk/api/responses/data_response"
14
15
  require_relative "whatsapp_sdk/api/responses/read_message_data_response"
16
+ require_relative "whatsapp_sdk/api/responses/media_data_response"
17
+ require_relative "whatsapp_sdk/api/responses/success_response"
18
+ require_relative "whatsapp_sdk/api/responses/error_response"
15
19
 
16
20
  # Resources
17
21
  require_relative "whatsapp_sdk/resource/address"
data/tmp/whatsapp.png ADDED
Binary file
data/whatsapp_sdk.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.metadata["changelog_uri"] = "https://github.com/ignacio-chiazzo/whatsapp_sdk/blob/main/CHANGELOG.md"
25
25
  else
26
26
  raise "RubyGems 2.0 or newer is required to protect against " \
27
- "public gem pushes."
27
+ "public gem pushes."
28
28
  end
29
29
 
30
30
  # Specify which files should be added to the gem when it is released.
@@ -41,5 +41,7 @@ Gem::Specification.new do |spec|
41
41
  spec.add_development_dependency "rake", "~> 10.0"
42
42
 
43
43
  spec.add_dependency("faraday", "~> 2.3.0")
44
+ spec.add_dependency("faraday-multipart", "~> 1.0.4")
44
45
  spec.add_dependency("oj", "~> 3.13.13")
46
+ spec.metadata['rubygems_mfa_required'] = 'true'
45
47
  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.1.0
4
+ version: 0.2.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: 2022-06-05 00:00:00.000000000 Z
11
+ date: 2022-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 2.3.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday-multipart
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.0.4
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.0.4
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: oj
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -106,16 +120,20 @@ files:
106
120
  - lib/version.rb
107
121
  - lib/whatsapp_sdk.rb
108
122
  - lib/whatsapp_sdk/api/client.rb
123
+ - lib/whatsapp_sdk/api/medias.rb
109
124
  - lib/whatsapp_sdk/api/messages.rb
110
125
  - lib/whatsapp_sdk/api/phone_numbers.rb
111
126
  - lib/whatsapp_sdk/api/request.rb
112
127
  - lib/whatsapp_sdk/api/response.rb
113
128
  - lib/whatsapp_sdk/api/responses/data_response.rb
114
129
  - lib/whatsapp_sdk/api/responses/error_response.rb
130
+ - lib/whatsapp_sdk/api/responses/media_data_response.rb
115
131
  - lib/whatsapp_sdk/api/responses/message_data_response.rb
132
+ - lib/whatsapp_sdk/api/responses/message_error_response.rb
116
133
  - lib/whatsapp_sdk/api/responses/phone_number_data_response.rb
117
134
  - lib/whatsapp_sdk/api/responses/phone_numbers_data_response.rb
118
135
  - lib/whatsapp_sdk/api/responses/read_message_data_response.rb
136
+ - lib/whatsapp_sdk/api/responses/success_response.rb
119
137
  - lib/whatsapp_sdk/error.rb
120
138
  - lib/whatsapp_sdk/resource/address.rb
121
139
  - lib/whatsapp_sdk/resource/button_parameter.rb
@@ -132,6 +150,7 @@ files:
132
150
  - lib/whatsapp_sdk/resource/parameter_object.rb
133
151
  - lib/whatsapp_sdk/resource/phone_number.rb
134
152
  - lib/whatsapp_sdk/resource/url.rb
153
+ - tmp/whatsapp.png
135
154
  - whatsapp_sdk.gemspec
136
155
  homepage: https://github.com/ignacio-chiazzo/whatsapp_sdk
137
156
  licenses:
@@ -140,6 +159,7 @@ metadata:
140
159
  homepage_uri: https://github.com/ignacio-chiazzo/whatsapp_sdk
141
160
  source_code_uri: https://github.com/ignacio-chiazzo/whatsapp_sdk
142
161
  changelog_uri: https://github.com/ignacio-chiazzo/whatsapp_sdk/blob/main/CHANGELOG.md
162
+ rubygems_mfa_required: 'true'
143
163
  post_install_message:
144
164
  rdoc_options: []
145
165
  require_paths: