ruby-whatsapp 0.3.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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +54 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +15 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +643 -0
- data/Rakefile +12 -0
- data/lib/ruby/whatsapp/client.rb +82 -0
- data/lib/ruby/whatsapp/configuration.rb +79 -0
- data/lib/ruby/whatsapp/instrumentation.rb +34 -0
- data/lib/ruby/whatsapp/media.rb +134 -0
- data/lib/ruby/whatsapp/message_templates/button/base.rb +26 -0
- data/lib/ruby/whatsapp/message_templates/button/copy_code.rb +59 -0
- data/lib/ruby/whatsapp/message_templates/button/otp/supported_app.rb +44 -0
- data/lib/ruby/whatsapp/message_templates/button/otp.rb +138 -0
- data/lib/ruby/whatsapp/message_templates/button/phone_number.rb +45 -0
- data/lib/ruby/whatsapp/message_templates/button/quick_reply.rb +38 -0
- data/lib/ruby/whatsapp/message_templates/button/url.rb +110 -0
- data/lib/ruby/whatsapp/message_templates/button.rb +56 -0
- data/lib/ruby/whatsapp/message_templates/categories.rb +47 -0
- data/lib/ruby/whatsapp/message_templates/component/base.rb +112 -0
- data/lib/ruby/whatsapp/message_templates/component/body.rb +139 -0
- data/lib/ruby/whatsapp/message_templates/component/buttons.rb +95 -0
- data/lib/ruby/whatsapp/message_templates/component/carousel/card.rb +100 -0
- data/lib/ruby/whatsapp/message_templates/component/carousel.rb +71 -0
- data/lib/ruby/whatsapp/message_templates/component/footer.rb +99 -0
- data/lib/ruby/whatsapp/message_templates/component/header.rb +188 -0
- data/lib/ruby/whatsapp/message_templates/component/limited_time_offer.rb +57 -0
- data/lib/ruby/whatsapp/message_templates/component.rb +62 -0
- data/lib/ruby/whatsapp/message_templates/component_set.rb +221 -0
- data/lib/ruby/whatsapp/message_templates/example.rb +148 -0
- data/lib/ruby/whatsapp/message_templates/library_template/body_inputs.rb +81 -0
- data/lib/ruby/whatsapp/message_templates/library_template/button_inputs.rb +146 -0
- data/lib/ruby/whatsapp/message_templates/library_template.rb +114 -0
- data/lib/ruby/whatsapp/message_templates/parameter_formats.rb +49 -0
- data/lib/ruby/whatsapp/message_templates/placeholders.rb +86 -0
- data/lib/ruby/whatsapp/message_templates/response/collection.rb +74 -0
- data/lib/ruby/whatsapp/message_templates/response/created.rb +65 -0
- data/lib/ruby/whatsapp/message_templates/response/node.rb +152 -0
- data/lib/ruby/whatsapp/message_templates/response/paging.rb +39 -0
- data/lib/ruby/whatsapp/message_templates/response/quality_score.rb +49 -0
- data/lib/ruby/whatsapp/message_templates/response/summary.rb +68 -0
- data/lib/ruby/whatsapp/message_templates/response.rb +22 -0
- data/lib/ruby/whatsapp/message_templates/statuses.rb +66 -0
- data/lib/ruby/whatsapp/message_templates/template.rb +180 -0
- data/lib/ruby/whatsapp/message_templates/value_object.rb +62 -0
- data/lib/ruby/whatsapp/message_templates.rb +283 -0
- data/lib/ruby/whatsapp/messages/address.rb +103 -0
- data/lib/ruby/whatsapp/messages/audio.rb +64 -0
- data/lib/ruby/whatsapp/messages/base.rb +46 -0
- data/lib/ruby/whatsapp/messages/contacts/address.rb +84 -0
- data/lib/ruby/whatsapp/messages/contacts/contact.rb +78 -0
- data/lib/ruby/whatsapp/messages/contacts/email.rb +49 -0
- data/lib/ruby/whatsapp/messages/contacts/name.rb +68 -0
- data/lib/ruby/whatsapp/messages/contacts/org.rb +41 -0
- data/lib/ruby/whatsapp/messages/contacts/phone.rb +59 -0
- data/lib/ruby/whatsapp/messages/contacts/url.rb +51 -0
- data/lib/ruby/whatsapp/messages/contacts.rb +37 -0
- data/lib/ruby/whatsapp/messages/document.rb +79 -0
- data/lib/ruby/whatsapp/messages/image.rb +72 -0
- data/lib/ruby/whatsapp/messages/interactive/base.rb +15 -0
- data/lib/ruby/whatsapp/messages/interactive/body.rb +39 -0
- data/lib/ruby/whatsapp/messages/interactive/footer.rb +40 -0
- data/lib/ruby/whatsapp/messages/interactive/header.rb +102 -0
- data/lib/ruby/whatsapp/messages/interactive/list_buttons/section/row.rb +66 -0
- data/lib/ruby/whatsapp/messages/interactive/list_buttons/section.rb +64 -0
- data/lib/ruby/whatsapp/messages/interactive/list_buttons.rb +63 -0
- data/lib/ruby/whatsapp/messages/interactive/media_carousel/card/button/quick_reply.rb +50 -0
- data/lib/ruby/whatsapp/messages/interactive/media_carousel/card/button.rb +47 -0
- data/lib/ruby/whatsapp/messages/interactive/media_carousel/card.rb +78 -0
- data/lib/ruby/whatsapp/messages/interactive/media_carousel.rb +50 -0
- data/lib/ruby/whatsapp/messages/interactive/product_carousel/card.rb +55 -0
- data/lib/ruby/whatsapp/messages/interactive/product_carousel.rb +50 -0
- data/lib/ruby/whatsapp/messages/interactive/reply_buttons/button.rb +59 -0
- data/lib/ruby/whatsapp/messages/interactive/reply_buttons.rb +47 -0
- data/lib/ruby/whatsapp/messages/interactive/url_button.rb +68 -0
- data/lib/ruby/whatsapp/messages/interactive.rb +112 -0
- data/lib/ruby/whatsapp/messages/location.rb +67 -0
- data/lib/ruby/whatsapp/messages/location_request.rb +41 -0
- data/lib/ruby/whatsapp/messages/mark_message_as_read.rb +42 -0
- data/lib/ruby/whatsapp/messages/reaction.rb +61 -0
- data/lib/ruby/whatsapp/messages/response/contacts.rb +36 -0
- data/lib/ruby/whatsapp/messages/response/messages.rb +27 -0
- data/lib/ruby/whatsapp/messages/response.rb +49 -0
- data/lib/ruby/whatsapp/messages/sticker.rb +62 -0
- data/lib/ruby/whatsapp/messages/template/component.rb +67 -0
- data/lib/ruby/whatsapp/messages/template/language.rb +55 -0
- data/lib/ruby/whatsapp/messages/template/parameter.rb +113 -0
- data/lib/ruby/whatsapp/messages/template.rb +62 -0
- data/lib/ruby/whatsapp/messages/text.rb +43 -0
- data/lib/ruby/whatsapp/messages/video.rb +68 -0
- data/lib/ruby/whatsapp/messages.rb +116 -0
- data/lib/ruby/whatsapp/railtie.rb +14 -0
- data/lib/ruby/whatsapp/request_error.rb +5 -0
- data/lib/ruby/whatsapp/response_handling.rb +44 -0
- data/lib/ruby/whatsapp/utils/language_codes.rb +96 -0
- data/lib/ruby/whatsapp/version.rb +5 -0
- data/lib/ruby/whatsapp/webhook/account_alerts.rb +58 -0
- data/lib/ruby/whatsapp/webhook/account_review_update.rb +27 -0
- data/lib/ruby/whatsapp/webhook/account_update/ban_info.rb +33 -0
- data/lib/ruby/whatsapp/webhook/account_update.rb +46 -0
- data/lib/ruby/whatsapp/webhook/automatic_events.rb +43 -0
- data/lib/ruby/whatsapp/webhook/business_capability_update.rb +36 -0
- data/lib/ruby/whatsapp/webhook/change.rb +61 -0
- data/lib/ruby/whatsapp/webhook/contact.rb +36 -0
- data/lib/ruby/whatsapp/webhook/entry.rb +35 -0
- data/lib/ruby/whatsapp/webhook/error.rb +47 -0
- data/lib/ruby/whatsapp/webhook/history.rb +54 -0
- data/lib/ruby/whatsapp/webhook/installer.rb +61 -0
- data/lib/ruby/whatsapp/webhook/message/audio.rb +28 -0
- data/lib/ruby/whatsapp/webhook/message/base.rb +61 -0
- data/lib/ruby/whatsapp/webhook/message/button.rb +33 -0
- data/lib/ruby/whatsapp/webhook/message/contacts/address.rb +68 -0
- data/lib/ruby/whatsapp/webhook/message/contacts/contact.rb +68 -0
- data/lib/ruby/whatsapp/webhook/message/contacts/email.rb +35 -0
- data/lib/ruby/whatsapp/webhook/message/contacts/name.rb +62 -0
- data/lib/ruby/whatsapp/webhook/message/contacts/org.rb +40 -0
- data/lib/ruby/whatsapp/webhook/message/contacts/phone.rb +40 -0
- data/lib/ruby/whatsapp/webhook/message/contacts/url.rb +35 -0
- data/lib/ruby/whatsapp/webhook/message/contacts.rb +31 -0
- data/lib/ruby/whatsapp/webhook/message/context.rb +49 -0
- data/lib/ruby/whatsapp/webhook/message/document.rb +32 -0
- data/lib/ruby/whatsapp/webhook/message/image.rb +18 -0
- data/lib/ruby/whatsapp/webhook/message/interactive.rb +53 -0
- data/lib/ruby/whatsapp/webhook/message/location.rb +49 -0
- data/lib/ruby/whatsapp/webhook/message/media.rb +54 -0
- data/lib/ruby/whatsapp/webhook/message/order/product_item.rb +50 -0
- data/lib/ruby/whatsapp/webhook/message/order.rb +43 -0
- data/lib/ruby/whatsapp/webhook/message/reaction.rb +37 -0
- data/lib/ruby/whatsapp/webhook/message/referral.rb +80 -0
- data/lib/ruby/whatsapp/webhook/message/sticker.rb +32 -0
- data/lib/ruby/whatsapp/webhook/message/system.rb +49 -0
- data/lib/ruby/whatsapp/webhook/message/text.rb +28 -0
- data/lib/ruby/whatsapp/webhook/message/unknown.rb +39 -0
- data/lib/ruby/whatsapp/webhook/message/video.rb +18 -0
- data/lib/ruby/whatsapp/webhook/message.rb +39 -0
- data/lib/ruby/whatsapp/webhook/message_template_components_update.rb +53 -0
- data/lib/ruby/whatsapp/webhook/message_template_quality_update.rb +59 -0
- data/lib/ruby/whatsapp/webhook/message_template_status_update.rb +54 -0
- data/lib/ruby/whatsapp/webhook/messages.rb +55 -0
- data/lib/ruby/whatsapp/webhook/metadata.rb +35 -0
- data/lib/ruby/whatsapp/webhook/notification.rb +36 -0
- data/lib/ruby/whatsapp/webhook/partner_solutions.rb +36 -0
- data/lib/ruby/whatsapp/webhook/payment_configuration_update.rb +51 -0
- data/lib/ruby/whatsapp/webhook/phone_number_name_update.rb +51 -0
- data/lib/ruby/whatsapp/webhook/phone_number_quality_update.rb +45 -0
- data/lib/ruby/whatsapp/webhook/security.rb +41 -0
- data/lib/ruby/whatsapp/webhook/signature.rb +28 -0
- data/lib/ruby/whatsapp/webhook/smb_app_state_sync/state_sync.rb +38 -0
- data/lib/ruby/whatsapp/webhook/smb_app_state_sync.rb +33 -0
- data/lib/ruby/whatsapp/webhook/smb_message_echoes.rb +48 -0
- data/lib/ruby/whatsapp/webhook/status/conversation.rb +42 -0
- data/lib/ruby/whatsapp/webhook/status/pricing.rb +38 -0
- data/lib/ruby/whatsapp/webhook/status.rb +65 -0
- data/lib/ruby/whatsapp/webhook/template_category_update.rb +64 -0
- data/lib/ruby/whatsapp/webhook/templates/webhooks_controller.rb.tt +31 -0
- data/lib/ruby/whatsapp/webhook/unknown_field.rb +37 -0
- data/lib/ruby/whatsapp/webhook/user_preferences.rb +47 -0
- data/lib/ruby/whatsapp/webhook/verification.rb +27 -0
- data/lib/ruby/whatsapp/webhook.rb +8 -0
- data/lib/ruby/whatsapp.rb +49 -0
- data/lib/tasks/whatsapp.rake +10 -0
- data/sig/ruby/whatsapp.rbs +6 -0
- metadata +267 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class Body < Base
|
|
7
|
+
module Defaults
|
|
8
|
+
MAX_TEXT_LENGTH = 1024
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @!attribute [rw] text
|
|
12
|
+
# @return [String]
|
|
13
|
+
attr_accessor :text
|
|
14
|
+
|
|
15
|
+
validates :text, presence: true, length: { maximum: Defaults::MAX_TEXT_LENGTH }
|
|
16
|
+
# @param text [String] The footer text.
|
|
17
|
+
def initialize(text)
|
|
18
|
+
@text = text
|
|
19
|
+
|
|
20
|
+
validate!
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
# @return [Hash] Serialized representation of the Header.
|
|
25
|
+
def serialize(text)
|
|
26
|
+
new(text).serialize
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [Hash] Serialized representation of the Header.
|
|
31
|
+
def serialize
|
|
32
|
+
{
|
|
33
|
+
text:,
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class Footer < Base
|
|
7
|
+
module Defaults
|
|
8
|
+
MAX_TEXT_LENGTH = 60
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @!attribute [rw] text
|
|
12
|
+
# @return [String]
|
|
13
|
+
attr_accessor :text
|
|
14
|
+
|
|
15
|
+
validates :text, presence: true, length: { maximum: Defaults::MAX_TEXT_LENGTH }
|
|
16
|
+
|
|
17
|
+
# @param text [String] The footer text.
|
|
18
|
+
def initialize(text)
|
|
19
|
+
@text = text
|
|
20
|
+
|
|
21
|
+
validate!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class << self
|
|
25
|
+
# @return [Hash] Serialized representation of the Header.
|
|
26
|
+
def serialize(text:)
|
|
27
|
+
new(text).serialize
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @return [Hash] Serialized representation of the Header.
|
|
32
|
+
def serialize
|
|
33
|
+
{
|
|
34
|
+
text:,
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class Header < Base
|
|
7
|
+
class HeaderError < Whatsapp::Error; end
|
|
8
|
+
|
|
9
|
+
module Types
|
|
10
|
+
IMAGE = "image"
|
|
11
|
+
VIDEO = "video"
|
|
12
|
+
DOCUMENT = "document"
|
|
13
|
+
TEXT = "text"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @!attribute [rw] type
|
|
17
|
+
# @return [String]
|
|
18
|
+
attr_accessor :type
|
|
19
|
+
|
|
20
|
+
validates :type, presence: true, inclusion: { in: Types.constants.map { |c| Types.const_get(c) } }
|
|
21
|
+
validate :validate_text_length
|
|
22
|
+
|
|
23
|
+
# @param type [String] The type of the header (e.g., "text", "image", "video", "document").
|
|
24
|
+
# @param kwargs [Hash] Additional keyword arguments for the header content.
|
|
25
|
+
def initialize(type:, **kwargs)
|
|
26
|
+
@type = type
|
|
27
|
+
@kwargs = kwargs
|
|
28
|
+
|
|
29
|
+
validate!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class << self
|
|
33
|
+
# @return [Hash] Serialized representation of the Header.
|
|
34
|
+
def serialize(type:, **)
|
|
35
|
+
new(type:, **).serialize
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [Hash] Serialized representation of the Header.
|
|
40
|
+
def serialize
|
|
41
|
+
case type
|
|
42
|
+
when Types::TEXT then serialize_text
|
|
43
|
+
when Types::IMAGE then serialize_image
|
|
44
|
+
when Types::DOCUMENT then serialize_document
|
|
45
|
+
when Types::VIDEO then serialize_video
|
|
46
|
+
else
|
|
47
|
+
raise HeaderError, "Unsupported header type: #{type.inspect}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
# @return [Hash] Serialized representation of text header.
|
|
54
|
+
def serialize_text
|
|
55
|
+
raise HeaderError, "Text content is required for text header" unless @kwargs[:text]
|
|
56
|
+
|
|
57
|
+
{
|
|
58
|
+
type: Types::TEXT,
|
|
59
|
+
text: @kwargs[:text],
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [Hash] Serialized representation of media header.
|
|
64
|
+
def serialize_image
|
|
65
|
+
handle_media(Types::IMAGE)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @return [Hash] Serialized representation of media header.
|
|
69
|
+
def serialize_document
|
|
70
|
+
handle_media(Types::DOCUMENT)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [Hash] Serialized representation of media header.
|
|
74
|
+
def serialize_video
|
|
75
|
+
handle_media(Types::VIDEO)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @return [Hash] Serialized representation of media header.
|
|
79
|
+
# @raise [HeaderError] if required link is missing.
|
|
80
|
+
def handle_media(type)
|
|
81
|
+
raise HeaderError, "#{type.capitalize} link is required for #{type} header" unless @kwargs[:link]
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
type:,
|
|
85
|
+
type.to_sym => {
|
|
86
|
+
link: @kwargs[:link],
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Validates that text headers don't exceed 60 characters
|
|
92
|
+
def validate_text_length
|
|
93
|
+
return unless type == Types::TEXT && @kwargs[:text]
|
|
94
|
+
|
|
95
|
+
return unless @kwargs[:text].length > 60
|
|
96
|
+
|
|
97
|
+
errors.add(:text, "must be 60 characters or less")
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class ListButtons
|
|
7
|
+
class Section
|
|
8
|
+
class Row
|
|
9
|
+
include ActiveModel::Validations
|
|
10
|
+
|
|
11
|
+
module Defaults
|
|
12
|
+
MAX_ID_LENGTH = 200
|
|
13
|
+
MAX_TITLE_LENGTH = 24
|
|
14
|
+
MAX_DESCRIPTION_LENGTH = 72
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @!attribute [rw] id
|
|
18
|
+
# @return [String]
|
|
19
|
+
attr_accessor :id
|
|
20
|
+
|
|
21
|
+
# @!attribute [rw] title
|
|
22
|
+
# @return [String]
|
|
23
|
+
attr_accessor :title
|
|
24
|
+
|
|
25
|
+
# @!attribute [rw] description
|
|
26
|
+
# @return [String, nil]
|
|
27
|
+
attr_accessor :description
|
|
28
|
+
|
|
29
|
+
validates :id, presence: true, length: { maximum: Defaults::MAX_ID_LENGTH }
|
|
30
|
+
validates :title, presence: true, length: { maximum: Defaults::MAX_TITLE_LENGTH }
|
|
31
|
+
validates :description, length: { maximum: Defaults::MAX_DESCRIPTION_LENGTH }, allow_nil: true
|
|
32
|
+
|
|
33
|
+
# @param id [String] The unique identifier for the row.
|
|
34
|
+
# @param title [String] The title of the row.
|
|
35
|
+
# @param description [String, nil] The description of the row.
|
|
36
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
37
|
+
def initialize(id:, title:, description: nil)
|
|
38
|
+
@id = id
|
|
39
|
+
@title = title
|
|
40
|
+
@description = description
|
|
41
|
+
|
|
42
|
+
validate!
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class << self
|
|
46
|
+
# @return [Hash] Serialized representation of the Row.
|
|
47
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
48
|
+
def serialize(**row)
|
|
49
|
+
new(**row).serialize
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [Hash] Serialized representation of the Row.
|
|
54
|
+
def serialize
|
|
55
|
+
{
|
|
56
|
+
id:,
|
|
57
|
+
title:,
|
|
58
|
+
description:,
|
|
59
|
+
}.compact
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class ListButtons
|
|
7
|
+
class Section
|
|
8
|
+
include ActiveModel::Validations
|
|
9
|
+
|
|
10
|
+
module Defaults
|
|
11
|
+
MAX_TITLE_LENGTH = 24
|
|
12
|
+
MIN_ROWS_LENGTH = 1
|
|
13
|
+
MAX_ROWS_LENGTH = 10
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @!attribute [rw] title
|
|
17
|
+
# @return [String]
|
|
18
|
+
attr_accessor :title
|
|
19
|
+
|
|
20
|
+
# @!attribute [rw] rows
|
|
21
|
+
# @return [Array<Hash>]
|
|
22
|
+
attr_accessor :rows
|
|
23
|
+
|
|
24
|
+
validates :title, presence: true, length: { maximum: Defaults::MAX_TITLE_LENGTH }
|
|
25
|
+
validates :rows, presence: true, length: { minimum: Defaults::MIN_ROWS_LENGTH, maximum: Defaults::MAX_ROWS_LENGTH }
|
|
26
|
+
|
|
27
|
+
# @param title [String] The title of the section.
|
|
28
|
+
# @param rows [Array<Hash>] The rows in the section.
|
|
29
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
30
|
+
def initialize(title:, rows:)
|
|
31
|
+
@title = title
|
|
32
|
+
@rows = rows
|
|
33
|
+
|
|
34
|
+
validate!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
# @return [Hash] Serialized representation of the Section.
|
|
39
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
40
|
+
def serialize(**section)
|
|
41
|
+
new(**section).serialize
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @return [Hash] Serialized representation of the Section.
|
|
46
|
+
def serialize
|
|
47
|
+
{
|
|
48
|
+
title:,
|
|
49
|
+
rows: serialized_rows,
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
# @return [Array<Hash>] Serialized rows.
|
|
56
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
57
|
+
def serialized_rows
|
|
58
|
+
rows.map { |row| Row.serialize(**row) }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
# Interactive list messages allow you to present WhatsApp users with a list of options to choose from
|
|
7
|
+
# Source: https://developers.facebook.com/documentation/business-messaging/whatsapp/messages/interactive-list-messages
|
|
8
|
+
class ListButtons < Base
|
|
9
|
+
module Defaults
|
|
10
|
+
MAX_BUTTON_LENGTH = 20
|
|
11
|
+
MIN_SECTIONS_COUNT = 1
|
|
12
|
+
MAX_SECTIONS_COUNT = 10
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @!attribute [rw] button
|
|
16
|
+
# @return [String]
|
|
17
|
+
attr_accessor :button
|
|
18
|
+
|
|
19
|
+
# @!attribute [rw] sections
|
|
20
|
+
# @return [Array<Hash>]
|
|
21
|
+
attr_accessor :sections
|
|
22
|
+
|
|
23
|
+
validates :button, presence: true, length: { maximum: Defaults::MAX_BUTTON_LENGTH }
|
|
24
|
+
validates :sections, presence: true, length: { minimum: Defaults::MIN_SECTIONS_COUNT,
|
|
25
|
+
maximum: Defaults::MAX_SECTIONS_COUNT, }
|
|
26
|
+
|
|
27
|
+
# @param button [String] The text for the list button.
|
|
28
|
+
# @param sections [Array<Hash>] The sections of the list button.
|
|
29
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
30
|
+
def initialize(button:, sections:)
|
|
31
|
+
@button = button
|
|
32
|
+
@sections = sections
|
|
33
|
+
|
|
34
|
+
validate!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
# @return [Hash] Serialized representation of the ListButtons.
|
|
39
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
40
|
+
def serialize(**list_buttons)
|
|
41
|
+
new(**list_buttons).serialize
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @return [Hash] Serialized representation of the ListButtons.
|
|
46
|
+
def serialize
|
|
47
|
+
{
|
|
48
|
+
button:,
|
|
49
|
+
sections: serialized_sections,
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
# @return [Array<Hash>] Serialized sections.
|
|
56
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
57
|
+
def serialized_sections
|
|
58
|
+
sections.map { |section| Section.serialize(**section) }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class MediaCarousel
|
|
7
|
+
class Card
|
|
8
|
+
class Button
|
|
9
|
+
class QuickReply
|
|
10
|
+
include ActiveModel::Validations
|
|
11
|
+
|
|
12
|
+
# @!attribute [rw] id
|
|
13
|
+
# @return [String]
|
|
14
|
+
attr_accessor :id
|
|
15
|
+
|
|
16
|
+
# @!attribute [rw] title
|
|
17
|
+
# @return [String]
|
|
18
|
+
attr_accessor :title
|
|
19
|
+
|
|
20
|
+
validates :id, presence: true, length: { maximum: 20 }
|
|
21
|
+
validates :title, presence: true, length: { maximum: 20 }
|
|
22
|
+
|
|
23
|
+
# @param id [String] The ID of the quick reply button.
|
|
24
|
+
# @param title [String] The title of the quick reply button.
|
|
25
|
+
def initialize(id:, title:)
|
|
26
|
+
@id = id
|
|
27
|
+
@title = title
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
# @return [Hash] Serialized representation of the QuickReply.
|
|
32
|
+
def serialize(id:, title:)
|
|
33
|
+
new(id:, title:).serialize
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @return [Hash] Serialized representation of the QuickReply.
|
|
38
|
+
def serialize
|
|
39
|
+
{
|
|
40
|
+
id:,
|
|
41
|
+
title:,
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class MediaCarousel
|
|
7
|
+
class Card
|
|
8
|
+
class Button
|
|
9
|
+
module Defaults
|
|
10
|
+
BUTTON_TYPE = "quick_reply"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @!attribute [rw] quick_reply
|
|
14
|
+
# @return [Hash]
|
|
15
|
+
attr_accessor :quick_reply
|
|
16
|
+
|
|
17
|
+
# @param quick_reply [Hash] The quick reply content of the button.
|
|
18
|
+
def initialize(quick_reply:)
|
|
19
|
+
@quick_reply = quick_reply
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class << self
|
|
23
|
+
# @return [Hash] Serialized representation of the Button.
|
|
24
|
+
def serialize(quick_reply:)
|
|
25
|
+
new(quick_reply:).serialize
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [Hash] Serialized representation of the Button.
|
|
30
|
+
def serialize
|
|
31
|
+
{
|
|
32
|
+
type: Defaults::BUTTON_TYPE,
|
|
33
|
+
quick_reply: serialized_quick_reply,
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def serialized_quick_reply
|
|
40
|
+
QuickReply.serialize(**quick_reply)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class MediaCarousel
|
|
7
|
+
class Card
|
|
8
|
+
include ActiveModel::Validations
|
|
9
|
+
|
|
10
|
+
module Defaults
|
|
11
|
+
TYPE = "cta_url"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @!attribute [rw] card_index
|
|
15
|
+
# @return [Integer]
|
|
16
|
+
attr_accessor :card_index
|
|
17
|
+
|
|
18
|
+
# @!attribute [rw] header
|
|
19
|
+
# @return [Hash]
|
|
20
|
+
attr_accessor :header
|
|
21
|
+
|
|
22
|
+
# @!attribute [rw] body
|
|
23
|
+
# @return [String]
|
|
24
|
+
attr_accessor :body
|
|
25
|
+
|
|
26
|
+
# @!attribute [rw] action
|
|
27
|
+
# @return [Hash]
|
|
28
|
+
attr_accessor :action
|
|
29
|
+
|
|
30
|
+
# @!attribute [rw] buttons
|
|
31
|
+
# @return [Array<Hash>]
|
|
32
|
+
attr_accessor :buttons
|
|
33
|
+
|
|
34
|
+
validates :card_index, presence: true
|
|
35
|
+
|
|
36
|
+
# @param card_index [Integer] The index of the card.
|
|
37
|
+
# @param header [Hash] The header content of the card.
|
|
38
|
+
# @param body [String] The body content of the card.
|
|
39
|
+
# @param action [Hash] The action content of the card.
|
|
40
|
+
def initialize(card_index:, header:, body:, action:, buttons:)
|
|
41
|
+
@card_index = card_index
|
|
42
|
+
@header = header
|
|
43
|
+
@body = body
|
|
44
|
+
@action = action
|
|
45
|
+
@buttons = buttons
|
|
46
|
+
|
|
47
|
+
validate!
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class << self
|
|
51
|
+
# @return [Hash] Serialized representation of the Card.
|
|
52
|
+
def serialize(card_index:, header:, body:, action:, buttons:)
|
|
53
|
+
new(card_index:, header:, body:, action:, buttons:).serialize
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @return [Hash] Serialized representation of the Card.
|
|
58
|
+
def serialize
|
|
59
|
+
{
|
|
60
|
+
card_index:,
|
|
61
|
+
type: Defaults::TYPE,
|
|
62
|
+
header: Whatsapp::Messages::Interactive::Header.serialize(**header),
|
|
63
|
+
body: Whatsapp::Messages::Interactive::Body.serialize(body),
|
|
64
|
+
action: Whatsapp::Messages::Interactive::UrlButton.serialize(**action),
|
|
65
|
+
buttons: serialized_buttons,
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def serialized_buttons
|
|
72
|
+
buttons.map { |button| Button.serialize(**button) }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class MediaCarousel < Base
|
|
7
|
+
module Defaults
|
|
8
|
+
MIN_CARDS_LENGTH = 2
|
|
9
|
+
MAX_CARDS_LENGTH = 10
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @!attribute [rw] cards
|
|
13
|
+
# @return [Array<Hash>]
|
|
14
|
+
attr_accessor :cards
|
|
15
|
+
|
|
16
|
+
validates :cards, presence: true, length: { minimum: Defaults::MIN_CARDS_LENGTH,
|
|
17
|
+
maximum: Defaults::MAX_CARDS_LENGTH, }
|
|
18
|
+
|
|
19
|
+
# @param cards [Array<Hash>] The media cards.
|
|
20
|
+
def initialize(cards:)
|
|
21
|
+
@cards = cards
|
|
22
|
+
|
|
23
|
+
validate!
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
# @return [Hash] Serialized representation of the MediaCarousel.
|
|
28
|
+
def serialize(cards:)
|
|
29
|
+
new(cards:).serialize
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Hash] Serialized representation of the MediaCarousel.
|
|
34
|
+
def serialize
|
|
35
|
+
{
|
|
36
|
+
cards: serialized_cards,
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# @return [Array<Hash>] Serialized cards.
|
|
43
|
+
# @raise [ActiveModel::ValidationError] if validation fails.
|
|
44
|
+
def serialized_cards
|
|
45
|
+
cards.map.with_index { |card, index| Card.serialize(card_index: index, **card) }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Whatsapp
|
|
4
|
+
class Messages
|
|
5
|
+
class Interactive
|
|
6
|
+
class ProductCarousel
|
|
7
|
+
class Card
|
|
8
|
+
module Defaults
|
|
9
|
+
TYPE = "product"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @!attribute [rw] card_index
|
|
13
|
+
# @return [Integer]
|
|
14
|
+
attr_accessor :card_index
|
|
15
|
+
|
|
16
|
+
# @!attribute [rw] catalog_id
|
|
17
|
+
# @return [String]
|
|
18
|
+
attr_accessor :catalog_id
|
|
19
|
+
|
|
20
|
+
# @!attribute [rw] product_retailer_id
|
|
21
|
+
# @return [String]
|
|
22
|
+
attr_accessor :product_retailer_id
|
|
23
|
+
|
|
24
|
+
# @param card_index [Integer] The index of the card in the carousel.
|
|
25
|
+
# @param catalog_id [String] The catalog ID associated with the product.
|
|
26
|
+
# @param product_retailer_id [String] The retailer ID of the product.
|
|
27
|
+
def initialize(card_index:, catalog_id:, product_retailer_id:)
|
|
28
|
+
@card_index = card_index
|
|
29
|
+
@catalog_id = catalog_id
|
|
30
|
+
@product_retailer_id = product_retailer_id
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class << self
|
|
34
|
+
# @return [Hash] Serialized representation of the Card.
|
|
35
|
+
def serialize(card_index:, catalog_id:, product_retailer_id:)
|
|
36
|
+
new(card_index:, catalog_id:, product_retailer_id:).serialize
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @return [Hash] Serialized representation of the Card.
|
|
41
|
+
def serialize
|
|
42
|
+
{
|
|
43
|
+
type: Defaults::TYPE,
|
|
44
|
+
card_index:,
|
|
45
|
+
action: {
|
|
46
|
+
catalog_id:,
|
|
47
|
+
product_retailer_id:,
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|