whatsapp_sdk 0.9.0 → 0.9.2

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: 5fb8ebc1170878767c0800ab380f6cca2cd853fe59ec7496921781ef85fde8fb
4
- data.tar.gz: 67e312ba37cc9c8e612af0a5d0840c1b7933eb3dfcebb9641faee41194387d21
3
+ metadata.gz: acff9c2aa69b398017bced8fbbf81d3d82eb4088f91b2dda24e3638da6c2240a
4
+ data.tar.gz: '0269bed60b15e5c8f1f1e4057f7683f5fe2ea8d931549390037f040530f125ad'
5
5
  SHA512:
6
- metadata.gz: 856af75ac80060b7f0c6e282fc64d396a102dc31c6cbd8bf09c15bcee55b265ee4e0e5ffbff7e3bab055659233cd4d2db087a6303598128d881ae935b5d45685
7
- data.tar.gz: d709a2b39b758cb294a1cc682320bfa4be3a634d137561e01b79f66c3df042312a31e07925d774ab42e84b51e7597a1b20bb6ef1965503a84085cfb1827aca58
6
+ metadata.gz: 70225a9c4b03a4c80e5c300d04eb61b8db45e0933a3aaef35fee71562c021adf80e33e3917b5439946b1d5690820ed4348e108f95692a8e614b221a7010761a1
7
+ data.tar.gz: b0ce380977fc51bf9f79f5fdd40c75ae533239ee78e40a15081b9f9bc19c827b94399373d979b82ad940fd9ac0a3d1ad4b3493ce27ae6f021e4df04d7c834d66
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Unreleased
2
2
 
3
+ # v 0.9.2
4
+ - Add Support to image/webp sticker media. @renatovico [#94](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/issues/94)
5
+
6
+ # v 0.9.1
7
+ - Invalidate unsupported and invalid media types @ignacio-chiazzo [#89](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/89)
8
+
3
9
  # v 0.9.0
4
10
  - Use binary mode to download files @ignacio-chiazzo [#88](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/87)
5
11
  - Added support for downloading media by specifying the type @ignacio-chiazzo [#87](https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/pull/87)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- whatsapp_sdk (0.9.0)
4
+ whatsapp_sdk (0.9.1)
5
5
  faraday (~> 2.3.0)
6
6
  faraday-multipart (~> 1.0.4)
7
7
  sorbet-runtime (~> 0.5.1)
data/README.md CHANGED
@@ -31,25 +31,26 @@ Or install it yourself as:
31
31
 
32
32
  ## Quick Start
33
33
 
34
- There are three primary resources, `Messages`, `Media` and `PhoneNumbers`. `Messages` allows users to send any kind of message (text, audio, location, video, image, etc.). `Media` allows users to manage media, and `Phone Numbers` enable clients to query the associated phone numbers.
34
+ There are three primary resources, `Messages`, `Media` and `PhoneNumbers`. `Messages` allows users to send any message (text, audio, location, video, image, etc.). `Media` allows users to manage media, and `Phone Numbers` enable clients to query the associated phone numbers.
35
35
 
36
- To use `Messages`, `Media` or `PhoneNumbers`, you need to initialize the `Client` that contains auth information. There are two ways to do it
36
+ To use `Messages`, `Media` or `PhoneNumbers`, you need to initialize the `Client` that contains auth information. There are two ways to do it.
37
37
 
38
- 1) Using an initializer
38
+ 1) Use an initializer
39
39
 
40
40
  ```ruby
41
+ # config/initializers/whatsapp_sdk.rb
41
42
  WhatsappSdk.configure do |config|
42
43
  config.access_token = ACCESS_TOKEN
43
44
  end
44
45
  ```
45
- OR 2) creating a `Client` instance and pass it to the `Messages`, `Medias` or `PhoneNumbers` instance like this:
46
+ OR 2) Create a `Client` instance and pass it to the `Messages`, `Medias` or `PhoneNumbers` instance like this:
46
47
 
47
48
  ```ruby
48
49
  client = WhatsappSdk::Api::Client.new("<ACCESS TOKEN>") # replace this with a valid access token
49
50
  messages_api = WhatsappSdk::Api::Messages.new(client)
50
51
  ```
51
52
 
