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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +13 -9
- data/example.rb +5 -24
- data/lib/whatsapp_sdk/api/client.rb +3 -3
- data/lib/whatsapp_sdk/api/medias.rb +25 -16
- data/lib/whatsapp_sdk/api/request.rb +2 -2
- data/lib/whatsapp_sdk/resource/media_types.rb +31 -0
- data/lib/whatsapp_sdk/version.rb +1 -1
- data/sorbet/rbi/annotations/mocha.rbi +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acff9c2aa69b398017bced8fbbf81d3d82eb4088f91b2dda24e3638da6c2240a
|
4
|
+
data.tar.gz: '0269bed60b15e5c8f1f1e4057f7683f5fe2ea8d931549390037f040530f125ad'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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
|
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)
|
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)
|
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
|
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
|
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
|
486
|
+
- Ensure that the Panel in the Facebook dashboard doesn't display any errors.
|
486
487
|
|
487
|
-
Note: Sometimes the messages are delayed
|
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
|
-
|
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 = "
|
26
|
-
SENDER_ID =
|
27
|
-
RECIPIENT_NUMBER =
|
28
|
-
BUSINESS_ID =
|
29
|
-
IMAGE_LINK = "
|
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,
|
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:,
|
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 =
|
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 '
|
10
|
-
require_relative '
|
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
|
-
|
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(
|
36
|
-
@
|
37
|
-
message = "Invalid Media Type. See the supported types" \
|
38
|
-
"
|
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
|
-
|
72
|
+
raise InvalidMediaTypeError.new(media_type: media_type) unless valid_media_type?(media_type)
|
70
73
|
|
71
|
-
|
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,
|
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
|
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
|
132
|
-
#
|
133
|
-
#
|
134
|
-
|
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:,
|
14
|
-
@client.download_file(url: url,
|
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
|
data/lib/whatsapp_sdk/version.rb
CHANGED
@@ -18,8 +18,8 @@ module Mocha::ClassMethods
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class Mocha::Expectation
|
21
|
-
sig { params(
|
22
|
-
def with(*
|
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.
|
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-
|
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
|