warb 0.1.0 → 0.1.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -5
  3. data/README.md +8 -0
  4. data/Rakefile +3 -3
  5. data/docs/messages/interactive_call_to_action_url.md +9 -9
  6. data/docs/messages/interactive_list.md +2 -2
  7. data/docs/messages/interactive_reply_button.md +9 -9
  8. data/docs/messages/template.md +13 -13
  9. data/examples/audio.rb +10 -10
  10. data/examples/document.rb +34 -34
  11. data/examples/image.rb +22 -22
  12. data/examples/interactive_call_to_action_url.rb +46 -46
  13. data/examples/interactive_list.rb +61 -61
  14. data/examples/interactive_reply_button.rb +43 -43
  15. data/examples/location.rb +32 -32
  16. data/examples/location_request.rb +11 -11
  17. data/examples/message.rb +8 -8
  18. data/examples/sticker.rb +10 -10
  19. data/examples/video.rb +22 -22
  20. data/examples/webhook.rb +44 -42
  21. data/lib/warb/client.rb +7 -5
  22. data/lib/warb/components/action.rb +12 -8
  23. data/lib/warb/components/button.rb +2 -2
  24. data/lib/warb/components/component.rb +1 -1
  25. data/lib/warb/components/copy_code_button.rb +4 -4
  26. data/lib/warb/components/quick_reply_button.rb +1 -1
  27. data/lib/warb/components/url_button.rb +4 -4
  28. data/lib/warb/components/voice_call_button.rb +1 -1
  29. data/lib/warb/configuration.rb +4 -1
  30. data/lib/warb/connection.rb +15 -9
  31. data/lib/warb/dispatcher.rb +3 -2
  32. data/lib/warb/dispatcher_concern.rb +2 -0
  33. data/lib/warb/errors.rb +27 -0
  34. data/lib/warb/indicator_dispatcher.rb +4 -4
  35. data/lib/warb/language.rb +2 -2
  36. data/lib/warb/media_dispatcher.rb +10 -10
  37. data/lib/warb/resources/audio.rb +1 -1
  38. data/lib/warb/resources/contact.rb +22 -20
  39. data/lib/warb/resources/currency.rb +6 -4
  40. data/lib/warb/resources/date_time.rb +1 -1
  41. data/lib/warb/resources/document.rb +1 -1
  42. data/lib/warb/resources/flow.rb +10 -8
  43. data/lib/warb/resources/image.rb +1 -1
  44. data/lib/warb/resources/interactive_call_to_action_url.rb +10 -8
  45. data/lib/warb/resources/interactive_list.rb +7 -5
  46. data/lib/warb/resources/interactive_reply_button.rb +10 -8
  47. data/lib/warb/resources/location.rb +1 -1
  48. data/lib/warb/resources/location_request.rb +5 -3
  49. data/lib/warb/resources/reaction.rb +1 -1
  50. data/lib/warb/resources/resource.rb +4 -4
  51. data/lib/warb/resources/sticker.rb +1 -1
  52. data/lib/warb/resources/template.rb +30 -29
  53. data/lib/warb/resources/text.rb +4 -4
  54. data/lib/warb/resources/video.rb +1 -1
  55. data/lib/warb/response.rb +33 -0
  56. data/lib/warb/response_error_handler.rb +42 -0
  57. data/lib/warb/template_dispatcher.rb +4 -2
  58. data/lib/warb/utils.rb +3 -1
  59. data/lib/warb/version.rb +1 -1
  60. data/lib/warb.rb +50 -42
  61. metadata +10 -3
@@ -7,7 +7,7 @@ module Warb
7
7
 
8
8
  def build_payload
9
9
  {
10
- type: "reaction",
10
+ type: 'reaction',
11
11
  reaction: {
12
12
  message_id: message_id || @params[:message_id],
13
13
  emoji: emoji || @params[:emoji]
@@ -27,19 +27,19 @@ module Warb
27
27
  raise NotImplementedError
28
28
  end
29
29
 
30
- def set_text_header
30
+ def add_text_header
31
31
  raise NotImplementedError
32
32
  end
33
33
 
34
- def set_image_header
34
+ def add_image_header
35
35
  raise NotImplementedError
36
36
  end
37
37
 
38
- def set_video_header
38
+ def add_video_header
39
39
  raise NotImplementedError
40
40
  end
41
41
 
42
- def set_document_header
42
+ def add_document_header
43
43
  raise NotImplementedError
44
44
  end
45
45
 
@@ -7,7 +7,7 @@ module Warb
7
7
 
8
8
  def build_payload
9
9
  {
10
- type: "sticker",
10
+ type: 'sticker',
11
11
  sticker: {
12
12
  id: media_id || @params[:media_id],
13
13
  link: link || @params[:link]
@@ -6,7 +6,7 @@ module Warb
6
6
  attr_accessor :name, :language, :resources, :header, :buttons
7
7
 
8
8
  def initialize(**params)
9
- super(**params)
9
+ super
10
10
 
11
11
  @name = params[:name]
12
12
  @language = params[:language]
@@ -14,9 +14,10 @@ module Warb
14
14
  @buttons = []
15
15
  end
16
16
 
17
+ # rubocop:disable Metrics/MethodLength
17
18
  def build_payload
18
19
  {
19
- type: "template",
20
+ type: 'template',
20
21
  template: {
21
22
  name: name,
22
23
  language: {
@@ -30,37 +31,38 @@ module Warb
30
31
  }
31
32
  }
32
33
  end
34
+ # rubocop:enable Metrics/MethodLength
33
35
 
34
- def add_currency_parameter(parameter_name = nil, **params, &block)
35
- add_parameter(parameter_name, Currency.new(**params), &block)
36
+ def add_currency_parameter(parameter_name = nil, **params, &)
37
+ add_parameter(parameter_name, Currency.new(**params), &)
36
38
  end
37
39
 
38
- def add_date_time_parameter(parameter_name = nil, **params, &block)
39
- add_parameter(parameter_name, DateTime.new(**params), &block)
40
+ def add_date_time_parameter(parameter_name = nil, **params, &)
41
+ add_parameter(parameter_name, DateTime.new(**params), &)
40
42
  end
41
43
 
42
- def add_text_parameter(parameter_name = nil, **params, &block)
43
- add_parameter(parameter_name, Text.new(**params), &block)
44
+ def add_text_parameter(parameter_name = nil, **params, &)
45
+ add_parameter(parameter_name, Text.new(**params), &)
44
46
  end
45
47
 
46
- def set_text_header(content: nil, message: nil, text: nil, parameter_name: nil, &block)
47
- set_header(Text.new(content:, message:, text:, parameter_name:), &block)
48
+ def add_text_header(content: nil, message: nil, text: nil, parameter_name: nil, &block)
49
+ add_header(Text.new(content:, message:, text:, parameter_name:), &block)
48
50
  end
49
51
 
50
- def set_image_header(media_id: nil, link: nil, &block)
51
- set_header(Image.new(media_id:, link:), &block)
52
+ def add_image_header(media_id: nil, link: nil, &block)
53
+ add_header(Image.new(media_id:, link:), &block)
52
54
  end
53
55
 
54
- def set_document_header(media_id: nil, link: nil, filename: nil, &block)
55
- set_header(Document.new(media_id:, link:, filename:), &block)
56
+ def add_document_header(media_id: nil, link: nil, filename: nil, &block)
57
+ add_header(Document.new(media_id:, link:, filename:), &block)
56
58
  end
57
59
 
58
- def set_video_header(media_id: nil, link: nil, &block)
59
- set_header(Video.new(media_id:, link:), &block)
60
+ def add_video_header(media_id: nil, link: nil, &block)
61
+ add_header(Video.new(media_id:, link:), &block)
60
62
  end
61
63
 
62
- def set_location_header(latitude: nil, longitude: nil, address: nil, name: nil, &block)
63
- set_header(Location.new(latitude:, longitude:, address:, name:), &block)
64
+ def add_location_header(latitude: nil, longitude: nil, address: nil, name: nil, &block)
65
+ add_header(Location.new(latitude:, longitude:, address:, name:), &block)
64
66
  end
65
67
 
66
68
  def add_quick_reply_button(index: position, &block)
@@ -71,7 +73,7 @@ module Warb
71
73
  add_button(Warb::Components::UrlButton.new(index:, text:), &block)
72
74
  end
73
75
 
74
- alias_method :add_auth_code_button, :add_dynamic_url_button
76
+ alias add_auth_code_button add_dynamic_url_button
75
77
 
76
78
  def add_copy_code_button(index: position, coupon_code: nil, &block)
77
79
  add_button(Warb::Components::CopyCodeButton.new(index:, coupon_code:), &block)
@@ -81,26 +83,25 @@ module Warb
81
83
  add_button(Warb::Components::VoiceCallButton.new(index:), &block)
82
84
  end
83
85
 
84
- def add_button(instance, &block)
86
+ def add_button(instance, &)
85
87
  return @buttons << instance.to_h unless block_given?
86
88
 
87
- @buttons << instance.tap(&block).to_h
89
+ @buttons << instance.tap(&).to_h
88
90
  end
89
91
 
90
92
  private
91
93
 
92
- def set_header(instance, &block)
94
+ def add_header(instance, &)
93
95
  @header = instance
94
96
 
95
- block_given? ? @header.tap(&block) : @header
97
+ block_given? ? @header.tap(&) : @header
96
98
  end
97
99
 
98
-
99
100
  def component_header
100
101
  return unless header.is_a? Resource
101
102
 
102
103
  {
103
- type: "header",
104
+ type: 'header',
104
105
  parameters: [
105
106
  header.build_header
106
107
  ]
@@ -111,7 +112,7 @@ module Warb
111
112
  return if resources.nil? || resources.empty?
112
113
 
113
114
  {
114
- type: "body",
115
+ type: 'body',
115
116
  parameters: build_parameters
116
117
  }
117
118
  end
@@ -135,17 +136,17 @@ module Warb
135
136
  resources.map(&:build_template_positional_parameter)
136
137
  end
137
138
 
138
- def add_parameter(parameter_name, instance, &block)
139
+ def add_parameter(parameter_name, instance, &)
139
140
  case resources
140
141
  when Hash
141
142
  resources[parameter_name.to_s] = instance
142
143
  when Array
143
144
  resources << instance
144
145
  else
145
- initialize_resources(parameter_name, instance, &block)
146
+ initialize_resources(parameter_name, instance, &)
146
147
  end
147
148
 
148
- block_given? ? instance.tap(&block) : instance
149
+ block_given? ? instance.tap(&) : instance
149
150
  end
150
151
 
151
152
  def initialize_resources(parameter_name, instance)
@@ -6,7 +6,7 @@ module Warb
6
6
  attr_accessor :content, :text, :message, :preview_url, :parameter_name
7
7
 
8
8
  def build_header
9
- { type: "text", text: message_per_priority }.tap do |header|
9
+ { type: 'text', text: message_per_priority }.tap do |header|
10
10
  parameter_name ||= @params[:parameter_name]
11
11
  header[:parameter_name] = parameter_name unless parameter_name.nil?
12
12
  end
@@ -14,7 +14,7 @@ module Warb
14
14
 
15
15
  def build_payload
16
16
  {
17
- type: "text",
17
+ type: 'text',
18
18
  text: {
19
19
  preview_url: preview_url || @params[:preview_url],
20
20
  body: message_per_priority
@@ -24,7 +24,7 @@ module Warb
24
24
 
25
25
  def build_template_named_parameter(parameter_name)
26
26
  {
27
- type: "text",
27
+ type: 'text',
28
28
  text: message_per_priority,
29
29
  parameter_name: parameter_name
30
30
  }
@@ -32,7 +32,7 @@ module Warb
32
32
 
33
33
  def build_template_positional_parameter
34
34
  {
35
- type: "text",
35
+ type: 'text',
36
36
  text: message_per_priority
37
37
  }
38
38
  end
@@ -19,7 +19,7 @@ module Warb
19
19
 
20
20
  def common_video_params
21
21
  {
22
- type: "video",
22
+ type: 'video',
23
23
  video: {
24
24
  id: media_id || @params[:media_id],
25
25
  link: link || @params[:link]
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warb
4
+ class Response
5
+ attr_reader :input, :wa_id, :message_id, :body
6
+
7
+ def initialize(body)
8
+ @body = body || {}
9
+ extract_contact_data
10
+ extract_message_data
11
+ end
12
+
13
+ private
14
+
15
+ def extract_contact_data
16
+ first_contact = contacts&.first
17
+ @input = first_contact&.dig('input')
18
+ @wa_id = first_contact&.dig('wa_id')
19
+ end
20
+
21
+ def extract_message_data
22
+ @message_id = messages&.first&.dig('id')
23
+ end
24
+
25
+ def contacts
26
+ @body['contacts']
27
+ end
28
+
29
+ def messages
30
+ @body['messages']
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Warb
4
+ class ResponseErrorHandler
5
+ def initialize(body, status)
6
+ @body = body
7
+ @status = status
8
+ end
9
+
10
+ def handle
11
+ raise Warb::RequestError, 'invalid body' if @body.nil?
12
+
13
+ http_class = Warb::HTTP_ERRORS[@status]
14
+ error_class = custom_class || http_class || Warb::RequestError
15
+ Warb.configuration.logger.error(message.to_s)
16
+
17
+ raise error_class, message_from_error
18
+ end
19
+
20
+ private
21
+
22
+ def custom_class
23
+ Warb.configuration.custom_errors[@status]&.dig(code)
24
+ end
25
+
26
+ def message_from_error
27
+ details || message || "HTTP #{@status}"
28
+ end
29
+
30
+ def code
31
+ @code ||= @body.dig('error', 'code')
32
+ end
33
+
34
+ def message
35
+ @message ||= @body.dig('error', 'message')
36
+ end
37
+
38
+ def details
39
+ @details ||= @body.dig('error', 'error_data', 'details')
40
+ end
41
+ end
42
+ end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Warb
2
4
  class TemplateDispatcher < Dispatcher
3
5
  def list(**args)
4
6
  filter = args.slice(:limit, :fields, :after, :before)
5
- filter[:fields] = filter[:fields].join(",") if filter[:fields].is_a?(Array)
7
+ filter[:fields] = filter[:fields].join(',') if filter[:fields].is_a?(Array)
6
8
 
7
- @client.get("message_templates", endpoint_prefix: :business_id, data: filter).body
9
+ @client.get('message_templates', endpoint_prefix: :business_id, data: filter).body
8
10
  end
9
11
  end
10
12
  end
data/lib/warb/utils.rb CHANGED
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  def normalize
3
- unicode_normalize(:nfd).gsub(/\p{Mn}/, "")
5
+ unicode_normalize(:nfd).gsub(/\p{Mn}/, '')
4
6
  end
5
7
  end
data/lib/warb/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Warb
4
- VERSION = "0.1.0"
4
+ VERSION = '0.1.2'
5
5
  end
data/lib/warb.rb CHANGED
@@ -1,49 +1,57 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "faraday"
4
- require "faraday/multipart"
5
- require_relative "warb/version"
6
- require_relative "warb/language"
7
- require_relative "warb/configuration"
8
- require_relative "warb/dispatcher_concern"
9
- require_relative "warb/client"
10
- require_relative "warb/resources/resource"
11
- require_relative "warb/resources/text"
12
- require_relative "warb/resources/image"
13
- require_relative "warb/resources/video"
14
- require_relative "warb/resources/sticker"
15
- require_relative "warb/resources/audio"
16
- require_relative "warb/resources/document"
17
- require_relative "warb/resources/location"
18
- require_relative "warb/resources/reaction"
19
- require_relative "warb/resources/location_request"
20
- require_relative "warb/resources/interactive_reply_button"
21
- require_relative "warb/resources/interactive_list"
22
- require_relative "warb/resources/interactive_call_to_action_url"
23
- require_relative "warb/resources/contact"
24
- require_relative "warb/resources/template"
25
- require_relative "warb/resources/currency"
26
- require_relative "warb/resources/date_time"
27
- require_relative "warb/resources/flow"
28
- require_relative "warb/dispatcher"
29
- require_relative "warb/media_dispatcher"
30
- require_relative "warb/template_dispatcher"
31
- require_relative "warb/indicator_dispatcher"
32
- require_relative "warb/utils"
33
- require_relative "warb/components/component"
34
- require_relative "warb/components/button"
35
- require_relative "warb/components/quick_reply_button"
36
- require_relative "warb/components/url_button"
37
- require_relative "warb/components/copy_code_button"
38
- require_relative "warb/components/voice_call_button"
39
- require_relative "warb/components/action"
3
+ require 'faraday'
4
+ require 'faraday/multipart'
5
+ require_relative 'warb/version'
6
+ require_relative 'warb/language'
7
+ require_relative 'warb/configuration'
8
+ require_relative 'warb/dispatcher_concern'
9
+ require_relative 'warb/client'
10
+ require_relative 'warb/errors'
11
+ require_relative 'warb/response_error_handler'
12
+ require_relative 'warb/response'
13
+ require_relative 'warb/resources/resource'
14
+ require_relative 'warb/resources/text'
15
+ require_relative 'warb/resources/image'
16
+ require_relative 'warb/resources/video'
17
+ require_relative 'warb/resources/sticker'
18
+ require_relative 'warb/resources/audio'
19
+ require_relative 'warb/resources/document'
20
+ require_relative 'warb/resources/location'
21
+ require_relative 'warb/resources/reaction'
22
+ require_relative 'warb/resources/location_request'
23
+ require_relative 'warb/resources/interactive_reply_button'
24
+ require_relative 'warb/resources/interactive_list'
25
+ require_relative 'warb/resources/interactive_call_to_action_url'
26
+ require_relative 'warb/resources/contact'
27
+ require_relative 'warb/resources/template'
28
+ require_relative 'warb/resources/currency'
29
+ require_relative 'warb/resources/date_time'
30
+ require_relative 'warb/resources/flow'
31
+ require_relative 'warb/dispatcher'
32
+ require_relative 'warb/media_dispatcher'
33
+ require_relative 'warb/template_dispatcher'
34
+ require_relative 'warb/indicator_dispatcher'
35
+ require_relative 'warb/utils'
36
+ require_relative 'warb/components/component'
37
+ require_relative 'warb/components/button'
38
+ require_relative 'warb/components/quick_reply_button'
39
+ require_relative 'warb/components/url_button'
40
+ require_relative 'warb/components/copy_code_button'
41
+ require_relative 'warb/components/voice_call_button'
42
+ require_relative 'warb/components/action'
40
43
 
41
44
  module Warb
42
- MESSAGING_PRODUCT = "whatsapp"
43
- RECIPIENT_TYPE = "individual"
44
-
45
- class Error < StandardError; end
46
- # Your code goes here...
45
+ MESSAGING_PRODUCT = 'whatsapp'
46
+ RECIPIENT_TYPE = 'individual'
47
+ HTTP_ERRORS = {
48
+ 400 => BadRequest,
49
+ 401 => Unauthorized,
50
+ 403 => Forbidden,
51
+ 404 => NotFound,
52
+ 500 => InternalServerError,
53
+ 503 => ServiceUnavailable
54
+ }.freeze
47
55
 
48
56
  class << self
49
57
  include DispatcherConcern
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: warb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rebase
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2025-08-19 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: faraday
@@ -121,6 +122,7 @@ files:
121
122
  - lib/warb/connection.rb
122
123
  - lib/warb/dispatcher.rb
123
124
  - lib/warb/dispatcher_concern.rb
125
+ - lib/warb/errors.rb
124
126
  - lib/warb/indicator_dispatcher.rb
125
127
  - lib/warb/language.rb
126
128
  - lib/warb/media_dispatcher.rb
@@ -142,6 +144,8 @@ files:
142
144
  - lib/warb/resources/template.rb
143
145
  - lib/warb/resources/text.rb
144
146
  - lib/warb/resources/video.rb
147
+ - lib/warb/response.rb
148
+ - lib/warb/response_error_handler.rb
145
149
  - lib/warb/template_dispatcher.rb
146
150
  - lib/warb/utils.rb
147
151
  - lib/warb/version.rb
@@ -152,6 +156,8 @@ metadata:
152
156
  homepage_uri: https://github.com/Rebase-BR/warb
153
157
  source_code_uri: https://github.com/Rebase-BR/warb
154
158
  changelog_uri: https://github.com/Rebase-BR/warb/blob/main/CHANGELOG.md?ref_type=heads
159
+ rubygems_mfa_required: 'true'
160
+ post_install_message:
155
161
  rdoc_options: []
156
162
  require_paths:
157
163
  - lib
@@ -166,7 +172,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
172
  - !ruby/object:Gem::Version
167
173
  version: '0'
168
174
  requirements: []
169
- rubygems_version: 3.6.7
175
+ rubygems_version: 3.4.10
176
+ signing_key:
170
177
  specification_version: 4
171
178
  summary: A simple yet powerfull whatsapp api wrapper
172
179
  test_files: []