whatsapp_sdk 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,13 +15,19 @@ module WhatsappSdk
15
15
  end
16
16
  end
17
17
 
18
+ # Send a text message.
19
+ #
20
+ # @param sender_id [Integer] Sender' phone number.
21
+ # @param recipient_number [Integer] Recipient' Phone number.
22
+ # @param message [String] Text to send.
23
+ # @return [WhatsappSdk::Api::Response] Response object.
18
24
  def send_text(sender_id:, recipient_number:, message:)
19
25
  params = {
20
26
  messaging_product: "whatsapp",
21
27
  to: recipient_number,
22
- recepient_type: "individual",
28
+ recipient_type: "individual",
23
29
  type: "text",
24
- "text": { body: message }
30
+ text: { body: message }
25
31
  }
26
32
 
27
33
  response = send_request(
@@ -29,20 +35,32 @@ module WhatsappSdk
29
35
  params: params
30
36
  )
31
37
 
32
- 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
+ )
33
42
  end
34
43
 
44
+ # Send location.
45
+ #
46
+ # @param sender_id [Integer] Sender' phone number.
47
+ # @param recipient_number [Integer] Recipient' Phone number.
48
+ # @param longitude [Float] Location longitude.
49
+ # @param latitude [Float] Location latitude.
50
+ # @param name [String] Location name.
51
+ # @param address [String] Location address.
52
+ # @return [WhatsappSdk::Api::Response] Response object.
35
53
  def send_location(sender_id:, recipient_number:, longitude:, latitude:, name:, address:)
36
54
  params = {
37
55
  messaging_product: "whatsapp",
38
56
  to: recipient_number,
39
- recepient_type: "individual",
57
+ recipient_type: "individual",
40
58
  type: "location",
41
- "location": {
42
- "longitude": longitude,
43
- "latitude": latitude,
44
- "name": name,
45
- "address": address
59
+ location: {
60
+ longitude: longitude,
61
+ latitude: latitude,
62
+ name: name,
63
+ address: address
46
64
  }
47
65
  }
48
66
 
@@ -51,16 +69,27 @@ module WhatsappSdk
51
69
  params: params
52
70
  )
53
71
 
54
- 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
+ )
55
76
  end
56
77
 
78
+ # Send an image.
79
+ #
80
+ # @param sender_id [Integer] Sender' phone number.
81
+ # @param recipient_number [Integer] Recipient' Phone number.
82
+ # @param image_id [Integer] Image ID.
83
+ # @param link [String] Image link.
84
+ # @param caption [String] Image caption.
85
+ # @return [WhatsappSdk::Api::Response] Response object.
57
86
  def send_image(sender_id:, recipient_number:, image_id: nil, link: nil, caption: "")
58
87
  raise MissingArgumentError, "image_id or link is required" if !image_id && !link
59
88
 
60
89
  params = {
61
90
  messaging_product: "whatsapp",
62
91
  to: recipient_number,
63
- recepient_type: "individual",
92
+ recipient_type: "individual",
64
93
  type: "image"
65
94
  }
66
95
  params[:image] = if link
@@ -74,16 +103,26 @@ module WhatsappSdk
74
103
  params: params
75
104
  )
76
105
 
77
- 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
+ )
78
110
  end
79
111
 
112
+ # Send an audio.
113
+ #
114
+ # @param sender_id [Integer] Sender' phone number.
115
+ # @param recipient_number [Integer] Recipient' Phone number.
116
+ # @param audio_id [Integer] Audio ID.
117
+ # @param link [String] Audio link.
118
+ # @return [WhatsappSdk::Api::Response] Response object.
80
119
  def send_audio(sender_id:, recipient_number:, audio_id: nil, link: nil)
81
120
  raise MissingArgumentError, "audio_id or link is required" if !audio_id && !link
82
121
 
83
122
  params = {
84
123
  messaging_product: "whatsapp",
85
124
  to: recipient_number,
86
- recepient_type: "individual",
125
+ recipient_type: "individual",
87
126
  type: "audio"
88
127
  }
