whatsapp_sdk 0.0.2 → 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.
@@ -1,32 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "data_response"
4
+
3
5
  module WhatsappSdk
4
6
  module Api
5
7
  module Responses
6
- class ErrorResponse
7
- attr_reader :code, :subcode, :message, :type, :data, :fbtrace_id
8
+ class ErrorResponse < DataResponse
9
+ attr_accessor :error, :status
8
10
 
9
- def initialize(code:, subcode:, message:, type:, data:, fbtrace_id:)
10
- @code = code
11
- @subcode = subcode
12
- @message = message
13
- @type = type
14
- @data = data
15
- @fbtrace_id = fbtrace_id
11
+ def initialize(response:)
12
+ @error = response["error"]
13
+ @status = response["status"]
14
+ super(response)
16
15
  end
17
16
 
18
17
  def self.build_from_response(response:)
19
- error_response = response["error"]
20
- return unless error_response
18
+ return unless response["error"]
21
19
 
22
- new(
23
- code: error_response["code"],
24
- subcode: error_response["error_subcode"],
25
- message: error_response["message"],
26
- type: error_response["type"],
27
- data: error_response["data"],
28
- fbtrace_id: error_response["fbtrace_id"]
29
- )
20
+ new(response: response)
30
21
  end
31
22
  end
32
23
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "data_response"
4
+
5
+ module WhatsappSdk
6
+ module Api
7
+ module Responses
8
+ class MediaDataResponse < DataResponse
9
+ attr_accessor :id, :url, :mime_type, :sha256, :file_size, :messaging_product
10
+
11
+ def initialize(response)
12
+ @id = response["id"]
13
+ @messaging_product = response["messaging_product"]
14
+ @url = response["url"]
15
+ @mime_type = response["mime_type"]
16
+ @sha256 = response["sha256"]
17
+ @file_size = response["file_size"]
18
+ super(response)
19
+ end
20
+
21
+ def self.build_from_response(response:)
22
+ return unless response["id"]
23
+
24
+ new(response)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "error_response"
4
+
5
+ module WhatsappSdk
6
+ module Api
7
+ module Responses
8
+ class MessageErrorResponse < ErrorResponse
9
+ attr_reader :code, :subcode, :message, :type, :data, :fbtrace_id
10
+
11
+ def initialize(response:)
12
+ @code = response["code"]
13
+ @subcode = response["error_subcode"]
14
+ @message = response["message"]
15
+ @type = response["type"]
16
+ @data = response["data"]
17
+ @fbtrace_id = response["fbtrace_id"]
18
+ super(response: response)
19
+ end
20
+
21
+ def self.build_from_response(response:)
22
+ error_response = response["error"]
23
+ return unless error_response
24
+
25
+ new(response: error_response)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -8,11 +8,11 @@ require_relative "../../resource/contact_response"
8
8
  module WhatsappSdk
9
9
  module Api
10
10
  module Responses
11
- class MessageDataResponse < DataResponse
12
- attr_reader :sucess
11
+ class ReadMessageDataResponse < DataResponse
12
+ attr_reader :success
13
13
 
14
14
  def initialize(response:)
15
- @sucess = response["sucess"]
15
+ @success = response["success"]
16
16
  super(response)
17
17
  end