52
- Each API operation returns a `WhatsappSdk::Api::Response` that contains `data` and `error` and a couple of helpful functions such as `ok?` and `error?`. There are three types of response `WhatsappSdk::Api::MessageDataResponse`, `WhatsappSdk::Api::PhoneNumberDataResponse` and `WhatsappSdk::Api::PhoneNumbersDataResponse`. Each of them contains different attributes.
53
+ Each API operation returns a `WhatsappSdk::Api::Response` that contains `data` and `error` and a couple of helpful functions such as `ok?` and `error?`. There are three types of responses `WhatsappSdk::Api::MessageDataResponse`, `WhatsappSdk::Api::PhoneNumberDataResponse` and `WhatsappSdk::Api::PhoneNumbersDataResponse`. Each of them contains different attributes.
53
54
 
54
55
  ## Set up a Meta app
55
56
 
@@ -480,17 +481,17 @@ Visit [the example file](/example.rb) with examples to call the API in a single
480
481
 
481
482
  ## Troubleshooting
482
483
 
483
- - If the API response is `success`, but the message is not delivered, ensure 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). Try also replying a message to the number your registered on your Whatsapp.
484
+ - If the API response is `success`, but the message is not delivered, ensure 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). Try also replying a message to the number you are registered on your Whatsapp.
484
485
  - Ensure your Meta App uses an API version greater than or equal to `v.14`.
485
- - Ensure that the Panel in the Facebook dashboard doesn't display any error.
486
+ - Ensure that the Panel in the Facebook dashboard doesn't display any errors.
486
487
 
