unione 1.1.3

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 (146) hide show
  1. checksums.yaml +7 -0
  2. data/AGENTS.md +99 -0
  3. data/LICENSE +21 -0
  4. data/README.md +270 -0
  5. data/docs/ConfirmedEmail.md +109 -0
  6. data/docs/Domain.md +257 -0
  7. data/docs/Email.md +126 -0
  8. data/docs/EmailValidation.md +54 -0
  9. data/docs/EventDump.md +157 -0
  10. data/docs/Obsolete.md +119 -0
  11. data/docs/Project.md +174 -0
  12. data/docs/Suppression.md +163 -0
  13. data/docs/System.md +73 -0
  14. data/docs/Tag.md +73 -0
  15. data/docs/Template.md +164 -0
  16. data/docs/Webhook.md +182 -0
  17. data/lib/unione/api/confirmed_email/confirmed_email_api.rb +47 -0
  18. data/lib/unione/api/confirmed_email/model/confirmed_email.rb +49 -0
  19. data/lib/unione/api/confirmed_email/model/confirmed_email_create_response.rb +50 -0
  20. data/lib/unione/api/confirmed_email/model/confirmed_email_delete_response.rb +50 -0
  21. data/lib/unione/api/confirmed_email/model/confirmed_email_list_response.rb +50 -0
  22. data/lib/unione/api/confirmed_email/model/confirmed_email_request.rb +42 -0
  23. data/lib/unione/api/domain/domain_api.rb +129 -0
  24. data/lib/unione/api/domain/model/dkim_status.rb +18 -0
  25. data/lib/unione/api/domain/model/domain_delete_request.rb +42 -0
  26. data/lib/unione/api/domain/model/domain_delete_response.rb +51 -0
  27. data/lib/unione/api/domain/model/domain_get_dns_records_request.rb +42 -0
  28. data/lib/unione/api/domain/model/domain_get_dns_records_response.rb +76 -0
  29. data/lib/unione/api/domain/model/domain_get_sandbox_domain_response.rb +51 -0
  30. data/lib/unione/api/domain/model/domain_list_request.rb +60 -0
  31. data/lib/unione/api/domain/model/domain_list_response.rb +51 -0
  32. data/lib/unione/api/domain/model/domain_list_response_domains_item.rb +58 -0
  33. data/lib/unione/api/domain/model/domain_list_response_domains_item_dkim.rb +52 -0
  34. data/lib/unione/api/domain/model/domain_list_response_domains_item_verification_record.rb +50 -0
  35. data/lib/unione/api/domain/model/domain_validate_dkim_request.rb +42 -0
  36. data/lib/unione/api/domain/model/domain_validate_dkim_response.rb +51 -0
  37. data/lib/unione/api/domain/model/domain_validate_verification_record_request.rb +42 -0
  38. data/lib/unione/api/domain/model/domain_validate_verification_record_response.rb +51 -0
  39. data/lib/unione/api/email/email_api.rb +56 -0
  40. data/lib/unione/api/email/model/email_send_request.rb +42 -0
  41. data/lib/unione/api/email/model/email_send_response.rb +83 -0
  42. data/lib/unione/api/email/model/email_subscribe_request.rb +58 -0
  43. data/lib/unione/api/email/model/message_object.rb +291 -0
  44. data/lib/unione/api/email/model/message_object_options.rb +70 -0
  45. data/lib/unione/api/email/model/message_object_recipients_item.rb +77 -0
  46. data/lib/unione/api/email_validation/email_validation_api.rb +34 -0
  47. data/lib/unione/api/email_validation/model/email_validation_single_request.rb +42 -0
  48. data/lib/unione/api/email_validation/model/email_validation_single_response.rb +140 -0
  49. data/lib/unione/api/event_dump/event_dump_api.rb +67 -0
  50. data/lib/unione/api/event_dump/model/event_dump_create_request.rb +119 -0
  51. data/lib/unione/api/event_dump/model/event_dump_create_response.rb +52 -0
  52. data/lib/unione/api/event_dump/model/event_dump_delete_request.rb +43 -0
  53. data/lib/unione/api/event_dump/model/event_dump_files_object.rb +51 -0
  54. data/lib/unione/api/event_dump/model/event_dump_get_request.rb +43 -0
  55. data/lib/unione/api/event_dump/model/event_dump_get_response.rb +51 -0
  56. data/lib/unione/api/event_dump/model/event_dump_list_response.rb +52 -0
  57. data/lib/unione/api/event_dump/model/event_dump_object.rb +66 -0
  58. data/lib/unione/api/event_dump/model/filter_object.rb +139 -0
  59. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_check_request.rb +42 -0
  60. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_check_response.rb +59 -0
  61. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_list_request.rb +43 -0
  62. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_list_response.rb +51 -0
  63. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_list_response_unsubscribed_item.rb +50 -0
  64. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_set_message.rb +25 -0
  65. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_set_request.rb +42 -0
  66. data/lib/unione/api/obsolete/model/obsolete_unsubscribed_set_response.rb +64 -0
  67. data/lib/unione/api/obsolete/obsolete_api.rb +57 -0
  68. data/lib/unione/api/project/model/project_create_request.rb +42 -0
  69. data/lib/unione/api/project/model/project_create_response.rb +60 -0
  70. data/lib/unione/api/project/model/project_delete_request.rb +52 -0
  71. data/lib/unione/api/project/model/project_list_object.rb +146 -0
  72. data/lib/unione/api/project/model/project_list_request.rb +50 -0
  73. data/lib/unione/api/project/model/project_list_response.rb +51 -0
  74. data/lib/unione/api/project/model/project_object.rb +94 -0
  75. data/lib/unione/api/project/model/project_update_object.rb +130 -0
  76. data/lib/unione/api/project/model/project_update_request.rb +60 -0
  77. data/lib/unione/api/project/model/project_update_response.rb +52 -0
  78. data/lib/unione/api/project/project_api.rb +71 -0
  79. data/lib/unione/api/suppression/model/suppression_delete_request.rb +42 -0
  80. data/lib/unione/api/suppression/model/suppression_get_object.rb +91 -0
  81. data/lib/unione/api/suppression/model/suppression_get_request.rb +52 -0
  82. data/lib/unione/api/suppression/model/suppression_get_response.rb +59 -0
  83. data/lib/unione/api/suppression/model/suppression_list_object.rb +91 -0
  84. data/lib/unione/api/suppression/model/suppression_list_request.rb +94 -0
  85. data/lib/unione/api/suppression/model/suppression_list_response.rb +61 -0
  86. data/lib/unione/api/suppression/model/suppression_set_request.rb +69 -0
  87. data/lib/unione/api/suppression/suppression_api.rb +63 -0
  88. data/lib/unione/api/system/model/project_accounting_object.rb +62 -0
  89. data/lib/unione/api/system/model/system_info_response.rb +95 -0
  90. data/lib/unione/api/system/model/system_info_response_accounting.rb +68 -0
  91. data/lib/unione/api/system/model/system_ping_response.rb +51 -0
  92. data/lib/unione/api/system/system_api.rb +35 -0
  93. data/lib/unione/api/tag/model/tag_delete_request.rb +42 -0
  94. data/lib/unione/api/tag/model/tag_list_response.rb +51 -0
  95. data/lib/unione/api/tag/model/tags_response_object.rb +50 -0
  96. data/lib/unione/api/tag/tag_api.rb +40 -0
  97. data/lib/unione/api/template/model/editor_type.rb +19 -0
  98. data/lib/unione/api/template/model/template_delete_request.rb +42 -0
  99. data/lib/unione/api/template/model/template_get_request.rb +42 -0
  100. data/lib/unione/api/template/model/template_get_response.rb +51 -0
  101. data/lib/unione/api/template/model/template_list_object.rb +232 -0
  102. data/lib/unione/api/template/model/template_list_request.rb +52 -0
  103. data/lib/unione/api/template/model/template_list_response.rb +51 -0
  104. data/lib/unione/api/template/model/template_object.rb +201 -0
  105. data/lib/unione/api/template/model/template_set_request.rb +42 -0
  106. data/lib/unione/api/template/model/template_set_response.rb +51 -0
  107. data/lib/unione/api/template/template_api.rb +66 -0
  108. data/lib/unione/api/webhook/model/block_type.rb +20 -0
  109. data/lib/unione/api/webhook/model/device_type.rb +22 -0
  110. data/lib/unione/api/webhook/model/domain_status.rb +19 -0
  111. data/lib/unione/api/webhook/model/event_name.rb +19 -0
  112. data/lib/unione/api/webhook/model/traffic_type.rb +24 -0
  113. data/lib/unione/api/webhook/model/webhook_callback.rb +52 -0
  114. data/lib/unione/api/webhook/model/webhook_callback_events_by_user_item.rb +66 -0
  115. data/lib/unione/api/webhook/model/webhook_callback_events_by_user_item_events_item.rb +52 -0
  116. data/lib/unione/api/webhook/model/webhook_callback_events_by_user_item_events_item_event_data.rb +167 -0
  117. data/lib/unione/api/webhook/model/webhook_callback_events_by_user_item_events_item_event_data_delivery_info.rb +192 -0
  118. data/lib/unione/api/webhook/model/webhook_delete_request.rb +42 -0
  119. data/lib/unione/api/webhook/model/webhook_event_format.rb +18 -0
  120. data/lib/unione/api/webhook/model/webhook_events_object.rb +52 -0
  121. data/lib/unione/api/webhook/model/webhook_get_request.rb +42 -0
  122. data/lib/unione/api/webhook/model/webhook_get_response.rb +51 -0
  123. data/lib/unione/api/webhook/model/webhook_list_request.rb +51 -0
  124. data/lib/unione/api/webhook/model/webhook_list_response.rb +51 -0
  125. data/lib/unione/api/webhook/model/webhook_object.rb +123 -0
  126. data/lib/unione/api/webhook/model/webhook_set_request.rb +109 -0
  127. data/lib/unione/api/webhook/model/webhook_set_response.rb +51 -0
  128. data/lib/unione/api/webhook/model/webhook_status.rb +21 -0
  129. data/lib/unione/api/webhook/webhook_api.rb +89 -0
  130. data/lib/unione/client/api_client.rb +93 -0
  131. data/lib/unione/client/api_error.rb +22 -0
  132. data/lib/unione/client/configuration.rb +49 -0
  133. data/lib/unione/client/decode.rb +33 -0
  134. data/lib/unione/common/model/attachments_array_item.rb +59 -0
  135. data/lib/unione/common/model/body_object.rb +57 -0
  136. data/lib/unione/common/model/email_counter_mode.rb +21 -0
  137. data/lib/unione/common/model/email_status.rb +23 -0
  138. data/lib/unione/common/model/headers_object.rb +72 -0
  139. data/lib/unione/common/model/inline_attachments_array_item.rb +59 -0
  140. data/lib/unione/common/model/success_response.rb +41 -0
  141. data/lib/unione/common/model/template_engine.rb +19 -0
  142. data/lib/unione/common/model/verification_record_status.rb +16 -0
  143. data/lib/unione/uni_one_client.rb +127 -0
  144. data/lib/unione/version.rb +5 -0
  145. data/lib/unione.rb +130 -0
  146. metadata +187 -0
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Api
5
+ module Webhook
6
+ module Model
7
+ # WebhookSetRequest
8
+ class WebhookSetRequest
9
+ # URL that will receive the notification when an event occurs. The URL should be unique for a user or
10
+ # a project. Only ASCII characters are supported for now in URL, please convert to
11
+ # [Punycode](https://en.wikipedia.org/wiki/Punycode) if you need to use non-ASCII characters.
12
+ # @return [String, nil]
13
+ attr_accessor :url
14
+
15
+ # Webhook status, "active" by default. "disabled" means that webhook has been disabled by the user,
16
+ # "stopped" means that webhook has been stopped by the system after 24h of failed calls (with minimum
17
+ # of 10 distinct events).
18
+ # Default: `active`.
19
+ # @return [WebhookStatus, nil]
20
+ attr_accessor :status
21
+
22
+ # Notification format. "json_post"(default) or "json_post_gzip".
23
+ # Default: `json_post`.
24
+ # @return [WebhookEventFormat, nil]
25
+ attr_accessor :event_format
26
+
27
+ # Shall detailed delivery info be returned(1) or not(0). When it's 1, the information about SMTP
28
+ # response and internal delivery status is returned for "hard_bounced" and "soft_bounced" email
29
+ # statuses; the user agent, recipient IP address, detected geo fields, device info detected from the
30
+ # user agent (device type and brand, OS name, browser or email client name) and traffic_type (human,
31
+ # machine, protected or unknown) are returned for "opened" and "clicked" statuses; URL is returned for
32
+ # "clicked" status. For "delivered", "soft_bounced" and "hard_bounced" statuses UniOne may also return
33
+ # sender_ip, the IP address of the SMTP server that sent the message, if available.
34
+ # Allowed values: `0`, `1`.
35
+ # Default: `0`.
36
+ # @return [Integer, nil]
37
+ attr_accessor :delivery_info
38
+
39
+ # 0=several event notifications can be reported in single webhook call, 1=only single event can be
40
+ # reported in one call (not recommended).
41
+ # Allowed values: `0`, `1`.
42
+ # Default: `0`.
43
+ # @return [Integer, nil]
44
+ attr_accessor :single_event
45
+
46
+ # Maximum quantity of permitted parallel queries to your server. The more your server can handle - the
47
+ # better.
48
+ # Default: `10`.
49
+ # @return [Integer, nil]
50
+ attr_accessor :max_parallel
51
+
52
+ # Object containing events to notify of.
53
+ # @return [WebhookEventsObject, nil]
54
+ attr_accessor :events
55
+
56
+ def initialize(
57
+ url:,
58
+ status: nil,
59
+ event_format: nil,
60
+ delivery_info: nil,
61
+ single_event: nil,
62
+ max_parallel: nil,
63
+ events: nil
64
+ )
65
+ @url = url
66
+ @status = status
67
+ @event_format = event_format
68
+ @delivery_info = delivery_info
69
+ @single_event = single_event
70
+ @max_parallel = max_parallel
71
+ @events = events
72
+ end
73
+
74
+ # Builds the object from decoded JSON. Lenient: a missing field, nil or a value of another type
75
+ # gives nil (data that is not a Hash gives an empty object).
76
+ def self.from_h(data)
77
+ data = {} unless data.is_a?(Hash)
78
+ new(
79
+ url: data['url'],
80
+ status: data['status'],
81
+ event_format: data['event_format'],
82
+ delivery_info: data['delivery_info'],
83
+ single_event: data['single_event'],
84
+ max_parallel: data['max_parallel'],
85
+ events: ::UniOne::Client::Decode.model(::UniOne::Api::Webhook::Model::WebhookEventsObject, data['events'])
86
+ )
87
+ end
88
+
89
+ # JSON-ready hash, nil fields are omitted.
90
+ def to_h
91
+ {
92
+ 'url' => @url,
93
+ 'status' => @status,
94
+ 'event_format' => @event_format,
95
+ 'delivery_info' => @delivery_info,
96
+ 'single_event' => @single_event,
97
+ 'max_parallel' => @max_parallel,
98
+ 'events' => @events.nil? ? nil : @events.to_h,
99
+ }.compact
100
+ end
101
+
102
+ def to_json(*args)
103
+ to_h.to_json(*args)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Api
5
+ module Webhook
6
+ module Model
7
+ # WebhookSetResponse
8
+ class WebhookSetResponse
9
+ # "success" string
10
+ # Allowed values: `success`.
11
+ # @return [String, nil]
12
+ attr_accessor :status
13
+
14
+ # Object with all the webhook properties.
15
+ # @return [WebhookObject, nil]
16
+ attr_accessor :object
17
+
18
+ def initialize(
19
+ status: nil,
20
+ object: nil
21
+ )
22
+ @status = status
23
+ @object = object
24
+ end
25
+
26
+ # Builds the object from decoded JSON. Lenient: a missing field, nil or a value of another type
27
+ # gives nil (data that is not a Hash gives an empty object).
28
+ def self.from_h(data)
29
+ data = {} unless data.is_a?(Hash)
30
+ new(
31
+ status: data['status'],
32
+ object: ::UniOne::Client::Decode.model(::UniOne::Api::Webhook::Model::WebhookObject, data['object'])
33
+ )
34
+ end
35
+
36
+ # JSON-ready hash, nil fields are omitted.
37
+ def to_h
38
+ {
39
+ 'status' => @status,
40
+ 'object' => @object.nil? ? nil : @object.to_h,
41
+ }.compact
42
+ end
43
+
44
+ def to_json(*args)
45
+ to_h.to_json(*args)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Api
5
+ module Webhook
6
+ module Model
7
+ # Webhook status, "active" by default. "disabled" means that webhook has been disabled by the user,
8
+ # "stopped" means that webhook has been stopped by the system after 24h of failed calls (with minimum
9
+ # of 10 distinct events).
10
+ module WebhookStatus
11
+ ACTIVE = 'active'
12
+ DISABLED = 'disabled'
13
+ STOPPED = 'stopped'
14
+
15
+ # All values
16
+ ALL = [ACTIVE, DISABLED, STOPPED].freeze
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module UniOne
6
+ module Api
7
+ module Webhook
8
+ # UniOne lets you recieve notifications about email status changes or spam blocks. You provide an URL
9
+ # and every time a watched event occurs we will notify you by submitting a request with JSON data to
10
+ # this URL.
11
+ #
12
+ # You can configure the format of webhook calls (JSON or gzipped JSON), which events you want to be
13
+ # notified of, whether or not you let us groups several events in one request, do you want to receive
14
+ # extra details like SMTP answer or recipient's user agent, etc.
15
+ #
16
+ # Please note that your webhook handler should be able to process at least 5 parallel requests, up to
17
+ # 100 events each (but you can configure the maximum number of parallel connections up to 100, which
18
+ # is recommended).
19
+ #
20
+ # If the URL of your webhook handler is not available (the response is not HTTP 200 OK within 3
21
+ # seconds timeout), the system will repeat requests each 10 minutes during 24 hours, passing extra
22
+ # parameter retry_count. If there were at least 10 events during last 24 hours and all the webhook
23
+ # requests about these events have failed then we consider webhook handler broken and change it's
24
+ # status to inactive automatically. A notification about that is sent to an email [configured in
25
+ # control panel](https://cp.unione.io/en/user/alerting/technical/).
26
+ #
27
+ # The format of webhook request and details of each event are described
28
+ # [here](https://docs.unione.io/en/web-api-ref#callback-format).
29
+ class WebhookApi
30
+ # @param client [::UniOne::Client::ApiClient]
31
+ def initialize(client)
32
+ @client = client
33
+ end
34
+
35
+ # Sets or edits a [webhook](https://docs.unione.io/en/web-api-ref#webhook), i.e. an event notification
36
+ # handler.
37
+ #
38
+ # Documentation: https://docs.unione.io/en/web-api-ref#webhook-set
39
+ # @param request [::UniOne::Api::Webhook::Model::WebhookSetRequest, Hash]
40
+ # @return [::UniOne::Api::Webhook::Model::WebhookSetResponse]
41
+ # @raise [::UniOne::Client::ApiError]
42
+ def set(request)
43
+ ::UniOne::Api::Webhook::Model::WebhookSetResponse.from_h(@client.call('/webhook/set.json', request.is_a?(Hash) ? request : request.to_h))
44
+ end
45
+
46
+ # Gets properties of a [webhook](https://docs.unione.io/en/web-api-ref#webhook).
47
+ #
48
+ # Documentation: https://docs.unione.io/en/web-api-ref#webhook-get
49
+ # @param request [::UniOne::Api::Webhook::Model::WebhookGetRequest, Hash]
50
+ # @return [::UniOne::Api::Webhook::Model::WebhookGetResponse]
51
+ # @raise [::UniOne::Client::ApiError]
52
+ def get(request)
53
+ ::UniOne::Api::Webhook::Model::WebhookGetResponse.from_h(@client.call('/webhook/get.json', request.is_a?(Hash) ? request : request.to_h))
54
+ end
55
+
56
+ # List all or some [webhooks](https://docs.unione.io/en/web-api-ref#webhook) (event notification
57
+ # handlers) of a user or a project.
58
+ #
59
+ # Documentation: https://docs.unione.io/en/web-api-ref#webhook-list
60
+ # @param request [::UniOne::Api::Webhook::Model::WebhookListRequest, Hash]
61
+ # @return [::UniOne::Api::Webhook::Model::WebhookListResponse]
62
+ # @raise [::UniOne::Client::ApiError]
63
+ def list(request)
64
+ ::UniOne::Api::Webhook::Model::WebhookListResponse.from_h(@client.call('/webhook/list.json', request.is_a?(Hash) ? request : request.to_h))
65
+ end
66
+
67
+ # Deletes an event notification handler
68
+ #
69
+ # You can also temporarily deactivate webhook without deleting it by setting it's status to "disabled"
70
+ # in [webhook/set](https://docs.unione.io/en/web-api-ref#webhook-set) method.
71
+ #
72
+ # Documentation: https://docs.unione.io/en/web-api-ref#webhook-delete
73
+ # @param request [::UniOne::Api::Webhook::Model::WebhookDeleteRequest, Hash]
74
+ # @return [::UniOne::Common::Model::SuccessResponse]
75
+ # @raise [::UniOne::Client::ApiError]
76
+ def delete(request)
77
+ ::UniOne::Common::Model::SuccessResponse.from_h(@client.call('/webhook/delete.json', request.is_a?(Hash) ? request : request.to_h))
78
+ end
79
+
80
+ # Webhook callback format description.
81
+ # @param body [String] raw body of the incoming request
82
+ # @return [::UniOne::Api::Webhook::Model::WebhookCallback]
83
+ def self.parse_callback(body)
84
+ ::UniOne::Api::Webhook::Model::WebhookCallback.from_h(JSON.parse(body))
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module UniOne
8
+ module Client
9
+ # The SDK and its version in the "platform" query parameter of every request.
10
+ PLATFORM = 'ruby-sdk.1.1.3'
11
+
12
+ # Default transport (HTTP layer of ApiClient): Net::HTTP of the standard library.
13
+ #
14
+ # A transport is any object responding to call(method, uri, headers, body, timeout) -> [status, body]
15
+ # (a lambda works too): method 'POST', uri [URI::HTTP] with the query string, headers [Hash] with the API key,
16
+ # body [String] JSON, timeout [Numeric] seconds; it returns the HTTP status [Integer] and the raw response body
17
+ # [String]. HTTP error statuses are returned, not raised; any exception becomes an ApiError.
18
+ class NetHttpTransport
19
+ def call(method, uri, headers, body, timeout)
20
+ request = Net::HTTPGenericRequest.new(method, true, true, uri)
21
+ headers.each { |name, value| request[name] = value }
22
+ request.body = body
23
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https',
24
+ open_timeout: timeout, read_timeout: timeout) do |http|
25
+ http.request(request)
26
+ end
27
+ [response.code.to_i, response.body.to_s]
28
+ end
29
+ end
30
+
31
+ # Low level client: every API method is a POST request with a JSON body that returns JSON.
32
+ class ApiClient
33
+ # @return [Configuration]
34
+ attr_reader :config
35
+ # @return [#call] HTTP layer, see NetHttpTransport
36
+ attr_reader :transport
37
+
38
+ # @param config [Configuration]
39
+ # @param transport [#call, nil] call(method, uri, headers, body, timeout) -> [status, body]; nil: NetHttpTransport
40
+ def initialize(config, transport: nil)
41
+ @config = config
42
+ @transport = transport || NetHttpTransport.new
43
+ end
44
+
45
+ # Headers of every request: JSON, User-Agent, the API key, then Configuration#headers.
46
+ # @return [Hash{String => String}]
47
+ def headers
48
+ {
49
+ 'Content-Type' => 'application/json',
50
+ 'Accept' => 'application/json',
51
+ 'User-Agent' => @config.user_agent,
52
+ 'X-API-KEY' => @config.api_key
53
+ }.merge((@config.headers || {}).transform_keys(&:to_s))
54
+ end
55
+
56
+ # Calls an API method, e.g. call('/email/send.json', {...}), and returns the decoded response.
57
+ # @raise [ApiError]
58
+ def call(path, body = {})
59
+ uri = URI("#{@config.base_url}/#{path.sub(%r{\A/+}, '')}")
60
+ uri.query = URI.encode_www_form(platform: [@config.platform, PLATFORM].compact.reject(&:empty?).join(','))
61
+ status, raw = send_request(uri, JSON.generate(body || {}))
62
+ status = status.to_i
63
+ raw = raw.to_s
64
+ begin
65
+ data = JSON.parse(raw)
66
+ rescue JSON::ParserError => e
67
+ raise ApiError.new("Invalid JSON in response (HTTP #{status}): #{raw[0, 500]} (#{e.message})",
68
+ http_status: status)
69
+ end
70
+ raise ApiError.new("Unexpected response (HTTP #{status}): #{raw[0, 500]}", http_status: status) unless data.is_a?(Hash)
71
+
72
+ if status >= 400 || data['status'] == 'error'
73
+ code = data['code']
74
+ raise ApiError.new((data['message'] || 'API error').to_s,
75
+ http_status: status,
76
+ error_code: code.to_s =~ /\A\d+\z/ ? code.to_i : nil,
77
+ response_body: data)
78
+ end
79
+ data
80
+ end
81
+
82
+ private
83
+
84
+ def send_request(uri, body)
85
+ @transport.call('POST', uri, headers, body, @config.timeout)
86
+ rescue ApiError
87
+ raise
88
+ rescue StandardError => e
89
+ raise ApiError.new("HTTP request failed: #{e.class}: #{e.message}")
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Client
5
+ # Raised when the API returns an error or the response can not be processed.
6
+ class ApiError < StandardError
7
+ # @return [Integer] HTTP status of the response, 0 when the request was not sent
8
+ attr_reader :http_status
9
+ # @return [Integer, nil] API error code (the "code" field of the error response)
10
+ attr_reader :error_code
11
+ # @return [Hash, nil] decoded error response
12
+ attr_reader :response_body
13
+
14
+ def initialize(message, http_status: 0, error_code: nil, response_body: nil)
15
+ super(message)
16
+ @http_status = http_status
17
+ @error_code = error_code
18
+ @response_body = response_body
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Client
5
+ # API connection settings.
6
+ class Configuration
7
+ DEFAULT_BASE_URL = 'https://api.unione.io/en/transactional/api/v1'
8
+ # API host api.unione.io
9
+ HOST_API = 'api.unione.io'
10
+ # API host eu1.unione.io
11
+ HOST_EU1 = 'eu1.unione.io'
12
+ # API host us1.unione.io
13
+ HOST_US1 = 'us1.unione.io'
14
+ # Path of the API on every host
15
+ BASE_PATH = '/en/transactional/api/v1'
16
+
17
+ # Base URL for an API host: 'eu1.unione.io' -> 'https://eu1.unione.io' + BASE_PATH; a full URL is kept as is.
18
+ def self.base_url_for(host)
19
+ return host.sub(%r{/+\z}, '') if host.include?('://')
20
+
21
+ "https://#{host.gsub(%r{\A/+|/+\z}, '')}#{BASE_PATH}"
22
+ end
23
+
24
+ # @return [String] user or project API key, sent in the X-API-KEY header
25
+ attr_accessor :api_key
26
+ # @return [String] base URL of the API
27
+ attr_accessor :base_url
28
+ # @return [Integer] request timeout in seconds
29
+ attr_accessor :timeout
30
+ # @return [String]
31
+ attr_accessor :user_agent
32
+ # @return [String, nil] package that uses the SDK and its version (e.g. 'rails.1.0.0'), sent in the "platform" query
33
+ # parameter before the SDK one (Client::PLATFORM)
34
+ attr_accessor :platform
35
+ # @return [Hash{String => String}] extra HTTP headers of every request (e.g. a tracing id); they override the
36
+ # default ones of the same name
37
+ attr_accessor :headers
38
+
39
+ def initialize(api_key, base_url: DEFAULT_BASE_URL, timeout: 30, user_agent: 'unione-ruby-sdk/1.1.3', platform: nil, headers: {})
40
+ @api_key = api_key
41
+ @base_url = base_url.sub(%r{/+\z}, '')
42
+ @timeout = timeout
43
+ @user_agent = user_agent
44
+ @platform = platform
45
+ @headers = headers || {}
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Client
5
+ # Lenient decoding of responses for the models: a response that lacks a field, has null in it or a value of
6
+ # another type does not break from_h, the field is nil (a model is built only from a Hash, a list only from an
7
+ # Array).
8
+ module Decode
9
+ module_function
10
+
11
+ # klass.from_h(value) for a Hash, nil for anything else.
12
+ def model(klass, value)
13
+ value.is_a?(Hash) ? klass.from_h(value) : nil
14
+ end
15
+
16
+ # The array (each item through the block, if given), nil for anything else.
17
+ def list(value, &block)
18
+ return nil unless value.is_a?(Array)
19
+
20
+ block ? value.map(&block) : value
21
+ end
22
+
23
+ # The hash (each value through the block, if given; [] - an empty object encoded as an array - gives {}),
24
+ # nil for anything else.
25
+ def map(value, &block)
26
+ return {} if value.is_a?(Array) && value.empty?
27
+ return nil unless value.is_a?(Hash)
28
+
29
+ block ? value.transform_values(&block) : value
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Common
5
+ module Model
6
+ # AttachmentsArrayItem
7
+ class AttachmentsArrayItem
8
+ # Attachment type, see [MIME](https://en.wikipedia.org/wiki/MIME). If unsure, use
9
+ # "application/octet-stream".
10
+ # @return [String, nil]
11
+ attr_accessor :type
12
+
13
+ # Attachment name in the format: "name.extension". When multiple attachments are passed, their names
14
+ # must be unique. The symbol ‘/’ is not allowed in attachment names.
15
+ # @return [String, nil]
16
+ attr_accessor :name
17
+
18
+ # File contents in [base64](https://en.wikipedia.org/wiki/Base64). Maximum file size 7MB (9786710
19
+ # bytes in base64).
20
+ # @return [String, nil]
21
+ attr_accessor :content
22
+
23
+ def initialize(
24
+ type:,
25
+ name:,
26
+ content:
27
+ )
28
+ @type = type
29
+ @name = name
30
+ @content = content
31
+ end
32
+
33
+ # Builds the object from decoded JSON. Lenient: a missing field, nil or a value of another type
34
+ # gives nil (data that is not a Hash gives an empty object).
35
+ def self.from_h(data)
36
+ data = {} unless data.is_a?(Hash)
37
+ new(
38
+ type: data['type'],
39
+ name: data['name'],
40
+ content: data['content']
41
+ )
42
+ end
43
+
44
+ # JSON-ready hash, nil fields are omitted.
45
+ def to_h
46
+ {
47
+ 'type' => @type,
48
+ 'name' => @name,
49
+ 'content' => @content,
50
+ }.compact
51
+ end
52
+
53
+ def to_json(*args)
54
+ to_h.to_json(*args)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Common
5
+ module Model
6
+ # Contains HTML/plaintext/AMP parts of the email. Either html or plaintext part is required.
7
+ class BodyObject
8
+ # HTML part of the email body
9
+ # @return [String, nil]
10
+ attr_accessor :html
11
+
12
+ # Plaintext part of the email body.
13
+ # @return [String, nil]
14
+ attr_accessor :plaintext
15
+
16
+ # Optional [AMP](http://amp.dev/documentation/guides-and-tutorials/learn/email_fundamentals/) part of
17
+ # the email body.
18
+ # @return [String, nil]
19
+ attr_accessor :amp
20
+
21
+ def initialize(
22
+ html: nil,
23
+ plaintext: nil,
24
+ amp: nil
25
+ )
26
+ @html = html
27
+ @plaintext = plaintext
28
+ @amp = amp
29
+ end
30
+
31
+ # Builds the object from decoded JSON. Lenient: a missing field, nil or a value of another type
32
+ # gives nil (data that is not a Hash gives an empty object).
33
+ def self.from_h(data)
34
+ data = {} unless data.is_a?(Hash)
35
+ new(
36
+ html: data['html'],
37
+ plaintext: data['plaintext'],
38
+ amp: data['amp']
39
+ )
40
+ end
41
+
42
+ # JSON-ready hash, nil fields are omitted.
43
+ def to_h
44
+ {
45
+ 'html' => @html,
46
+ 'plaintext' => @plaintext,
47
+ 'amp' => @amp,
48
+ }.compact
49
+ end
50
+
51
+ def to_json(*args)
52
+ to_h.to_json(*args)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Common
5
+ module Model
6
+ # Sets the email counter mode. It allows you to choose whether the counter should reset automatically,
7
+ # or remain permanent. The following values are acceptable: 'default' - the counter resets to zero
8
+ # automatically at the beginning of each accounting period, 'permanent' - the counter never resets
9
+ # automatically. The reset can be done only manually by the user in the request with the passes 0
10
+ # value in the email_counter field. If the request doesn't contain the field or contains a null value,
11
+ # the limit value doesn't change.
12
+ module EmailCounterMode
13
+ DEFAULT = 'default'
14
+ PERMANENT = 'permanent'
15
+
16
+ # All values
17
+ ALL = [DEFAULT, PERMANENT].freeze
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniOne
4
+ module Common
5
+ module Model
6
+ # EmailStatus
7
+ module EmailStatus
8
+ SENT = 'sent'
9
+ DELIVERED = 'delivered'
10
+ OPENED = 'opened'
11
+ CLICKED = 'clicked'
12
+ UNSUBSCRIBED = 'unsubscribed'
13
+ SUBSCRIBED = 'subscribed'
14
+ SOFT_BOUNCED = 'soft_bounced'
15
+ HARD_BOUNCED = 'hard_bounced'
16
+ SPAM = 'spam'
17
+
18
+ # All values
19
+ ALL = [SENT, DELIVERED, OPENED, CLICKED, UNSUBSCRIBED, SUBSCRIBED, SOFT_BOUNCED, HARD_BOUNCED, SPAM].freeze
20
+ end
21
+ end
22
+ end
23
+ end