18
18
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "data_response"
4
+
5
+ module WhatsappSdk
6
+ module Api
7
+ module Responses
8
+ class SuccessResponse < DataResponse
9
+ def initialize(response:)
10
+ @success = response["success"]
11
+ super(response)
12
+ end
13
+
14
+ def self.build_from_response(response:)
15
+ return unless response["success"]
16
+
17
+ new(response: response)
18
+ end
19
+
20
+ def success?
21
+ @success
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ # This module allows client instantiating the client as a singleton like the following example:
5
+ # WhatsappSdk.configure do |config|
6
+ # config.access_token = ACCESS_TOKEN
7
+ # end
8
+ #
9
+ # The gem have access to the client through WhatsappSdk.configuration.client
10
+
11
+ class << self
12
+ def configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ def configure
17
+ yield(configuration)
18
+ end
19
+ end
20
+
21
+ class Configuration
22
+ attr_accessor :access_token
23
+
24
+ def initialize(access_token = nil)
25
+ @access_token = access_token
26
+ end
27
+
28
+ def client
29
+ return unless access_token
30
+
31
+ WhatsappSdk::Api::Client.new(access_token)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ module Resource
5
+ class ButtonParameter
6
+ class InvalidType < StandardError
7
+ attr_accessor :message
8
+
9
+ def initialize(type)
10
+ @message = "invalid type #{type}. type should be text or payload"
11
+ super
12
+ end
13
+ end
14
+
15
+ # Returns the button parameter type.
16
+ #
17
+ # @returns type [String] Valid options are payload and text.
18
+ attr_accessor :type
19
+
20
+ module Type
21
+ TEXT = "text"
22
+ PAYLOAD = "payload"
23
+
24
+ VALID_TYPES = [PAYLOAD, TEXT].freeze
25
+ end
26
+
27
+ # Required for quick_reply buttons.
28
+ # Returns the button payload. Developer-defined payload that is returned when the button is clicked
29
+ # in addition to the display text on the button.
30
+ #
31
+ # @returns payload [String]
32
+ attr_accessor :payload
33
+
34
+ # Required for URL buttons.
35
+ # Developer-provided suffix that is appended to the predefined prefix URL in the template.
36
+ #
37
+ # @returns text [String]
38
+ attr_accessor :text
39
+
40
+ def initialize(type:, payload: nil, text: nil)
41
+ @type = type
42
+ @payload = payload
43
+ @text = text
44
+ validate
45
+ end
46
+
47
+ def to_json(*_args)
48
+ json = {
49
+ type: type
50
+ }
51
+ json[:payload] = payload if payload
52
+ json[:text] = text if text
53
+ json
54
+ end
55
+
56
+ private
57
+
58
+ def validate
59
+ return if Type::VALID_TYPES.include?(type)
60
+
61
+ raise InvalidType, type
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ module Resource
5
+ class Component
6
+ class InvalidField < StandardError
7
+ attr_reader :field, :message
8
+
9
+ def initialize(field, message)
10
+ @field = field
11
+ @message = message
12
+ super(message)
13
+ end
14
+ end
15
+
16
+ module Type
17
+ HEADER = 'header'
18
+ BODY = 'body'
19
+ BUTTON = 'button'
20
+ end
21
+
22
+ module Subtype
23
+ QUICK_REPLY = "quick_reply"
24
+ URL = "url"
25
+ end
26
+
27
+ # Returns the Component type.
28
+ #
29
+ # @returns type [String]. Supported Options are header, body and button.
30
+ attr_accessor :type
31
+
32
+ # Returns the parameters of the component. For button type, it's required.
33
+ #
34
+ # @returns parameter [Array<ButtonParameter, ParameterObject>] .
35
+ attr_accessor :parameters
36
+
37
+ # Returns the Type of button to create. Required when type=button. Not used for the other types.
38
+ # Supported Options
39
+ # quick_reply: Refers to a previously created quick reply button
40
+ # that allows for the customer to return a predefined message.
41
+ # url: Refers to a previously created button that allows the customer to visit the URL generated by
42
+ # appending the text parameter to the predefined prefix URL in the template.
43
+ #
44
+ # @returns subtype [String]. Valid options are quick_reply and url.
45
+ attr_accessor :sub_type
46
+
47
+ # Required when type=button. Not used for the other types.
48
+ # Position index of the button. You can have up to 3 buttons using index values of 0 to 2.
49
+ #
50
+ # @returns index [Integer].
51
+ attr_accessor :index
52
+
53
+ def add_parameter(parameter)
54
+ @parameters << parameter
55
+ end
56
+
57
+ def initialize(type:, parameters: [], sub_type: nil, index: nil)
58
+ @parameters = parameters
59
+ @type = type
60
+ @sub_type = sub_type
61
+ @index = index.nil? && type == Type::BUTTON ? 0 : index
62
+ validate_fields
63
+ end
64
+
65
+ def to_json(*_args)
66
+ json = {
67
+ type: type,
68
+ parameters: parameters.map(&:to_json)
69
+ }
70
+ json[:sub_type] = sub_type if sub_type
71
+ json[:index] = index if index
72
+ json
73
+ end
74
+
75
+ private
76
+
77
+ def validate_fields
78
+ return if type == Type::BUTTON
79
+ raise InvalidField.new(:sub_type, 'sub_type is not required when type is not button') if sub_type
80
+
81
+ raise InvalidField.new(:index, 'index is not required when type is not button') if index
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ module Resource
5
+ class Currency
6
+ # Returns default text if localization fails.
7
+ #
8
+ # @returns fallback_value [String].
9
+ attr_accessor :fallback_value
10
+
11
+ # Currency code as defined in ISO 4217.
12
+ #
13
+ # @returns code [String].
14
+ attr_accessor :code
15
+
16
+ # Amount multiplied by 1000.
17
+ #
18
+ # @returns code [Float].
19
+ attr_accessor :amount
20
+
21
+ def initialize(fallback_value:, code:, amount:)
22
+ @fallback_value = fallback_value
23
+ @code = code
24
+ @amount = amount
25
+ end
26
+
27
+ def to_json(*_args)
28
+ {
29
+ fallback_value: fallback_value,
30
+ code: code,
31
+ amount_1000: amount
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ module Resource
5
+ class DateTime
6
+ # Returns default text if localization fails.
7
+ #
8
+ # @returns fallback_value [String].
9
+ attr_accessor :fallback_value
10
+
11
+ def initialize(fallback_value:)
12
+ @fallback_value = fallback_value
13
+ end
14
+
15
+ def to_json(*_args)
16
+ {
17
+ fallback_value: fallback_value
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ module Resource
5
+ class Media
6
+ class InvalidMedia < StandardError
7
+ attr_reader :field, :message
8
+
9
+ def initialize(field, message)
10
+ @field = field
11
+ @message = message
12
+ super(message)
13
+ end
14
+ end
15
+
16
+ # Returns media id.
17
+ #
18
+ # @returns id [String].
19
+ attr_accessor :id
20
+
21
+ module Type
22
+ AUDIO = 'audio'
23
+ DOCUMENT = 'document'
24
+ IMAGE = 'image'
25
+ VIDEO = 'video'
26
+ STICKER = 'sticker'
27
+
28
+ VALID_TYPES = [AUDIO, DOCUMENT, IMAGE, VIDEO, STICKER].freeze
29
+ end
30
+
31
+ # @returns type [String]. Valid options ar audio, document, image, video and sticker.
32
+ attr_accessor :type
33
+
34
+ # The protocol and URL of the media to be sent. Use only with HTTP/HTTPS URLs.
35
+ # Do not use this field when the message type is set to text.
36
+ #
37
+ # @returns link [String].
38
+ attr_accessor :link
39
+
40
+ # Describes the specified document or image media.
41
+ #
42
+ # @returns caption [String].
43
+ attr_accessor :caption
44
+
45
+ # Describes the filename for the specific document. Use only with document media.
46
+ #
47
+ # @returns filename [String].
48
+ attr_accessor :filename
49
+
50
+ def initialize(type:, id: nil, link: nil, caption: nil, filename: nil)
51
+ @type = type
52
+ @id = id
53
+ @link = link
54
+ @caption = caption
55
+ @filename = filename
56
+ validate_media
57
+ end
58
+
59
+ def to_json(*_args)
60
+ json = {}
61
+ json[:id] = id unless id.nil?
62
+ json[:link] = link unless link.nil?
63
+ json[:caption] = caption unless caption.nil?
64
+ json[:filename] = filename unless filename.nil?
65
+ json
66
+ end
67
+
68
+ private
69
+
70
+ def validate_media
71
+ unless Type::VALID_TYPES.include?(type)
72
+ raise InvalidMedia.new(:type, "invalid type. type should be audio, document, image, video or sticker")
73
+ end
74
+ if filename && (type != Type::DOCUMENT)
75
+ raise InvalidMedia.new(:filename, "filename can only be used with document")
76
+ end
77
+
78
+ if caption && !(type == Type::DOCUMENT || type == Type::IMAGE)
79
+ raise InvalidMedia.new(:caption, "caption can only be used with document or image")
80
+ end
81
+
82
+ true
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WhatsappSdk
4
+ module Resource
5
+ class ParameterObject
6
+ class InvalidType < StandardError
7
+ attr_accessor :message
8
+
9
+ def initialize(type)
10
+ @message = "invalid type #{type}. type should be text, currency, date_time, image, document or video"
11
+ super
12
+ end
13
+ end
14
+
15
+ class MissingValue < StandardError
16
+ attr_reader :field, :message
17
+
18
+ def initialize(field, message)
19
+ @field = field
20
+ @message = message
21
+ super(message)
22
+ end
23
+ end
24
+
25
+ # Returns the parameter type.
26
+ #
27
+ # @returns type [String] Valid options are text, currency, date_time, image, document, video.
28
+ attr_accessor :type
29
+
30
+ module Type
31
+ TEXT = "text"
32
+ CURRENCY = "currency"
33
+ DATE_TIME = "date_time"
34
+ IMAGE = "image"
35
+ DOCUMENT = "document"
36
+ VIDEO = "video"
37
+
38
+ VALID_TYPES = [TEXT, CURRENCY, DATE_TIME, IMAGE, DOCUMENT, VIDEO].freeze
39
+ end
40
+
41
+ # Returns Text string if the parameter object type is text.
42
+ # For the header component, the character limit is 60 characters.
43
+ # For the body component, the character limit is 1024 characters.
44
+ #
45
+ # @returns text [String]
46
+ attr_accessor :text
47
+
48
+ # Returns Currency if the parameter object type is currency.
49
+ #
50
+ # @returns currency [Currency]
51
+ attr_accessor :currency
52
+
53
+ # Returns date_time if the parameter object type is date_time.
54
+ #
55
+ # @returns date_time [DateTime]
56
+ attr_accessor :date_time
57
+
58
+ # Returns image if the parameter object type is image.
59
+ #
60
+ # @returns image [Media]
61
+ attr_accessor :image
62
+
63
+ # Returns document if the parameter object type is document.
64
+ #
65
+ # @returns document [Media]
66
+ attr_accessor :document
67
+
68
+ # Returns video if the parameter object type is video.
69
+ #
70
+ # @returns video [Media]
71
+ attr_accessor :video
72
+
73
+ def initialize(type:, text: nil, currency: nil, date_time: nil, image: nil, document: nil, video: nil)
74
+ @type = type
75
+ @text = text
76
+ @currency = currency
77
+ @date_time = date_time
78
+ @image = image
79
+ @document = document
80
+ @video = video
81
+ validate
82
+ end
83
+
84
+ def to_json(*_args)
85
+ json = { type: type }
86
+ json[type.to_sym] = case type
87
+ when "text"
88
+ text
89
+ when "currency"
90
+ currency.to_json
91
+ when "date_time"
92
+ date_time.to_json
93
+ when "image"
94
+ image.to_json
95
+ when "document"
96
+ document.to_json
97
+ when "video"
98
+ video.to_json
99
+ else
100
+ raise "Invalid type: #{type}"
101
+ end
102
+
103
+ json
104
+ end
105
+
106
+ private
107
+
108
+ def validate
109
+ validate_attributes
110
+ validate_type
111
+ end
112
+
113
+ def validate_type
114
+ return if Type::VALID_TYPES.include?(type)
115
+
116
+ raise InvalidType, type
117
+ end
118
+
119
+ def validate_attributes
120
+ [
121
+ [:text, text],
122
+ [:currency, currency],
123
+ [:date_time, date_time],
124
+ [:image, image],
125
+ [:document, document],
126
+ [:video, video]
127
+ ].each do |type_sym, value|
128
+ next unless type == type_sym
129
+ raise MissingValue.new(type, "#{type} is required when the type is #{type}") if value.nil?
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
data/lib/whatsapp_sdk.rb CHANGED
@@ -1,24 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Configuration
4
+ require_relative "whatsapp_sdk/configuration"
5
+
3
6
  # APIs
4
7
  require_relative "whatsapp_sdk/api/phone_numbers"
5
8
  require_relative "whatsapp_sdk/api/messages"
9
+ require_relative "whatsapp_sdk/api/medias"
6
10
  require_relative "whatsapp_sdk/api/client"
7
11
 
8
12
  # APIs responses
9
13
  require_relative "whatsapp_sdk/api/responses/message_data_response"
10
14
  require_relative "whatsapp_sdk/api/responses/phone_number_data_response"
11
15
  require_relative "whatsapp_sdk/api/responses/phone_numbers_data_response"
12
- require_relative "whatsapp_sdk/api/responses/error_response"
16
+ require_relative "whatsapp_sdk/api/responses/message_error_response"
13
17
  require_relative "whatsapp_sdk/api/responses/data_response"
18
+ require_relative "whatsapp_sdk/api/responses/read_message_data_response"
19
+ require_relative "whatsapp_sdk/api/responses/media_data_response"
20
+ require_relative "whatsapp_sdk/api/responses/success_response"
21
+ require_relative "whatsapp_sdk/api/responses/error_response"
14
22
 
15
23
  # Resources
16
24
  require_relative "whatsapp_sdk/resource/address"
25
+ require_relative "whatsapp_sdk/resource/button_parameter"
26
+ require_relative "whatsapp_sdk/resource/component"
17
27
  require_relative "whatsapp_sdk/resource/contact_response"
18
28
  require_relative "whatsapp_sdk/resource/contact"
29
+ require_relative "whatsapp_sdk/resource/currency"
30
+ require_relative "whatsapp_sdk/resource/date_time"
19
31
  require_relative "whatsapp_sdk/resource/email"
32
+ require_relative "whatsapp_sdk/resource/media"
20
33
  require_relative "whatsapp_sdk/resource/message"
21
34
  require_relative "whatsapp_sdk/resource/name"
22
35
  require_relative "whatsapp_sdk/resource/org"
36
+ require_relative "whatsapp_sdk/resource/parameter_object"
23
37
  require_relative "whatsapp_sdk/resource/phone_number"
24
38
  require_relative "whatsapp_sdk/resource/url"
data/tmp/whatsapp.png ADDED
Binary file