whatsapp_sdk 0.9.0 → 0.9.2

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: 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