89
128
  params[:audio] = link ? { link: link } : { id: audio_id }
@@ -93,16 +132,27 @@ module WhatsappSdk
93
132
  params: params
94
133
  )
95
134
 
96
- 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
+ )
97
139
  end
98
140
 
141
+ # Send a video.
142
+ #
143
+ # @param sender_id [Integer] Sender' phone number.
144
+ # @param recipient_number [Integer] Recipient' Phone number.
145
+ # @param video_id [Integer] Video ID.
146
+ # @param link [String] Image link.
147
+ # @param caption [String] Image caption.
148
+ # @return [WhatsappSdk::Api::Response] Response object.
99
149
  def send_video(sender_id:, recipient_number:, video_id: nil, link: nil, caption: "")
100
150
  raise MissingArgumentError, "video_id or link is required" if !video_id && !link
101
151
 
102
152
  params = {
103
153
  messaging_product: "whatsapp",
104
154
  to: recipient_number,
105
- recepient_type: "individual",
155
+ recipient_type: "individual",
106
156
  type: "video"
107
157
  }
108
158
  params[:video] = if link
@@ -116,16 +166,27 @@ module WhatsappSdk
116
166
  params: params
117
167
  )
118
168
 
119
- 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
+ )
120
173
  end
121
174
 
175
+ # Send a document.
176
+ #
177
+ # @param sender_id [Integer] Sender' phone number.
178
+ # @param recipient_number [Integer] Recipient' Phone number.
179
+ # @param document_id [Integer] document ID.
180
+ # @param link [String] Image link.
181
+ # @param caption [String] Image caption.
182
+ # @return [WhatsappSdk::Api::Response] Response object.
122
183
  def send_document(sender_id:, recipient_number:, document_id: nil, link: nil, caption: "")
123
184
  raise MissingArgumentError, "document or link is required" if !document_id && !link
124
185
 
125
186
  params = {
126
187
  messaging_product: "whatsapp",
127
188
  to: recipient_number,
128
- recepient_type: "individual",
189
+ recipient_type: "individual",
129
190
  type: "document"
130
191
  }
131
192
  params[:document] = if link
@@ -139,16 +200,25 @@ module WhatsappSdk
139
200
  params: params
140
201
  )
141
202
 
142
- 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
+ )
143
207
  end
144
208
 
209
+ # Send a document.
210
+ #
211
+ # @param sender_id [Integer] Sender' phone number.
212
+ # @param recipient_number [Integer] Recipient' Phone number.
213
+ # @param link [String] Image link.
214
+ # @return [WhatsappSdk::Api::Response] Response object.
145
215
  def send_sticker(sender_id:, recipient_number:, sticker_id: nil, link: nil)
146
216
  raise MissingArgumentError, "sticker or link is required" if !sticker_id && !link
147
217
 
148
218
  params = {
149
219
  messaging_product: "whatsapp",
150
220
  to: recipient_number,
151
- recepient_type: "individual",
221
+ recipient_type: "individual",
152
222
  type: "sticker"
153
223
  }
154
224
  params[:sticker] = link ? { link: link } : { id: sticker_id }
@@ -158,14 +228,25 @@ module WhatsappSdk
158
228
  params: params
159
229
  )
160
230
 
161
- 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
+ )
162
235
  end
163
236
 
237
+ # Send contacts.
238
+ # You can either send contacts objects or contacts as JSON.
239
+ #
240
+ # @param sender_id [Integer] Sender' phone number.
241
+ # @param recipient_number [Integer] Recipient' Phone number.
242
+ # @param contacts [Array<Contact>] Contacts.
243
+ # @param contacts_json [Json] Contacts.
244
+ # @return [WhatsappSdk::Api::Response] Response object.
164
245
  def send_contacts(sender_id:, recipient_number:, contacts: nil, contacts_json: {})
165
246
  params = {
166
247
  messaging_product: "whatsapp",
167
248
  to: recipient_number,
168
- recepient_type: "individual",
249
+ recipient_type: "individual",
169
250
  type: "contacts"
170
251
  }