487
- Note: Sometimes the messages are delayed, see [Meta documentation](https://developers.facebook.com/docs/whatsapp/on-premises/guides/send-message-performance#delays).
488
+ Note: Sometimes the messages are delayed; see [Meta documentation](https://developers.facebook.com/docs/whatsapp/on-premises/guides/send-message-performance#delays).
488
489
 
489
490
  ## Development
490
491
 
491
492
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
492
493
 
493
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
494
+ Run ' bundle exec rake install ' to install this gem onto your local machine. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
494
495
 
495
496
  ### Run all the tests
496
497
  - **Unit tests:** Run `rake test`
@@ -506,6 +507,9 @@ Bug reports and pull requests are welcome on GitHub at [https://github.com/ignac
506
507
 
507
508
  If you want a feature to be implemented in the gem, please, open an issue and we will take a look as soon as we can.
508
509
 
510
+
511
+ Do you want to contribute and are unsure where to start? Ping me on Twitter, and I will help you!
512
+
509
513
  ## License
510
514
 
511
515
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/example.rb CHANGED
@@ -22,12 +22,11 @@ require "pry-nav"
22
22
 
23
23
  ################# UPDATE CONSTANTS #################
24
24
 
25
- ACCESS_TOKEN = "EAAHlmy2rChwBAGELLYnNnJfhKOPuSuaX5cRrfYA65RLY2NlEsMQ4x4tO3fz2imwrhmyx2pvKnC07tm0sWRzFHEko7CtXoZBTSb3lrBrKlx86eDvtdZBm2P2ewEJPbotfMYhTYwLsfMyRdQqgNAmc0wij1hMTHOusZALovPKHsme3RvAo1Ag1wqZA3qrPB2WhZChhKWPOkVQZDZD"
26
- SENDER_ID = 100219219709628
27
- RECIPIENT_NUMBER = 15550429560
28
- BUSINESS_ID = 102_261_539_298_487
29
- IMAGE_LINK = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
30
- AUDIO_LINK = "https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=2951440611667284&ext=1681491953&hash=ATsLUNWiMmGDndn5YlpWQFHm5CUXca0gdahSJTCp5XjgTQ"
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>"
31
30
 
32
31
  if ACCESS_TOKEN == "<TODO replace>"
33
32
  puts "\n\n**** Please update the ACCESS_TOKEN constant in this file. ****\n\n"
@@ -53,24 +52,6 @@ medias_api = WhatsappSdk::Api::Medias.new
53
52
  messages_api = WhatsappSdk::Api::Messages.new
54
53
  phone_numbers_api = WhatsappSdk::Api::PhoneNumbers.new
55
54
  business_profile_api = WhatsappSdk::Api::BusinessProfile.new
56
-
57
- binding.pry
58
- # upload an audio
59
- uploaded_media = medias_api.upload(sender_id: SENDER_ID, file_path: "tmp/downloaded_audio.ogg", type: "audio/ogg")
60
- media_id = uploaded_media.data&.id
61
- puts "Uploaded media id: #{media_id}"
62
-
63
- # get a media audio
64
- media = medias_api.media(media_id: media_id).data
65
- puts "Media info: #{media.raw_data_response}"
66
-
67
- # get a media audio
68
- audio_link = media.url
69
- download_image = medias_api.download(url: audio_link, file_path: 'tmp/downloaded_audio2.ogg', media_type: "audio/ogg")
70
- puts "Downloaded: #{download_image.data.success?}"
71
-
72
-
73
-
74
55
  ############################## Business API ##############################
75
56
  business_profile = business_profile_api.details(SENDER_ID)
76
57
  business_profile_api.update(phone_number_id: SENDER_ID, params: { about: "A very cool business" } )
@@ -36,14 +36,14 @@ module WhatsappSdk
36
36
  end
37
37
 
38
38
  sig do
39
- params(url: String, content_header: String, file_path: T.nilable(String))
39
+ params(url: String, content_type_header: String, file_path: T.nilable(String))
40
40
  .returns(Net::HTTPResponse)
41
41
  end
42
- def download_file(url:, content_header:, file_path: nil)
42
+ def download_file(url:, content_type_header:, file_path: nil)
43
43
  uri = URI.parse(url)
44
44
  request = Net::HTTP::Get.new(uri)
45
45
  request["Authorization"] = "Bearer #{@access_token}"
46
- request.content_type = content_header
46
+ request.content_type = content_type_header
47
47
  req_options = { use_ssl: uri.scheme == "https" }
48
48
 
49
49
  response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
@@ -6,8 +6,9 @@ require "faraday/multipart"
6
6
 
7
7
  require_relative "request"
8
8
  require_relative "response"
9
- require_relative '../../../lib/whatsapp_sdk/api/responses/media_data_response'
10
- require_relative '../../../lib/whatsapp_sdk/api/responses/success_response'
9
+ require_relative 'responses/media_data_response'
10
+ require_relative 'responses/success_response'
11
+ require_relative '../resource/media_types'
11
12
 
12
13
  module WhatsappSdk
13
14
  module Api
@@ -19,9 +20,11 @@ module WhatsappSdk
19
20
  attr_reader :file_path
20
21
 
21
22
  sig { params(file_path: String).void }
22
- def initialize(file_path)
23
+ def initialize(file_path:)
23
24
  @file_path = file_path
24
- super("Couldn't find file_path: #{file_path}")
25
+
26
+ message = "Couldn't find file_path: #{file_path}"
27
+ super(message)
25
28
  end
26
29
  end
27
30
 
@@ -32,10 +35,10 @@ module WhatsappSdk
32
35
  attr_reader :media_type
33
36
 
34
37
  sig { params(media_type: String).void }
35
- def initialize(_media_type)
36
- @file_path = file_path
37
- message = "Invalid Media Type. See the supported types" \
38
- "see the official documentation https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types."
38
+ def initialize(media_type:)
39
+ @media_type = media_type
40
+ message = "Invalid Media Type #{media_type}. See the supported types in the official documentation " \
41
+ "https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types."
39
42
  super(message)
40
43
  end
41
44
  end
@@ -66,11 +69,11 @@ module WhatsappSdk
66
69
  # @return [WhatsappSdk::Api::Response] Response object.
67
70
  sig { params(url: String, file_path: String, media_type: String).returns(WhatsappSdk::Api::Response) }
68
71
  def download(url:, file_path:, media_type:)
69
- return InvalidMediaTypeError(media_type) if media_type && !valid_content_header?(media_type)
72
+ raise InvalidMediaTypeError.new(media_type: media_type) unless valid_media_type?(media_type)
70
73
 
71
- content_header = media_type
74
+ content_type_header = map_media_type_to_content_type_header(media_type)
72
75
 
73
- response = download_file(url: url, file_path: file_path, content_header: content_header)
76
+ response = download_file(url: url, file_path: file_path, content_type_header: content_type_header)
74
77
  response = if response.code.to_i == 200
75
78
  { "success" => true }
76
79
  else
@@ -93,7 +96,7 @@ module WhatsappSdk
93
96
  # @return [WhatsappSdk::Api::Response] Response object.
94
97
  sig { params(sender_id: Integer, file_path: String, type: String).returns(WhatsappSdk::Api::Response) }
95
98
  def upload(sender_id:, file_path:, type:)
96
- raise FileNotFoundError, file_path unless File.file?(file_path)
99
+ raise FileNotFoundError.new(file_path: file_path) unless File.file?(file_path)
97
100
 
98
101
  params = {
99
102
  messaging_product: "whatsapp",
@@ -128,10 +131,16 @@ module WhatsappSdk
128
131
 
129
132
  private
130
133
 
131
- def valid_content_header?(_media_type)
132
- # TODO: Add validations for media types. See available types in the official documentation
133
- # https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types.
134
- true
134
+ def map_media_type_to_content_type_header(media_type)
135
+ # Media type maps 1:1 to the content-type header.
136
+ # The list of supported types are in MediaTypes::SUPPORTED_TYPES.
137
+ # It uses the media type defined by IANA https://www.iana.org/assignments/media-types
138
+
139
+ media_type
140
+ end
141
+
142
+ def valid_media_type?(media_type)
143
+ WhatsappSdk::Resource::MediaTypes::SUPPORTED_MEDIA_TYPES.include?(media_type)
135
144
  end
136
145
  end
137
146
  end
@@ -10,8 +10,8 @@ module WhatsappSdk
10
10
  @client = client
11
11
  end
12
12
 
13
- def download_file(url:, content_header:, file_path: nil)
14
- @client.download_file(url: url, content_header: content_header, file_path: file_path)
13
+ def download_file(url:, content_type_header:, file_path: nil)
14
+ @client.download_file(url: url, content_type_header: content_type_header, file_path: file_path)
15
15
  end
16
16
 
17
17
  def send_request(endpoint: nil, full_url: nil, http_method: "post", params: {}, headers: {})
@@ -0,0 +1,31 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module WhatsappSdk
5
+ module Resource
6
+ class MediaTypes
7
+ extend T::Sig
8
+
9
+ # The media types supported by Whatsapp. The list contains all the types defined in the Whatsapp API
10
+ # documentation: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types
11
+ #
12
+ # The media type is used as a content-type header when downloading the file with MediasApi#download_file.
13
+ # The content-type header matches with the media type using Internet Assigned Numbers Authority (IANA).
14
+ # Media type list defined by IANA https://www.iana.org/assignments/media-types/media-types.xhtml
15
+ #
16
+
17
+ AUDIO_TYPES = %w[audio/aac audio/mp4 audio/mpeg audio/amr audio/ogg].freeze
18
+ DOCUMENT_TYPES = %w[
19
+ text/plain application/pdf application/vnd.ms-powerpoint application/msword application/vnd.ms-excel
20
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document
21
+ application/vnd.openxmlformats-officedocument.presentationml.presentation
22
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
23
+ ].freeze
24
+ IMAGE_TYPES = %w[image/jpeg image/png].freeze
25
+ STICKER_TYPES = %w[image/webp].freeze
26
+ VIDEO_TYPES = %w[video/mp4 video/3gp].freeze
27
+
28
+ SUPPORTED_MEDIA_TYPES = [AUDIO_TYPES + DOCUMENT_TYPES + IMAGE_TYPES + STICKER_TYPES + VIDEO_TYPES].flatten.freeze
29
+ end
30
+ end
31
+ end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module WhatsappSdk
5
- VERSION = "0.9.0"
5
+ VERSION = "0.9.2"
6
6
  end
@@ -18,8 +18,8 @@ module Mocha::ClassMethods
18
18
  end
19
19
 
20
20
  class Mocha::Expectation
21
- sig { params(expected_parameters_or_matchers: T.untyped, kwargs: T.untyped, matching_block: T.nilable(T.proc.params(actual_parameters: T.untyped).void)).returns(Mocha::Expectation) }
22
- def with(*expected_parameters_or_matchers, **kwargs, &matching_block); end
21
+ sig { params(expected_parameters: T.untyped, matching_block: T.nilable(T.proc.params(actual_parameters: T.untyped).void)).returns(Mocha::Expectation) }
22
+ def with(*expected_parameters, &matching_block); end
23
23
 
24
24
  sig { params(values: T.untyped).returns(Mocha::Expectation) }
25
25
  def returns(*values); 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.9.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ignacio-chiazzo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-15 00:00:00.000000000 Z
11
+ date: 2023-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -191,6 +191,7 @@ files:
191
191
  - lib/whatsapp_sdk/resource/interactive_footer.rb
192
192
  - lib/whatsapp_sdk/resource/interactive_header.rb
193
193
  - lib/whatsapp_sdk/resource/media.rb
194
+ - lib/whatsapp_sdk/resource/media_types.rb
194
195
  - lib/whatsapp_sdk/resource/message.rb
195
196
  - lib/whatsapp_sdk/resource/name.rb
196
197
  - lib/whatsapp_sdk/resource/org.rb