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.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +54 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +15 -0
  6. data/CODE_OF_CONDUCT.md +132 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +643 -0
  9. data/Rakefile +12 -0
  10. data/lib/ruby/whatsapp/client.rb +82 -0
  11. data/lib/ruby/whatsapp/configuration.rb +79 -0
  12. data/lib/ruby/whatsapp/instrumentation.rb +34 -0
  13. data/lib/ruby/whatsapp/media.rb +134 -0
  14. data/lib/ruby/whatsapp/message_templates/button/base.rb +26 -0
  15. data/lib/ruby/whatsapp/message_templates/button/copy_code.rb +59 -0
  16. data/lib/ruby/whatsapp/message_templates/button/otp/supported_app.rb +44 -0
  17. data/lib/ruby/whatsapp/message_templates/button/otp.rb +138 -0
  18. data/lib/ruby/whatsapp/message_templates/button/phone_number.rb +45 -0
  19. data/lib/ruby/whatsapp/message_templates/button/quick_reply.rb +38 -0
  20. data/lib/ruby/whatsapp/message_templates/button/url.rb +110 -0
  21. data/lib/ruby/whatsapp/message_templates/button.rb +56 -0
  22. data/lib/ruby/whatsapp/message_templates/categories.rb +47 -0
  23. data/lib/ruby/whatsapp/message_templates/component/base.rb +112 -0
  24. data/lib/ruby/whatsapp/message_templates/component/body.rb +139 -0
  25. data/lib/ruby/whatsapp/message_templates/component/buttons.rb +95 -0
  26. data/lib/ruby/whatsapp/message_templates/component/carousel/card.rb +100 -0
  27. data/lib/ruby/whatsapp/message_templates/component/carousel.rb +71 -0
  28. data/lib/ruby/whatsapp/message_templates/component/footer.rb +99 -0
  29. data/lib/ruby/whatsapp/message_templates/component/header.rb +188 -0
  30. data/lib/ruby/whatsapp/message_templates/component/limited_time_offer.rb +57 -0
  31. data/lib/ruby/whatsapp/message_templates/component.rb +62 -0
  32. data/lib/ruby/whatsapp/message_templates/component_set.rb +221 -0
  33. data/lib/ruby/whatsapp/message_templates/example.rb +148 -0
  34. data/lib/ruby/whatsapp/message_templates/library_template/body_inputs.rb +81 -0
  35. data/lib/ruby/whatsapp/message_templates/library_template/button_inputs.rb +146 -0
  36. data/lib/ruby/whatsapp/message_templates/library_template.rb +114 -0
  37. data/lib/ruby/whatsapp/message_templates/parameter_formats.rb +49 -0
  38. data/lib/ruby/whatsapp/message_templates/placeholders.rb +86 -0
  39. data/lib/ruby/whatsapp/message_templates/response/collection.rb +74 -0
  40. data/lib/ruby/whatsapp/message_templates/response/created.rb +65 -0
  41. data/lib/ruby/whatsapp/message_templates/response/node.rb +152 -0
  42. data/lib/ruby/whatsapp/message_templates/response/paging.rb +39 -0
  43. data/lib/ruby/whatsapp/message_templates/response/quality_score.rb +49 -0
  44. data/lib/ruby/whatsapp/message_templates/response/summary.rb +68 -0
  45. data/lib/ruby/whatsapp/message_templates/response.rb +22 -0
  46. data/lib/ruby/whatsapp/message_templates/statuses.rb +66 -0
  47. data/lib/ruby/whatsapp/message_templates/template.rb +180 -0
  48. data/lib/ruby/whatsapp/message_templates/value_object.rb +62 -0
  49. data/lib/ruby/whatsapp/message_templates.rb +283 -0
  50. data/lib/ruby/whatsapp/messages/address.rb +103 -0
  51. data/lib/ruby/whatsapp/messages/audio.rb +64 -0
  52. data/lib/ruby/whatsapp/messages/base.rb +46 -0
  53. data/lib/ruby/whatsapp/messages/contacts/address.rb +84 -0
  54. data/lib/ruby/whatsapp/messages/contacts/contact.rb +78 -0
  55. data/lib/ruby/whatsapp/messages/contacts/email.rb +49 -0
  56. data/lib/ruby/whatsapp/messages/contacts/name.rb +68 -0
  57. data/lib/ruby/whatsapp/messages/contacts/org.rb +41 -0
  58. data/lib/ruby/whatsapp/messages/contacts/phone.rb +59 -0
  59. data/lib/ruby/whatsapp/messages/contacts/url.rb +51 -0
  60. data/lib/ruby/whatsapp/messages/contacts.rb +37 -0
  61. data/lib/ruby/whatsapp/messages/document.rb +79 -0
  62. data/lib/ruby/whatsapp/messages/image.rb +72 -0
  63. data/lib/ruby/whatsapp/messages/interactive/base.rb +15 -0
  64. data/lib/ruby/whatsapp/messages/interactive/body.rb +39 -0
  65. data/lib/ruby/whatsapp/messages/interactive/footer.rb +40 -0
  66. data/lib/ruby/whatsapp/messages/interactive/header.rb +102 -0
  67. data/lib/ruby/whatsapp/messages/interactive/list_buttons/section/row.rb +66 -0
  68. data/lib/ruby/whatsapp/messages/interactive/list_buttons/section.rb +64 -0
  69. data/lib/ruby/whatsapp/messages/interactive/list_buttons.rb +63 -0
  70. data/lib/ruby/whatsapp/messages/interactive/media_carousel/card/button/quick_reply.rb +50 -0
  71. data/lib/ruby/whatsapp/messages/interactive/media_carousel/card/button.rb +47 -0
  72. data/lib/ruby/whatsapp/messages/interactive/media_carousel/card.rb +78 -0
  73. data/lib/ruby/whatsapp/messages/interactive/media_carousel.rb +50 -0
  74. data/lib/ruby/whatsapp/messages/interactive/product_carousel/card.rb +55 -0
  75. data/lib/ruby/whatsapp/messages/interactive/product_carousel.rb +50 -0
  76. data/lib/ruby/whatsapp/messages/interactive/reply_buttons/button.rb +59 -0
  77. data/lib/ruby/whatsapp/messages/interactive/reply_buttons.rb +47 -0
  78. data/lib/ruby/whatsapp/messages/interactive/url_button.rb +68 -0
  79. data/lib/ruby/whatsapp/messages/interactive.rb +112 -0
  80. data/lib/ruby/whatsapp/messages/location.rb +67 -0
  81. data/lib/ruby/whatsapp/messages/location_request.rb +41 -0
  82. data/lib/ruby/whatsapp/messages/mark_message_as_read.rb +42 -0
  83. data/lib/ruby/whatsapp/messages/reaction.rb +61 -0
  84. data/lib/ruby/whatsapp/messages/response/contacts.rb +36 -0
  85. data/lib/ruby/whatsapp/messages/response/messages.rb +27 -0
  86. data/lib/ruby/whatsapp/messages/response.rb +49 -0
  87. data/lib/ruby/whatsapp/messages/sticker.rb +62 -0
  88. data/lib/ruby/whatsapp/messages/template/component.rb +67 -0
  89. data/lib/ruby/whatsapp/messages/template/language.rb +55 -0
  90. data/lib/ruby/whatsapp/messages/template/parameter.rb +113 -0
  91. data/lib/ruby/whatsapp/messages/template.rb +62 -0
  92. data/lib/ruby/whatsapp/messages/text.rb +43 -0
  93. data/lib/ruby/whatsapp/messages/video.rb +68 -0
  94. data/lib/ruby/whatsapp/messages.rb +116 -0
  95. data/lib/ruby/whatsapp/railtie.rb +14 -0
  96. data/lib/ruby/whatsapp/request_error.rb +5 -0
  97. data/lib/ruby/whatsapp/response_handling.rb +44 -0
  98. data/lib/ruby/whatsapp/utils/language_codes.rb +96 -0
  99. data/lib/ruby/whatsapp/version.rb +5 -0
  100. data/lib/ruby/whatsapp/webhook/account_alerts.rb +58 -0
  101. data/lib/ruby/whatsapp/webhook/account_review_update.rb +27 -0
  102. data/lib/ruby/whatsapp/webhook/account_update/ban_info.rb +33 -0
  103. data/lib/ruby/whatsapp/webhook/account_update.rb +46 -0
  104. data/lib/ruby/whatsapp/webhook/automatic_events.rb +43 -0
  105. data/lib/ruby/whatsapp/webhook/business_capability_update.rb +36 -0
  106. data/lib/ruby/whatsapp/webhook/change.rb +61 -0
  107. data/lib/ruby/whatsapp/webhook/contact.rb +36 -0
  108. data/lib/ruby/whatsapp/webhook/entry.rb +35 -0
  109. data/lib/ruby/whatsapp/webhook/error.rb +47 -0
  110. data/lib/ruby/whatsapp/webhook/history.rb +54 -0
  111. data/lib/ruby/whatsapp/webhook/installer.rb +61 -0
  112. data/lib/ruby/whatsapp/webhook/message/audio.rb +28 -0
  113. data/lib/ruby/whatsapp/webhook/message/base.rb +61 -0
  114. data/lib/ruby/whatsapp/webhook/message/button.rb +33 -0
  115. data/lib/ruby/whatsapp/webhook/message/contacts/address.rb +68 -0
  116. data/lib/ruby/whatsapp/webhook/message/contacts/contact.rb +68 -0
  117. data/lib/ruby/whatsapp/webhook/message/contacts/email.rb +35 -0
  118. data/lib/ruby/whatsapp/webhook/message/contacts/name.rb +62 -0
  119. data/lib/ruby/whatsapp/webhook/message/contacts/org.rb +40 -0
  120. data/lib/ruby/whatsapp/webhook/message/contacts/phone.rb +40 -0
  121. data/lib/ruby/whatsapp/webhook/message/contacts/url.rb +35 -0
  122. data/lib/ruby/whatsapp/webhook/message/contacts.rb +31 -0
  123. data/lib/ruby/whatsapp/webhook/message/context.rb +49 -0
  124. data/lib/ruby/whatsapp/webhook/message/document.rb +32 -0
  125. data/lib/ruby/whatsapp/webhook/message/image.rb +18 -0
  126. data/lib/ruby/whatsapp/webhook/message/interactive.rb +53 -0
  127. data/lib/ruby/whatsapp/webhook/message/location.rb +49 -0
  128. data/lib/ruby/whatsapp/webhook/message/media.rb +54 -0
  129. data/lib/ruby/whatsapp/webhook/message/order/product_item.rb +50 -0
  130. data/lib/ruby/whatsapp/webhook/message/order.rb +43 -0
  131. data/lib/ruby/whatsapp/webhook/message/reaction.rb +37 -0
  132. data/lib/ruby/whatsapp/webhook/message/referral.rb +80 -0
  133. data/lib/ruby/whatsapp/webhook/message/sticker.rb +32 -0
  134. data/lib/ruby/whatsapp/webhook/message/system.rb +49 -0
  135. data/lib/ruby/whatsapp/webhook/message/text.rb +28 -0
  136. data/lib/ruby/whatsapp/webhook/message/unknown.rb +39 -0
  137. data/lib/ruby/whatsapp/webhook/message/video.rb +18 -0
  138. data/lib/ruby/whatsapp/webhook/message.rb +39 -0
  139. data/lib/ruby/whatsapp/webhook/message_template_components_update.rb +53 -0
  140. data/lib/ruby/whatsapp/webhook/message_template_quality_update.rb +59 -0
  141. data/lib/ruby/whatsapp/webhook/message_template_status_update.rb +54 -0
  142. data/lib/ruby/whatsapp/webhook/messages.rb +55 -0
  143. data/lib/ruby/whatsapp/webhook/metadata.rb +35 -0
  144. data/lib/ruby/whatsapp/webhook/notification.rb +36 -0
  145. data/lib/ruby/whatsapp/webhook/partner_solutions.rb +36 -0
  146. data/lib/ruby/whatsapp/webhook/payment_configuration_update.rb +51 -0
  147. data/lib/ruby/whatsapp/webhook/phone_number_name_update.rb +51 -0
  148. data/lib/ruby/whatsapp/webhook/phone_number_quality_update.rb +45 -0
  149. data/lib/ruby/whatsapp/webhook/security.rb +41 -0
  150. data/lib/ruby/whatsapp/webhook/signature.rb +28 -0
  151. data/lib/ruby/whatsapp/webhook/smb_app_state_sync/state_sync.rb +38 -0
  152. data/lib/ruby/whatsapp/webhook/smb_app_state_sync.rb +33 -0
  153. data/lib/ruby/whatsapp/webhook/smb_message_echoes.rb +48 -0
  154. data/lib/ruby/whatsapp/webhook/status/conversation.rb +42 -0
  155. data/lib/ruby/whatsapp/webhook/status/pricing.rb +38 -0
  156. data/lib/ruby/whatsapp/webhook/status.rb +65 -0
  157. data/lib/ruby/whatsapp/webhook/template_category_update.rb +64 -0
  158. data/lib/ruby/whatsapp/webhook/templates/webhooks_controller.rb.tt +31 -0
  159. data/lib/ruby/whatsapp/webhook/unknown_field.rb +37 -0
  160. data/lib/ruby/whatsapp/webhook/user_preferences.rb +47 -0
  161. data/lib/ruby/whatsapp/webhook/verification.rb +27 -0
  162. data/lib/ruby/whatsapp/webhook.rb +8 -0
  163. data/lib/ruby/whatsapp.rb +49 -0
  164. data/lib/tasks/whatsapp.rake +10 -0
  165. data/sig/ruby/whatsapp.rbs +6 -0
  166. metadata +267 -0
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # Common envelope shared by every inbound message type: who sent it, its
7
+ # wamid, when it arrived, and (optionally) what it's replying to.
8
+ class Base
9
+ # @!attribute [rw] from
10
+ # @return [String, nil]
11
+ attr_accessor :from
12
+
13
+ # @!attribute [rw] id
14
+ # @return [String, nil] The message's wamid.
15
+ attr_accessor :id
16
+
17
+ # @!attribute [rw] timestamp
18
+ # @return [String, nil]
19
+ attr_accessor :timestamp
20
+
21
+ # @!attribute [rw] type
22
+ # @return [String, nil]
23
+ attr_accessor :type
24
+
25
+ # @!attribute [rw] context
26
+ # @return [Context, nil]
27
+ attr_accessor :context
28
+
29
+ # @!attribute [rw] referral
30
+ # @return [Referral, nil]
31
+ attr_accessor :referral
32
+
33
+ def initialize(from:, id:, timestamp:, type:, context: nil, referral: nil)
34
+ @from = from
35
+ @id = id
36
+ @timestamp = timestamp
37
+ @type = type
38
+ @context = context
39
+ @referral = referral
40
+ end
41
+
42
+ class << self
43
+ # Extracts the fields every message type shares, for subclasses to
44
+ # merge with their own type-specific payload before calling `new`.
45
+ # @param data [Hash] The raw message hash.
46
+ # @return [Hash]
47
+ def common_attributes(data)
48
+ {
49
+ from: data["from"],
50
+ id: data["id"],
51
+ timestamp: data["timestamp"],
52
+ type: data["type"],
53
+ context: Context.deserialize(data["context"]),
54
+ referral: Referral.deserialize(data["referral"]),
55
+ }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # An inbound tap on a template's quick-reply button.
7
+ class Button < Base
8
+ # @!attribute [rw] text
9
+ # @return [String, nil] The button's display text.
10
+ attr_accessor :text
11
+
12
+ # @!attribute [rw] payload
13
+ # @return [String, nil] The developer-defined payload configured on the template button.
14
+ attr_accessor :payload
15
+
16
+ def initialize(text:, payload:, **base_attributes)
17
+ super(**base_attributes)
18
+
19
+ @text = text
20
+ @payload = payload
21
+ end
22
+
23
+ class << self
24
+ # @param data [Hash] The raw message hash.
25
+ # @return [Button]
26
+ def deserialize(data)
27
+ new(text: data.dig("button", "text"), payload: data.dig("button", "payload"), **common_attributes(data))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ class Contacts < Base
7
+ # A physical address entry within an inbound contact card.
8
+ class Address
9
+ # @!attribute [rw] street
10
+ # @return [String, nil]
11
+ attr_accessor :street
12
+
13
+ # @!attribute [rw] city
14
+ # @return [String, nil]
15
+ attr_accessor :city
16
+
17
+ # @!attribute [rw] state
18
+ # @return [String, nil]
19
+ attr_accessor :state
20
+
21
+ # @!attribute [rw] zip
22
+ # @return [String, nil]
23
+ attr_accessor :zip
24
+
25
+ # @!attribute [rw] country
26
+ # @return [String, nil]
27
+ attr_accessor :country
28
+
29
+ # @!attribute [rw] country_code
30
+ # @return [String, nil]
31
+ attr_accessor :country_code
32
+
33
+ # @!attribute [rw] type
34
+ # @return [String, nil]
35
+ attr_accessor :type
36
+
37
+ def initialize(street: nil, city: nil, state: nil, zip: nil, country: nil, country_code: nil, type: nil)
38
+ @street = street
39
+ @city = city
40
+ @state = state
41
+ @zip = zip
42
+ @country = country
43
+ @country_code = country_code
44
+ @type = type
45
+ end
46
+
47
+ class << self
48
+ # @param data [Hash] A raw `addresses[]` entry.
49
+ # @return [Address]
50
+ def deserialize(data)
51
+ data ||= {}
52
+
53
+ new(
54
+ street: data["street"],
55
+ city: data["city"],
56
+ state: data["state"],
57
+ zip: data["zip"],
58
+ country: data["country"],
59
+ country_code: data["country_code"],
60
+ type: data["type"]
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ class Contacts < Base
7
+ # A single inbound contact card.
8
+ class Contact
9
+ # @!attribute [rw] name
10
+ # @return [Name]
11
+ attr_accessor :name
12
+
13
+ # @!attribute [rw] phones
14
+ # @return [Array<Phone>]
15
+ attr_accessor :phones
16
+
17
+ # @!attribute [rw] emails
18
+ # @return [Array<Email>]
19
+ attr_accessor :emails
20
+
21
+ # @!attribute [rw] addresses
22
+ # @return [Array<Address>]
23
+ attr_accessor :addresses
24
+
25
+ # @!attribute [rw] org
26
+ # @return [Org, nil]
27
+ attr_accessor :org
28
+
29
+ # @!attribute [rw] urls
30
+ # @return [Array<Url>]
31
+ attr_accessor :urls
32
+
33
+ # @!attribute [rw] birthday
34
+ # @return [String, nil] Date in YYYY-MM-DD format.
35
+ attr_accessor :birthday
36
+
37
+ def initialize(name:, phones:, emails:, addresses:, urls:, org: nil, birthday: nil)
38
+ @name = name
39
+ @phones = phones
40
+ @emails = emails
41
+ @addresses = addresses
42
+ @org = org
43
+ @urls = urls
44
+ @birthday = birthday
45
+ end
46
+
47
+ class << self
48
+ # @param data [Hash] A raw `contacts[]` entry.
49
+ # @return [Contact]
50
+ def deserialize(data)
51
+ data ||= {}
52
+
53
+ new(
54
+ name: Name.deserialize(data["name"]),
55
+ phones: Array(data["phones"]).map { |phone_data| Phone.deserialize(phone_data) },
56
+ emails: Array(data["emails"]).map { |email_data| Email.deserialize(email_data) },
57
+ addresses: Array(data["addresses"]).map { |address_data| Address.deserialize(address_data) },
58
+ org: data["org"] ? Org.deserialize(data["org"]) : nil,
59
+ urls: Array(data["urls"]).map { |url_data| Url.deserialize(url_data) },
60
+ birthday: data["birthday"]
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ class Contacts < Base
7
+ # An email entry within an inbound contact card.
8
+ class Email
9
+ # @!attribute [rw] email
10
+ # @return [String, nil]
11
+ attr_accessor :email
12
+
13
+ # @!attribute [rw] type
14
+ # @return [String, nil]
15
+ attr_accessor :type
16
+
17
+ def initialize(email:, type: nil)
18
+ @email = email
19
+ @type = type
20
+ end
21
+
22
+ class << self
23
+ # @param data [Hash] A raw `emails[]` entry.
24
+ # @return [Email]
25
+ def deserialize(data)
26
+ data ||= {}
27
+
28
+ new(email: data["email"], type: data["type"])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ class Contacts < Base
7
+ # The name component of an inbound contact card.
8
+ class Name
9
+ # @!attribute [rw] formatted_name
10
+ # @return [String, nil]
11
+ attr_accessor :formatted_name
12
+
13
+ # @!attribute [rw] first_name
14
+ # @return [String, nil]
15
+ attr_accessor :first_name
16
+
17
+ # @!attribute [rw] last_name
18
+ # @return [String, nil]
19
+ attr_accessor :last_name
20
+
21
+ # @!attribute [rw] middle_name
22
+ # @return [String, nil]
23
+ attr_accessor :middle_name
24
+
25
+ # @!attribute [rw] prefix
26
+ # @return [String, nil]
27
+ attr_accessor :prefix
28
+
29
+ # @!attribute [rw] suffix
30
+ # @return [String, nil]
31
+ attr_accessor :suffix
32
+
33
+ def initialize(formatted_name:, first_name: nil, last_name: nil, middle_name: nil, prefix: nil, suffix: nil)
34
+ @formatted_name = formatted_name
35
+ @first_name = first_name
36
+ @last_name = last_name
37
+ @middle_name = middle_name
38
+ @prefix = prefix
39
+ @suffix = suffix
40
+ end
41
+
42
+ class << self
43
+ # @param data [Hash] The raw `name` hash.
44
+ # @return [Name]
45
+ def deserialize(data)
46
+ data ||= {}
47
+
48
+ new(
49
+ formatted_name: data["formatted_name"],
50
+ first_name: data["first_name"],
51
+ last_name: data["last_name"],
52
+ middle_name: data["middle_name"],
53
+ prefix: data["prefix"],
54
+ suffix: data["suffix"]
55
+ )
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ class Contacts < Base
7
+ # The organization details of an inbound contact card.
8
+ class Org
9
+ # @!attribute [rw] company
10
+ # @return [String, nil]
11
+ attr_accessor :company
12
+
13
+ # @!attribute [rw] department
14
+ # @return [String, nil]
15
+ attr_accessor :department
16
+
17
+ # @!attribute [rw] title
18
+ # @return [String, nil]
19
+ attr_accessor :title
20
+
21
+ def initialize(company: nil, department: nil, title: nil)
22
+ @company = company
23
+ @department = department
24
+ @title = title
25
+ end
26
+
27
+ class << self
28
+ # @param data [Hash, nil] The raw `org` hash.
29
+ # @return [Org]
30
+ def deserialize(data)
31
+ data ||= {}
32
+
33
+ new(company: data["company"], department: data["department"], title: data["title"])
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ class Contacts < Base
7
+ # A phone number entry within an inbound contact card.
8
+ class Phone
9
+ # @!attribute [rw] phone
10
+ # @return [String, nil]
11
+ attr_accessor :phone
12
+
13
+ # @!attribute [rw] type
14
+ # @return [String, nil]
15
+ attr_accessor :type
16
+
17
+ # @!attribute [rw] wa_id
18
+ # @return [String, nil]
19
+ attr_accessor :wa_id
20
+
21
+ def initialize(phone:, type: nil, wa_id: nil)
22
+ @phone = phone
23
+ @type = type
24
+ @wa_id = wa_id
25
+ end
26
+
27
+ class << self
28
+ # @param data [Hash] A raw `phones[]` entry.
29
+ # @return [Phone]
30
+ def deserialize(data)
31
+ data ||= {}
32
+
33
+ new(phone: data["phone"], type: data["type"], wa_id: data["wa_id"])
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ class Contacts < Base
7
+ # A URL entry within an inbound contact card.
8
+ class Url
9
+ # @!attribute [rw] url
10
+ # @return [String, nil]
11
+ attr_accessor :url
12
+
13
+ # @!attribute [rw] type
14
+ # @return [String, nil]
15
+ attr_accessor :type
16
+
17
+ def initialize(url:, type: nil)
18
+ @url = url
19
+ @type = type
20
+ end
21
+
22
+ class << self
23
+ # @param data [Hash] A raw `urls[]` entry.
24
+ # @return [Url]
25
+ def deserialize(data)
26
+ data ||= {}
27
+
28
+ new(url: data["url"], type: data["type"])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # An inbound shared contact card (or cards).
7
+ class Contacts < Base
8
+ # @!attribute [rw] contacts
9
+ # @return [Array<Contact>]
10
+ attr_accessor :contacts
11
+
12
+ def initialize(contacts:, **base_attributes)
13
+ super(**base_attributes)
14
+
15
+ @contacts = contacts
16
+ end
17
+
18
+ class << self
19
+ # @param data [Hash] The raw message hash.
20
+ # @return [Contacts]
21
+ def deserialize(data)
22
+ new(
23
+ contacts: Array(data["contacts"]).map { |contact_data| Contact.deserialize(contact_data) },
24
+ **common_attributes(data)
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # Present when an inbound message replies to a previous one (e.g. a reply
7
+ # swipe, or a tap on an interactive button/list from an earlier message).
8
+ class Context
9
+ # @!attribute [rw] from
10
+ # @return [String, nil]
11
+ attr_accessor :from
12
+
13
+ # @!attribute [rw] id
14
+ # @return [String, nil] The wamid of the message being replied to.
15
+ attr_accessor :id
16
+
17
+ # @!attribute [rw] forwarded
18
+ # @return [Boolean, nil]
19
+ attr_accessor :forwarded
20
+
21
+ # @!attribute [rw] frequently_forwarded
22
+ # @return [Boolean, nil]
23
+ attr_accessor :frequently_forwarded
24
+
25
+ def initialize(from:, id:, forwarded: nil, frequently_forwarded: nil)
26
+ @from = from
27
+ @id = id
28
+ @forwarded = forwarded
29
+ @frequently_forwarded = frequently_forwarded
30
+ end
31
+
32
+ class << self
33
+ # @param data [Hash, nil] The raw `context` hash.
34
+ # @return [Context, nil]
35
+ def deserialize(data)
36
+ return if data.nil?
37
+
38
+ new(
39
+ from: data["from"],
40
+ id: data["id"],
41
+ forwarded: data["forwarded"],
42
+ frequently_forwarded: data["frequently_forwarded"]
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # An inbound document message.
7
+ class Document < Media
8
+ # @!attribute [rw] filename
9
+ # @return [String, nil]
10
+ attr_accessor :filename
11
+
12
+ def initialize(filename: nil, **media_and_base_attributes)
13
+ super(**media_and_base_attributes)
14
+
15
+ @filename = filename
16
+ end
17
+
18
+ class << self
19
+ # @param data [Hash] The raw message hash.
20
+ # @return [Document]
21
+ def deserialize(data)
22
+ new(
23
+ filename: data.dig("document", "filename"),
24
+ **media_attributes(data, "document"),
25
+ **common_attributes(data)
26
+ )
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # An inbound image message.
7
+ class Image < Media
8
+ class << self
9
+ # @param data [Hash] The raw message hash.
10
+ # @return [Image]
11
+ def deserialize(data)
12
+ new(**media_attributes(data, "image"), **common_attributes(data))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # An inbound reply to an interactive message — a button tap (`button_reply`)
7
+ # or a list row selection (`list_reply`).
8
+ class Interactive < Base
9
+ # @!attribute [rw] interactive_type
10
+ # @return [String, nil] Either `"button_reply"` or `"list_reply"`.
11
+ attr_accessor :interactive_type
12
+
13
+ # @!attribute [rw] reply_id
14
+ # @return [String, nil] The id of the tapped button/row.
15
+ attr_accessor :reply_id
16
+
17
+ # @!attribute [rw] title
18
+ # @return [String, nil]
19
+ attr_accessor :title
20
+
21
+ # @!attribute [rw] description
22
+ # @return [String, nil] Only present for `list_reply`.
23
+ attr_accessor :description
24
+
25
+ def initialize(interactive_type:, reply_id:, title:, description: nil, **base_attributes)
26
+ super(**base_attributes)
27
+
28
+ @interactive_type = interactive_type
29
+ @reply_id = reply_id
30
+ @title = title
31
+ @description = description
32
+ end
33
+
34
+ class << self
35
+ # @param data [Hash] The raw message hash.
36
+ # @return [Interactive]
37
+ def deserialize(data)
38
+ interactive_type = data.dig("interactive", "type")
39
+ reply = data.dig("interactive", interactive_type) || {}
40
+
41
+ new(
42
+ interactive_type:,
43
+ reply_id: reply["id"],
44
+ title: reply["title"],
45
+ description: reply["description"],
46
+ **common_attributes(data)
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Whatsapp
4
+ module Webhook
5
+ class Message
6
+ # An inbound shared location.
7
+ class Location < Base
8
+ # @!attribute [rw] latitude
9
+ # @return [Float, nil]
10
+ attr_accessor :latitude
11
+
12
+ # @!attribute [rw] longitude
13
+ # @return [Float, nil]
14
+ attr_accessor :longitude
15
+
16
+ # @!attribute [rw] name
17
+ # @return [String, nil]
18
+ attr_accessor :name
19
+
20
+ # @!attribute [rw] address
21
+ # @return [String, nil]
22
+ attr_accessor :address
23
+
24
+ def initialize(latitude:, longitude:, name: nil, address: nil, **base_attributes)
25
+ super(**base_attributes)
26
+
27
+ @latitude = latitude
28
+ @longitude = longitude
29
+ @name = name
30
+ @address = address
31
+ end
32
+
33
+ class << self
34
+ # @param data [Hash] The raw message hash.
35
+ # @return [Location]
36
+ def deserialize(data)
37
+ new(
38
+ latitude: data.dig("location", "latitude"),
39
+ longitude: data.dig("location", "longitude"),
40
+ name: data.dig("location", "name"),
41
+ address: data.dig("location", "address"),
42
+ **common_attributes(data)
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end