171
252
  params[:contacts] = contacts ? contacts.map(&:to_h) : contacts_json
@@ -175,7 +256,10 @@ module WhatsappSdk
175
256
  params: params
176
257
  )
177
258
 
178
- 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
+ )
179
263
  end
180
264
 
181
265
  def send_interactive_button
@@ -190,6 +274,69 @@ module WhatsappSdk
190
274
  # TODO: https://developers.facebook.com/docs/whatsapp_sdk/cloud-api/reference/messages#contacts-object
191
275
  end
192
276
 
277
+ # Mark a message as read.
278
+ #
279
+ # @param sender_id [Integer] Sender' phone number.
280
+ # @param message_id [Integer] Message ID.
281
+ # @return [WhatsappSdk::Api::Response] Response object.
282
+ def read_message(sender_id:, message_id:)
283
+ params = {
284
+ messaging_product: "whatsapp",
285
+ status: "read",
286
+ message_id: message_id
287
+ }
288
+
289
+ response = send_request(
290
+ endpoint: endpoint(sender_id),
291
+ params: params
292
+ )
293
+
294
+ WhatsappSdk::Api::Response.new(
295
+ response: response,
296
+ data_class_type: WhatsappSdk::Api::Responses::ReadMessageDataResponse
297
+ )
298
+ end
299
+
300
+ # Send template
301
+ #
302
+ # @param sender_id [Integer] Sender' phone number.
303
+ # @param recipient_number [Integer] Recipient' Phone number.
304
+ # @param name [String] the template's name.
305
+ # @param language [String] template language.
306
+ # @param components [Component] Component.
307
+ # @param components_json [Json] The component as a Json. If you pass components_json, you can't pass components.
308
+ # @return [WhatsappSdk::Api::Response] Response object.
309
+ def send_template(sender_id:, recipient_number:, name:, language:, components: nil, components_json: nil)
310
+ raise MissingArgumentError, "components or components_json is required" if !components && !components_json
311
+
312
+ params = {
313
+ messaging_product: "whatsapp",
314
+ recipient_type: "individual",
315
+ to: recipient_number,
316
+ type: "template",
317
+ template: {
318
+ name: name
319
+ }
320
+ }
321
+
322
+ params[:template][:language] = { code: language } if language
323
+ params[:template][:components] = if components.nil?
324
+ components_json
325
+ else
326
+ components.map(&:to_json)
327
+ end
328
+
329
+ response = send_request(
330
+ endpoint: endpoint(sender_id),
331
+ params: params
332
+ )
333
+
334
+ WhatsappSdk::Api::Response.new(
335
+ response: response,
336
+ data_class_type: WhatsappSdk::Api::Responses::MessageDataResponse
337
+ )
338
+ end
339
+
193
340
  private
194
341
 
195
342
  def endpoint(sender_id)
@@ -6,24 +6,36 @@ require_relative "response"
6
6
  module WhatsappSdk
7
7
  module Api
8
8
  class PhoneNumbers < Request
9
+ # Get list of registered numbers.
10
+ #
11
+ # @param business_id [Integer] Business Id.
12
+ # @return [WhatsappSdk::Api::Response] Response object.
9
13
  def registered_numbers(business_id)
10
14
  response = send_request(
11
15
  http_method: "get",
12
16
  endpoint: "#{business_id}/phone_numbers"
13
17
  )
14
18
 
15
- WhatsappSdk::Api::Response.new(response: response,
16
- class_type: WhatsappSdk::Api::Responses::PhoneNumbersDataResponse)
19
+ WhatsappSdk::Api::Response.new(
20
+ response: response,
21
+ data_class_type: WhatsappSdk::Api::Responses::PhoneNumbersDataResponse
22
+ )
17
23
  end
18
24
 
25
+ # Get the registered number id.
26
+ #
27
+ # @param phone_number_id [Integer] The registered number we want to retrieve.
28
+ # @return [WhatsappSdk::Api::Response] Response object.
19
29
  def registered_number(phone_number_id)
