whatsapp_sdk 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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: