warb 0.1.4 → 1.0.0

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -12
  3. data/README.md +9 -32
  4. data/Rakefile +3 -3
  5. data/docs/README.md +1 -4
  6. data/docs/components/README.md +1 -4
  7. data/docs/messages/README.md +1 -2
  8. data/docs/messages/flow.md +5 -241
  9. data/docs/messages/interactive_call_to_action_url.md +9 -9
  10. data/docs/messages/interactive_list.md +2 -2
  11. data/docs/messages/interactive_reply_button.md +9 -9
  12. data/docs/setup.md +1 -45
  13. data/examples/audio.rb +10 -10
  14. data/examples/document.rb +34 -34
  15. data/examples/image.rb +22 -22
  16. data/examples/interactive_call_to_action_url.rb +46 -46
  17. data/examples/interactive_list.rb +61 -61
  18. data/examples/interactive_reply_button.rb +43 -43
  19. data/examples/location.rb +32 -32
  20. data/examples/location_request.rb +11 -11
  21. data/examples/message.rb +8 -8
  22. data/examples/sticker.rb +10 -10
  23. data/examples/video.rb +22 -22
  24. data/examples/webhook.rb +43 -77
  25. data/lib/warb/client.rb +5 -7
  26. data/lib/warb/components/action.rb +8 -12
  27. data/lib/warb/configuration.rb +1 -4
  28. data/lib/warb/connection.rb +9 -15
  29. data/lib/warb/dispatcher.rb +3 -4
  30. data/lib/warb/dispatcher_concern.rb +0 -6
  31. data/lib/warb/indicator_dispatcher.rb +4 -4
  32. data/lib/warb/media_dispatcher.rb +10 -10
  33. data/lib/warb/resources/audio.rb +1 -1
  34. data/lib/warb/resources/contact.rb +20 -22
  35. data/lib/warb/resources/document.rb +1 -1
  36. data/lib/warb/resources/flow.rb +20 -82
  37. data/lib/warb/resources/image.rb +1 -1
  38. data/lib/warb/resources/interactive_call_to_action_url.rb +8 -10
  39. data/lib/warb/resources/interactive_list.rb +5 -7
  40. data/lib/warb/resources/interactive_reply_button.rb +8 -10
  41. data/lib/warb/resources/location.rb +1 -11
  42. data/lib/warb/resources/location_request.rb +3 -5
  43. data/lib/warb/resources/reaction.rb +1 -1
  44. data/lib/warb/resources/resource.rb +4 -14
  45. data/lib/warb/resources/sticker.rb +1 -1
  46. data/lib/warb/resources/text.rb +3 -31
  47. data/lib/warb/resources/video.rb +1 -1
  48. data/lib/warb/utils.rb +1 -3
  49. data/lib/warb/version.rb +1 -1
  50. data/lib/warb.rb +31 -67
  51. metadata +3 -34
  52. data/docs/components/button.md +0 -62
  53. data/docs/components/copy_code_button.md +0 -57
  54. data/docs/components/flow_button.md +0 -102
  55. data/docs/components/url_button.md +0 -57
  56. data/docs/messages/template.md +0 -373
  57. data/docs/resources/README.md +0 -14
  58. data/docs/resources/currency.md +0 -22
  59. data/docs/resources/date_time.md +0 -11
  60. data/docs/resources/text.md +0 -9
  61. data/lib/warb/category.rb +0 -8
  62. data/lib/warb/components/button.rb +0 -29
  63. data/lib/warb/components/component.rb +0 -19
  64. data/lib/warb/components/copy_code_button.rb +0 -30
  65. data/lib/warb/components/flow_button.rb +0 -32
  66. data/lib/warb/components/quick_reply_button.rb +0 -15
  67. data/lib/warb/components/url_button.rb +0 -30
  68. data/lib/warb/components/voice_call_button.rb +0 -15
  69. data/lib/warb/errors.rb +0 -27
  70. data/lib/warb/language.rb +0 -8
  71. data/lib/warb/resources/currency.rb +0 -47
  72. data/lib/warb/resources/date_time.rb +0 -34
  73. data/lib/warb/resources/helpers/header.rb +0 -35
  74. data/lib/warb/resources/template.rb +0 -163
  75. data/lib/warb/resources/validation.rb +0 -30
  76. data/lib/warb/response.rb +0 -33
  77. data/lib/warb/response_error_handler.rb +0 -42
  78. data/lib/warb/template_dispatcher.rb +0 -21
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Warb
4
- module Resources
5
- class Currency < Resource
6
- BRL = 'BRL'
7
- USD = 'USD'
8
-
9
- attr_accessor :amount, :code, :fallback
10
-
11
- def initialize(**params)
12
- super
13
-
14
- @code = params[:code]
15
- @amount = params[:amount]
16
- @fallback = params[:fallback]
17
- end
18
-
19
- def build_template_named_parameter(parameter_name)
20
- common_currency_params.merge(parameter_name: parameter_name)
21
- end
22
-
23
- def build_template_positional_parameter
24
- common_currency_params
25
- end
26
-
27
- private
28
-
29
- # rubocop:disable Naming/VariableNumber
30
- def common_currency_params
31
- {
32
- type: 'currency',
33
- currency: {
34
- amount_1000: amount * 1000,
35
- code: code,
36
- fallback_value: fallback || default_fallback_value
37
- }
38
- }
39
- end
40
- # rubocop:enable Naming/VariableNumber
41
-
42
- def default_fallback_value
43
- "#{amount} (#{code})"
44
- end
45
- end
46
- end
47
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Warb
4
- module Resources
5
- class DateTime < Resource
6
- attr_accessor :date_time
7
-
8
- def initialize(date_time = nil, **params)
9
- super(**params)
10
-
11
- @date_time = date_time || params[:date_time]
12
- end
13
-
14
- def build_template_named_parameter(parameter_name)
15
- common_date_time_params.merge(parameter_name: parameter_name)
16
- end
17
-
18
- def build_template_positional_parameter
19
- common_date_time_params
20
- end
21
-
22
- private
23
-
24
- def common_date_time_params
25
- {
26
- type: 'date_time',
27
- date_time: {
28
- fallback_value: date_time
29
- }
30
- }
31
- end
32
- end
33
- end
34
- end
@@ -1,35 +0,0 @@
1
- module Warb
2
- module Resources
3
- module Helpers
4
- module Header
5
- def add_text_header(content: nil, message: nil, text: nil, parameter_name: nil, &block)
6
- add_header(Warb::Resources::Text.new(content:, message:, text:, parameter_name:), &block)
7
- end
8
-
9
- def add_image_header(media_id: nil, link: nil, &block)
10
- add_header(Warb::Resources::Image.new(media_id:, link:), &block)
11
- end
12
-
13
- def add_document_header(media_id: nil, link: nil, filename: nil, &block)
14
- add_header(Warb::Resources::Document.new(media_id:, link:, filename:), &block)
15
- end
16
-
17
- def add_video_header(media_id: nil, link: nil, &block)
18
- add_header(Warb::Resources::Video.new(media_id:, link:), &block)
19
- end
20
-
21
- def add_location_header(latitude: nil, longitude: nil, address: nil, name: nil, &block)
22
- add_header(Warb::Resources::Location.new(latitude:, longitude:, address:, name:), &block)
23
- end
24
-
25
- private
26
-
27
- def add_header(instance, &)
28
- @header = instance
29
-
30
- block_given? ? @header.tap(&) : @header
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,163 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Warb
4
- module Resources
5
- class Template < Resource
6
- include Helpers::Header
7
-
8
- attr_accessor :name, :language, :resources, :header, :category, :body, :buttons
9
-
10
- def initialize(**params)
11
- super
12
-
13
- @name = params[:name]
14
- @language = params[:language]
15
- @resources = params[:resources]
16
- @category = params[:category]
17
- @body = params[:body]
18
- @buttons = []
19
- end
20
-
21
- # rubocop:disable Metrics/MethodLength
22
- def build_payload
23
- {
24
- type: 'template',
25
- template: {
26
- name: name,
27
- language: {
28
- code: language
29
- },
30
- components: [
31
- component_header,
32
- component_body,
33
- *buttons
34
- ].compact
35
- }
36
- }
37
- end
38
- # rubocop:enable Metrics/MethodLength
39
-
40
- def creation_payload
41
- {
42
- name: name,
43
- language: language,
44
- category: category,
45
- components: [
46
- body&.build_template_example_parameter
47
- ].compact
48
- }
49
- end
50
-
51
- def add_currency_parameter(parameter_name = nil, **params, &)
52
- add_parameter(parameter_name, Currency.new(**params), &)
53
- end
54
-
55
- def add_date_time_parameter(parameter_name = nil, **params, &)
56
- add_parameter(parameter_name, DateTime.new(**params), &)
57
- end
58
-
59
- def add_text_parameter(parameter_name = nil, **params, &)
60
- add_parameter(parameter_name, Text.new(**params), &)
61
- end
62
-
63
- def add_quick_reply_button(index: position, &block)
64
- add_button(Warb::Components::QuickReplyButton.new(index:), &block)
65
- end
66
-
67
- def add_dynamic_url_button(index: position, text: nil, &block)
68
- add_button(Warb::Components::UrlButton.new(index:, text:), &block)
69
- end
70
-
71
- alias add_auth_code_button add_dynamic_url_button
72
-
73
- def add_copy_code_button(index: position, coupon_code: nil, &block)
74
- add_button(Warb::Components::CopyCodeButton.new(index:, coupon_code:), &block)
75
- end
76
-
77
- def add_voice_call_button(index: position, &block)
78
- add_button(Warb::Components::VoiceCallButton.new(index:), &block)
79
- end
80
-
81
- def add_flow_button(index: position, flow_token: nil, flow_action_data: nil, &block)
82
- add_button(
83
- Warb::Components::FlowButton.new(index: index, flow_token: flow_token,
84
- flow_action_data: flow_action_data), &block
85
- )
86
- end
87
-
88
- def add_button(instance, &)
89
- return @buttons << instance.to_h unless block_given?
90
-
91
- @buttons << instance.tap(&).to_h
92
- end
93
-
94
- private
95
-
96
- def component_header
97
- return unless header.is_a? Resource
98
-
99
- {
100
- type: 'header',
101
- parameters: [
102
- header.build_header
103
- ]
104
- }
105
- end
106
-
107
- def component_body
108
- return if resources.nil? || resources.empty?
109
-
110
- {
111
- type: 'body',
112
- parameters: build_parameters
113
- }
114
- end
115
-
116
- def build_parameters
117
- case resources
118
- when Hash
119
- named_parameters
120
- when Array
121
- positional_parameters
122
- end
123
- end
124
-
125
- def named_parameters
126
- resources.map do |parameter_name, resource|
127
- resource.build_template_named_parameter(parameter_name.to_s)
128
- end
129
- end
130
-
131
- def positional_parameters
132
- resources.map(&:build_template_positional_parameter)
133
- end
134
-
135
- def add_parameter(parameter_name, instance, &)
136
- case resources
137
- when Hash
138
- resources[parameter_name.to_s] = instance
139
- when Array
140
- resources << instance
141
- else
142
- initialize_resources(parameter_name, instance, &)
143
- end
144
-
145
- block_given? ? instance.tap(&) : instance
146
- end
147
-
148
- def initialize_resources(parameter_name, instance)
149
- if parameter_name.nil?
150
- @resources = []
151
- @resources << instance
152
- else
153
- @resources = {}
154
- @resources[parameter_name] = instance
155
- end
156
- end
157
-
158
- def position
159
- buttons.count
160
- end
161
- end
162
- end
163
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Warb
4
- module Resources
5
- module Validation
6
- def blank?(val)
7
- val.respond_to?(:empty?) ? val.empty? : !val
8
- end
9
-
10
- def raw_value(field)
11
- respond_to?(field) ? public_send(field) : nil
12
- end
13
-
14
- def resolve(field, default = nil)
15
- val = raw_value(field)
16
- val = @params[field] if blank?(val) && defined?(@params) && @params&.key?(field)
17
- val = default if blank?(val) && !default.nil?
18
- val
19
- end
20
-
21
- def validates(field, required: false, message: nil)
22
- needed = required.respond_to?(:call) ? required.call : required
23
- return unless needed
24
- return unless blank?(resolve(field))
25
-
26
- raise ArgumentError, (message || "#{field} is required")
27
- end
28
- end
29
- end
30
- end
data/lib/warb/response.rb DELETED
@@ -1,33 +0,0 @@
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
@@ -1,42 +0,0 @@
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 ? "(##{code}) #{details}" : message
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,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Warb
4
- class TemplateDispatcher < Dispatcher
5
- def create(**args)
6
- template = Resources::Template.new(**args)
7
- @client.post('message_templates', template.creation_payload, endpoint_prefix: :business_id)
8
- end
9
-
10
- def delete(template_name)
11
- @client.delete('message_templates', { name: template_name }, endpoint_prefix: :business_id).body
12
- end
13
-
14
- def list(**args)
15
- filter = args.slice(:limit, :fields, :after, :before)
16
- filter[:fields] = filter[:fields].join(',') if filter[:fields].is_a?(Array)
17
-
18
- @client.get('message_templates', endpoint_prefix: :business_id, data: filter).body
19
- end
20
- end
21
- end