20
30
  response = send_request(
21
31
  http_method: "get",
22
32
  endpoint: phone_number_id.to_s
23
33
  )
24
34
 
25
- WhatsappSdk::Api::Response.new(response: response,
26
- class_type: WhatsappSdk::Api::Responses::PhoneNumberDataResponse)
35
+ WhatsappSdk::Api::Response.new(
36
+ response: response,
37
+ data_class_type: WhatsappSdk::Api::Responses::PhoneNumberDataResponse
38
+ )
27
39
  end
28
40
  end
29
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
@@ -3,28 +3,25 @@
3
3
  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
- require_relative "responses/error_response"
6
+ require_relative "responses/read_message_data_response"
7
+ require_relative "responses/message_error_response"
7
8
 
8
9
  module WhatsappSdk
9
10
  module Api
10
11
  class Response
11
12
  attr_accessor :error, :data
12
13
 
13
- CLASS_TYPE = {
14
- message_data_response: Responses::MessageDataResponse,
15
- phone_number_data_response: Responses::PhoneNumberDataResponse,
16
- phone_numbers_data_response: Responses::PhoneNumbersDataResponse
17
- }.freeze
18
-
19
- def initialize(response:, class_type:)
20
- @data = class_type.build_from_response(response: response)
21
- @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)
22
17
  end
23
18
 
19
+ # @return [Boolean] Whether or not the response is successful.
24
20
  def ok?
25
21
  @error.nil?
26
22
  end
27
23
 
24
+ # @return [Boolean] Whether or not the response has an error.
28
25
  def error?
29
26
  !!@error
30
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
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../request"
4
+ require_relative "data_response"
5
+ require_relative "../../resource/message"
6
+ require_relative "../../resource/contact_response"
7
+
8
+ module WhatsappSdk
9
+ module Api
10
+ module Responses
11
+ class ReadMessageDataResponse < DataResponse
12
+ attr_reader :success
13
+
14
+ def initialize(response:)
15
+ @success = response["success"]
16
+ super(response)
17
+ end
18
+
19
+ def self.build_from_response(response:)
20
+ return if response["error"]
21
+
22
+ new(response: response)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -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
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ module Resource
5
+ class ButtonParameter
6
+ class InvalidType < StandardError
7
+ attr_accessor :message
8
+
9
+ def initialize(type)
10
+ @message = "invalid type #{type}. type should be text or payload"
11
+ super
12
+ end
13
+ end
14
+
15
+ # Returns the button parameter type.
16
+ #
17
+ # @returns type [String] Valid options are payload and text.
18
+ attr_accessor :type
19
+
20
+ module Type
21
+ TEXT = "text"
22
+ PAYLOAD = "payload"
23
+
24
+ VALID_TYPES = [PAYLOAD, TEXT].freeze
25
+ end
26
+
27
+ # Required for quick_reply buttons.
28
+ # Returns the button payload. Developer-defined payload that is returned when the button is clicked
29
+ # in addition to the display text on the button.
30
+ #
31
+ # @returns payload [String]
32
+ attr_accessor :payload
33
+
34
+ # Required for URL buttons.
35
+ # Developer-provided suffix that is appended to the predefined prefix URL in the template.
36
+ #
37
+ # @returns text [String]
38
+ attr_accessor :text
39
+
40
+ def initialize(type:, payload: nil, text: nil)
41
+ @type = type
42
+ @payload = payload
43
+ @text = text
44
+ validate
45
+ end
46
+
47
+ def to_json(*_args)
48
+ json = {
49
+ type: type
50
+ }
51
+ json[:payload] = payload if payload
52
+ json[:text] = text if text
53
+ json
54
+ end
55
+
56
+ private
57
+
58
+ def validate
59
+ return if Type::VALID_TYPES.include?(type)
60
+
61
+ raise InvalidType, type
62
+ end
63
+ end
64
+ end
65
+ end