wavix-sdk-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +124 -0
  4. data/lib/middleware/follow_redirects_middleware.rb +15 -0
  5. data/lib/services/fields_validator.rb +26 -0
  6. data/lib/wavix-sdk-ruby.rb +5 -0
  7. data/lib/wavix_api/base_methods.rb +180 -0
  8. data/lib/wavix_api/v1/base_destroy.rb +31 -0
  9. data/lib/wavix_api/v1/base_find.rb +31 -0
  10. data/lib/wavix_api/v1/base_search.rb +31 -0
  11. data/lib/wavix_api/v1/billing/invoices/find.rb +44 -0
  12. data/lib/wavix_api/v1/billing/invoices/search.rb +21 -0
  13. data/lib/wavix_api/v1/billing/transactions/search.rb +39 -0
  14. data/lib/wavix_api/v1/buy/carts/checkout.rb +23 -0
  15. data/lib/wavix_api/v1/buy/carts/find.rb +23 -0
  16. data/lib/wavix_api/v1/buy/carts/update.rb +34 -0
  17. data/lib/wavix_api/v1/buy/cities/search.rb +47 -0
  18. data/lib/wavix_api/v1/buy/countries/search.rb +31 -0
  19. data/lib/wavix_api/v1/buy/dids/search.rb +41 -0
  20. data/lib/wavix_api/v1/buy/regions/search.rb +33 -0
  21. data/lib/wavix_api/v1/call/recordings/destroy.rb +23 -0
  22. data/lib/wavix_api/v1/call/recordings/month_statistics/details.rb +35 -0
  23. data/lib/wavix_api/v1/call/recordings/month_statistics/search.rb +35 -0
  24. data/lib/wavix_api/v1/call/recordings/recording_settings.rb +40 -0
  25. data/lib/wavix_api/v1/call/recordings/retention_policy.rb +23 -0
  26. data/lib/wavix_api/v1/call/recordings/search.rb +55 -0
  27. data/lib/wavix_api/v1/call/recordings/update_recording_settings.rb +48 -0
  28. data/lib/wavix_api/v1/call/recordings/update_retention_policy.rb +37 -0
  29. data/lib/wavix_api/v1/call/transcriptions/find.rb +31 -0
  30. data/lib/wavix_api/v1/call/transcriptions/retranscribe.rb +35 -0
  31. data/lib/wavix_api/v1/cdrs/advanced_search.rb +67 -0
  32. data/lib/wavix_api/v1/cdrs/common_vars.rb +22 -0
  33. data/lib/wavix_api/v1/cdrs/metrics.rb +29 -0
  34. data/lib/wavix_api/v1/cdrs/search.rb +35 -0
  35. data/lib/wavix_api/v1/e911_records/create.rb +47 -0
  36. data/lib/wavix_api/v1/e911_records/destroy.rb +31 -0
  37. data/lib/wavix_api/v1/e911_records/search.rb +33 -0
  38. data/lib/wavix_api/v1/e911_records/validate_address.rb +44 -0
  39. data/lib/wavix_api/v1/mydids/cities.rb +32 -0
  40. data/lib/wavix_api/v1/mydids/destroy.rb +55 -0
  41. data/lib/wavix_api/v1/mydids/find.rb +21 -0
  42. data/lib/wavix_api/v1/mydids/search.rb +35 -0
  43. data/lib/wavix_api/v1/mydids/update.rb +40 -0
  44. data/lib/wavix_api/v1/mydids/update_destinations.rb +73 -0
  45. data/lib/wavix_api/v1/mydids/update_sms_enabled.rb +32 -0
  46. data/lib/wavix_api/v1/papers/create.rb +65 -0
  47. data/lib/wavix_api/v1/papers/find.rb +42 -0
  48. data/lib/wavix_api/v1/profile/account_config.rb +21 -0
  49. data/lib/wavix_api/v1/profile/find.rb +21 -0
  50. data/lib/wavix_api/v1/profile/update.rb +58 -0
  51. data/lib/wavix_api/v1/sub_organizations/create.rb +36 -0
  52. data/lib/wavix_api/v1/sub_organizations/find.rb +19 -0
  53. data/lib/wavix_api/v1/sub_organizations/search.rb +31 -0
  54. data/lib/wavix_api/v1/sub_organizations/transactions.rb +39 -0
  55. data/lib/wavix_api/v1/sub_organizations/update.rb +40 -0
  56. data/lib/wavix_api/v1/trunks/create.rb +76 -0
  57. data/lib/wavix_api/v1/trunks/destroy.rb +19 -0
  58. data/lib/wavix_api/v1/trunks/find.rb +19 -0
  59. data/lib/wavix_api/v1/trunks/search.rb +30 -0
  60. data/lib/wavix_api/v1/trunks/update.rb +85 -0
  61. data/lib/wavix_api/v1/voice_campaigns/create.rb +39 -0
  62. data/lib/wavix_api/v1/voice_campaigns/find.rb +21 -0
  63. data/lib/wavix_api/v2/base_destroy.rb +10 -0
  64. data/lib/wavix_api/v2/base_find.rb +10 -0
  65. data/lib/wavix_api/v2/base_search.rb +10 -0
  66. data/lib/wavix_api/v2/messages/all.rb +23 -0
  67. data/lib/wavix_api/v2/messages/async_create.rb +23 -0
  68. data/lib/wavix_api/v2/messages/attachments/find.rb +59 -0
  69. data/lib/wavix_api/v2/messages/common_vars.rb +50 -0
  70. data/lib/wavix_api/v2/messages/create.rb +24 -0
  71. data/lib/wavix_api/v2/messages/find.rb +19 -0
  72. data/lib/wavix_api/v2/messages/opt_outs/create.rb +34 -0
  73. data/lib/wavix_api/v2/messages/search.rb +23 -0
  74. data/lib/wavix_api/v2/messages/sender_ids/create.rb +40 -0
  75. data/lib/wavix_api/v2/messages/sender_ids/destroy.rb +21 -0
  76. data/lib/wavix_api/v2/messages/sender_ids/find.rb +21 -0
  77. data/lib/wavix_api/v2/messages/sender_ids/restrictions.rb +32 -0
  78. data/lib/wavix_api/v2/messages/sender_ids/search.rb +21 -0
  79. data/lib/wavix_api/v3/messages/sender_ids/create.rb +51 -0
  80. data/lib/wavix_api/v3/messages/sender_ids/find.rb +21 -0
  81. data/lib/wavix_api/v3/messages/sender_ids/search.rb +21 -0
  82. data/lib/wavix_api.rb +155 -0
  83. data/wavix-sdk-ruby.gemspec +40 -0
  84. metadata +204 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7109971ce5978d84427cf88468e30e1d579f237f8100643bd1b1b1555512ce6d
4
+ data.tar.gz: a10cec01767eecd0254cca6364247f201643a6a7b887adf6727c51f82d5fc941
5
+ SHA512:
6
+ metadata.gz: 6e6712f8ade79a0d43a2dc6c376cda0ecf20b946ddf8623ad15c7fcebad5dad28748924b4c4409cf4e15995ce02971fd59db7a256d53628795373e925cbc1e6f
7
+ data.tar.gz: 336d67bc2673dabf399def966dcd1ed66e8080da77e9de7953d1a3ce48a0603f1d176b126b8570f8824dc810439f8374bbb8f29ab963e7af138b1d1c1b93372b
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Wavix
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # Wavix Backend Public API Ruby SDK
2
+
3
+ Welcome to the Wavix Ruby SDK documentation. This guide will walk you through installing, configuring, and using the Wavix Ruby SDK to interact seamlessly with the Wavix Backend Public API.
4
+
5
+ ## Installing the SDK
6
+
7
+ To include the Wavix Ruby SDK in your application, add the following line to your Gemfile:
8
+
9
+ gem 'wavix-sdk-ruby'
10
+
11
+ Then, run `bundle install` to install the gem.
12
+
13
+ ## Configuration
14
+
15
+ First, obtain your token for connecting to the API (more information [here](https://wavix.com/api#/rest/getting-started/api-key-management)). Then, configure the `WavixApi` class with the necessary variables to enable future requests:
16
+ ```
17
+ WavixApi.host = 'api.wavix.com'
18
+ WavixApi.api_key = 'your_token'
19
+ ```
20
+ Replace `your_token` with the token you received.
21
+
22
+ ## Overview
23
+
24
+ The Wavix Ruby SDK uses the [Faraday](https://github.com/lostisland/faraday) gem for making HTTP requests and returns service results using [Struct](https://ruby-doc.org/core-2.5.1/Struct.html).
25
+
26
+ Response attributes:
27
+
28
+ Attribute | Description | Example
29
+ ------------- | ------------- | -------------
30
+ status | Response status code | 200
31
+ status_str | String value of response status code | OK
32
+ body | Response JSON body | `"{\"success\":true}"`
33
+ parsed_body | Parsed response body | `{ "success" => true }`
34
+ success? | Boolean state of response status | `true`
35
+
36
+ The Wavix Ruby SDK uses the [json-schema](https://github.com/voxpupuli/json-schema) for body and parameter validation. Errors related to invalid data in arguments will follow the logic of `json-schema`. These errors are raised as `WavixApi::ValidationError`, allowing you to handle them using `rescue`.
37
+
38
+ "The property '#/a' of type String did not match the following type: integer"
39
+
40
+ ## Examples
41
+
42
+ Once you have set your credentials, you can use the SDK to interact with the [Wavix Public API](https://wavix.com/api).
43
+
44
+ ### Getting profile data
45
+ ```
46
+ > WavixApi::V1::Profile::Find.new.call
47
+ => #<struct status=200, status_str="OK", body="{\"id\":1,\"additional_info\":\"dev\",\"attn_contact_name\":\"wavix\",\"billing_address\":\"wavix in the house\",\"company_name\":\"wavix\",\"contact_email\":\"some@email.com\",\"default_destinations\":[],\"default_short_link_endpoint\":null,\"email\":\"some@email.com\",\"first_name\":\"First\",\"last_name\":\"Last\",\"phone\":\"1234567890\",\"timezone\":\"Europe/Berlin\"}", parsed_body={"id"=>1, "additional_info"=>"dev", "attn_contact_name"=>"wavix", "billing_address"=>"wavix in the house", "company_name"=>"wavix", "contact_email"=>"some@email.com", "default_destinations"=>[{"transport"=>"sip", "value"=>"Default SIP URI"}, {"transport"=>"pstn", "value"=>"Default PSTN"}], "default_short_link_endpoint"=>nil, "phone"=>"79231234567", "timezone"=>"Europe/Berlin"}, success?=true>
48
+ ```
49
+
50
+ Alternatively, you can use a more concise version to achieve identical results.
51
+ ```
52
+ > WavixApi::V1::Profile::Find.call
53
+ => #<struct status=200, status_str="OK", body="{\"id\":1,\"additional_info\":\"dev\",\"attn_contact_name\":\"wavix\",\"billing_address\":\"wavix in the house\",\"company_name\":\"wavix\",\"contact_email\":\"some@email.com\",\"default_destinations\":[],\"default_short_link_endpoint\":null,\"email\":\"some@email.com\",\"first_name\":\"First\",\"last_name\":\"Last\",\"phone\":\"1234567890\",\"timezone\":\"Europe/Berlin\"}", parsed_body={"id"=>1, "additional_info"=>"dev", "attn_contact_name"=>"wavix", "billing_address"=>"wavix in the house", "company_name"=>"wavix", "contact_email"=>"some@email.com", "default_destinations"=>[{"transport"=>"sip", "value"=>"Default SIP URI"}, {"transport"=>"pstn", "value"=>"Default PSTN"}], "default_short_link_endpoint"=>nil, "phone"=>"79231234567", "timezone"=>"Europe/Berlin"}, success?=true>
54
+ ```
55
+
56
+
57
+ ### Searching Available DID Numbers for Purchase with Parameters
58
+ ```
59
+ > WavixApi::V1::Buy::Dids::Search.new(type_filter: '', text_enabled_only: false, country_id: 1, city_id: 2}).call
60
+ => #<struct status=200, status_str="OK", body="{\"dids\":[],\"pagination\":{\"total\":0,\"total_pages\":1,\"current_page\":1,\"per_page\":50}}", parsed_body={"dids"=>[], "pagination"=>{"total"=>0, "total_pages"=>1, "current_page"=>1, "per_page"=>50}}, success?=true>
61
+ ```
62
+
63
+ Or short version
64
+ ```
65
+ > WavixApi::V1::Buy::Dids::Search.call(type_filter: '', text_enabled_only: false, country_id: 1, city_id: 2)
66
+ ```
67
+
68
+
69
+ ### Destroy call recording by ID
70
+ ```
71
+ > WavixApi::V1::Call::Recordings::Destroy.new(id: 123).call
72
+ => #<struct status=400, status_str="Bad Request", body="{\"error\":true,\"message\":\"deleted due to the retention policy settings\",\"deleted_at\":\"2023-12-17T00:01:08.000Z\"}", parsed_body={"error"=>true, "message"=>"deleted due to the retention policy settings", "deleted_at"=>"2023-12-17T00:01:08.000Z"}, success?=false>
73
+ ```
74
+
75
+ ### Create message with body
76
+ ```
77
+ > WavixApi::V2::Messages::Create.new(
78
+ from: '12345678901',
79
+ to: '12345678902',
80
+ message_body: {
81
+ text: 'Test ruby sdk'
82
+ }
83
+ ).call
84
+ => #<struct status=201, status_str=“Created”, body="{\"charge\":\"0.0\",\"delivered_at\":null,\"error_message\":null,\"from\":\"+12345678901\",\"mcc\":\"310\",\"message_body\":{\"text\":\"Test ruby sdk\",\"media\":[]},\"message_id\":\"27b6ed5b-3536-412e-b0e3-4f421ba54212\",\"message_type\":\"sms\",\"mnc\":\"000\",\"segments\":1,\"sent_at\":null,\"status\":\"accepted\",\"submitted_at\":\"2024-06-26T14:02:08\",\"tag\":null,\"to\":\"+12345678902\"}", parsed_body={"charge"=>"0.0", "delivered_at"=>nil, "error_message"=>nil, "from"=>"+12345678901", "mcc"=>"310", "message_body"=>{"text"=>"Test ruby sdk", "media"=>[]}, "message_id"=>"27b6ed5b-3536-412e-b0e3-4f421ba54212", "message_type"=>"sms", "mnc"=>"000", "segments"=>1, "sent_at"=>nil, "status"=>"accepted", "submitted_at"=>"2024-06-26T14:02:08", "tag"=>nil, "to"=>"+12345678902"}, success?=true>
85
+ ```
86
+
87
+ Or short version
88
+
89
+ ```
90
+ > WavixApi::V2::Messages::Create.call(
91
+ from: '12345678901',
92
+ to: '12345678902',
93
+ message_body: {
94
+ text: 'Test ruby sdk'
95
+ }
96
+ )
97
+ ```
98
+
99
+ ### Update Sub-organizations with ID and body
100
+ ```
101
+ > WavixApi::V1::SubOrganizations::Update.new(name: 'Test ruby SDK', id: 123).call
102
+ => #<struct status=200, status_str="OK", body="{\"api_key\":\"key\",\"created_at\":\"2024-03-12T15:32:49.000Z\",\"default_destinations\":{\"sms_endpoint\":\"\",\"dlr_endpoint\":\"\"},\"id\":123,\"master_organization\":100000,\"name\":\"Test ruby SDK\",\"status\":\"enabled\"}", parsed_body={"api_key"=>"key", "created_at"=>"2024-03-12T15:32:49.000Z", "default_destinations"=>{"sms_endpoint"=>"", "dlr_endpoint"=>""}, "id"=>123, "master_organization"=>100000, "name"=>"Test ruby SDK", "status"=>"enabled"}, success?=true>
103
+ ```
104
+
105
+ Or short version
106
+ ```
107
+ > WavixApi::V1::SubOrganizations::Update.call(name: 'Test ruby SDK', id: 123)
108
+ ```
109
+
110
+ ## Download billing invoice PDF
111
+
112
+ You can specify the path to save the file
113
+
114
+ ```
115
+ WavixApi::V1::Billing::Invoices::Find.new(id: 1, save_path: 'path/to/file.pdf').call
116
+ ```
117
+
118
+ ## Create papers with File
119
+
120
+ To upload a file, use `File.open(path)`.
121
+
122
+ ```
123
+ WavixApi::V1::Papers::Create.new(did_ids: '1,2', doc_id: 3, doc_attachment: File.open('file.jpg')}).call
124
+ ```
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ class FollowRedirectsMiddleware < Faraday::Middleware
5
+ REDIRECT_CODES = [301, 302, 303, 307, 308].freeze
6
+
7
+ def call(env)
8
+ @app.call(env).on_complete do |response_env|
9
+ if REDIRECT_CODES.include?(response_env.status)
10
+ env.url = URI.parse(response_env[:response_headers]['location'])
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json-schema'
4
+
5
+ module Services
6
+ class FieldsValidator
7
+ attr_accessor :fields, :schema
8
+ attr_reader :error
9
+
10
+ def initialize(attributes = {})
11
+ attributes.each do |key, value|
12
+ instance_variable_set("@#{key}", value)
13
+ end
14
+ end
15
+
16
+ def call
17
+ JSON::Validator.validate!(schema, fields)
18
+ rescue JSON::Schema::ValidationError => e
19
+ @error = e.message
20
+ end
21
+
22
+ def valid?
23
+ @error.nil?
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavix_api'
4
+
5
+ Dir[File.join(__dir__, 'wavix_api/**/*.rb')].sort.each { |file| require file }
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'services/fields_validator'
4
+
5
+ module WavixApi
6
+ class ValidationError < StandardError; end
7
+
8
+ module BaseMethods
9
+ attr_reader :params, :id, :client
10
+
11
+ DEFAULT_HEADERS = { 'Content-Type' => 'application/json' }.freeze
12
+ PAGINATION_SCHEMA = {
13
+ page: { type: 'integer' },
14
+ per_page: { type: 'integer' }
15
+ }.freeze
16
+ ONLY_ID_SCHEMA = {
17
+ type: 'object',
18
+ properties: {
19
+ id: { type: 'integer' }.freeze
20
+ }.freeze,
21
+ required: %i[id].freeze
22
+ }.freeze
23
+ ONLY_UUID_SCHEMA = {
24
+ type: 'object',
25
+ properties: {
26
+ id: { type: 'string' }.freeze
27
+ }.freeze,
28
+ required: %i[id].freeze
29
+ }.freeze
30
+ AVAILABLE_TRANSCRIPTION_LANGUAGES = %w[en de es fr it].freeze
31
+ BASE_DATE_FORMAT = '%Y-%m-%d'
32
+ ONLY_DIGITS_REGEXP = /^\d+$/.freeze
33
+ IP_REGEXP = /^\d(\.\d)*$/.freeze
34
+ LIST_OF_DIGITS_REGEXP = /^\d+(,\d+)*$/.freeze
35
+
36
+ class << self
37
+ attr_accessor :params_schema
38
+ end
39
+
40
+ def initialize(params = {})
41
+ @params = deep_symbolize_keys(params)
42
+ @id = @params[:id]
43
+ @client = ::WavixApi.client
44
+ end
45
+
46
+ def validate!
47
+ validate_params! unless self.class.instance_variable_get('@params_schema').nil?
48
+ validate_appid!
49
+ end
50
+
51
+ def validate_dates!(fields, step_params: params)
52
+ invalid_fields = fields.select do |field|
53
+ value = step_params[field.to_sym]
54
+ nested = field.to_s.split('.')
55
+ # INFO: in case of nested key. For example: item.date_from, item.nested_item.date_from
56
+ if nested.count > 1
57
+ validate_dates!(nested[1..-1], step_params: step_params[nested.first.to_i])
58
+ else
59
+ !value.is_a?(::DateTime) && (!value.nil? && !value.empty?)
60
+ end
61
+ end
62
+ return true if invalid_fields.empty?
63
+
64
+ raise_error("Fields #{invalid_fields} must be a DateTime")
65
+ end
66
+
67
+ def stringify_dates!(params, fields:, format: BASE_DATE_FORMAT)
68
+ fields.each do |field|
69
+ nested = field.to_s.split('.')
70
+ # INFO: in case of nested key. For example: item.date_from, item.nested_item.date_from
71
+ if nested.count > 1
72
+ key = nested.first.to_sym
73
+ stringify_dates!(params[key], fields: nested[1..-1].join('.'), format: format)
74
+ else
75
+ value = params[field.to_sym]
76
+ next if !value.is_a?(::DateTime) && (value.nil? || value.empty?)
77
+
78
+ params[field.to_sym] = value.strftime(format)
79
+ end
80
+ end
81
+ end
82
+
83
+ def get(path, headers: {})
84
+ client.get(
85
+ path,
86
+ params: params.merge(additional_params),
87
+ headers: DEFAULT_HEADERS.merge(headers)
88
+ )
89
+ end
90
+
91
+ def download(path, headers: {}, save_path: nil)
92
+ client.download(
93
+ path,
94
+ params: params.merge(additional_params),
95
+ headers: DEFAULT_HEADERS.merge(headers),
96
+ save_path: save_path
97
+ )
98
+ end
99
+
100
+ def post(path, with_file: false, headers: {})
101
+ client.post(
102
+ path,
103
+ params: additional_params,
104
+ headers: DEFAULT_HEADERS.merge(headers),
105
+ body: params.except(:id),
106
+ with_file: with_file
107
+ )
108
+ end
109
+
110
+ def put(path)
111
+ client.put(path, body: params.except(:id), params: additional_params)
112
+ end
113
+
114
+ def patch(path)
115
+ client.patch(path, body: params.except(:id), params: additional_params)
116
+ end
117
+
118
+ def delete(path)
119
+ client.delete(path, params: params.merge(additional_params))
120
+ end
121
+
122
+ def raise_error(error)
123
+ raise ValidationError, error
124
+ end
125
+
126
+ def format_file(file, content_type: 'multipart/form-data')
127
+ Faraday::Multipart::FilePart.new(file.path, content_type)
128
+ end
129
+
130
+ def file_extention(file)
131
+ File.extname(file.path).to_s[1..-1]
132
+ end
133
+
134
+ def call
135
+ self.class.call(params)
136
+ end
137
+
138
+ private
139
+
140
+ def deep_transform_keys_in_object(object, &block)
141
+ case object
142
+ when Hash
143
+ object.each_with_object({}) do |(key, value), result|
144
+ result[yield(key)] = deep_transform_keys_in_object(value, &block)
145
+ end
146
+ when Array
147
+ object.map { |e| deep_transform_keys_in_object(e, &block) }
148
+ else
149
+ object
150
+ end
151
+ end
152
+
153
+ def deep_symbolize_keys(object)
154
+ deep_transform_keys_in_object(object) do |key|
155
+ key.to_sym
156
+ rescue StandardError
157
+ key
158
+ end
159
+ end
160
+
161
+ def validate_appid!
162
+ raise_error('api_key is required') if WavixApi.api_key.nil? || WavixApi.api_key.empty?
163
+ end
164
+
165
+ def validate_params!
166
+ service = ::Services::FieldsValidator.new(
167
+ fields: params,
168
+ schema: self.class.instance_variable_get('@params_schema')
169
+ )
170
+ service.call
171
+ raise_error(service.error) unless service.valid?
172
+ end
173
+
174
+ def additional_params
175
+ { appid: WavixApi.api_key }.tap do |res|
176
+ res[:id] = id if !id.nil? && (id.is_a?(Integer) || id.empty?)
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavix_api'
4
+
5
+ module WavixApi
6
+ module V1
7
+ class BaseDestroy
8
+ include ::WavixApi::BaseMethods
9
+
10
+ class << self
11
+ def call(id = nil)
12
+ instance = new({ id: id })
13
+
14
+ instance.validate!
15
+
16
+ instance.delete([path, instance.id].join('/'))
17
+ end
18
+
19
+ private
20
+
21
+ def path
22
+ raise NoMethodError
23
+ end
24
+ end
25
+
26
+ def call
27
+ self.class.call(id)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavix_api'
4
+
5
+ module WavixApi
6
+ module V1
7
+ class BaseFind
8
+ include WavixApi::BaseMethods
9
+
10
+ class << self
11
+ def call(id = nil)
12
+ instance = new({ id: id })
13
+
14
+ instance.validate!
15
+
16
+ instance.get([path, instance.id].join('/'))
17
+ end
18
+
19
+ private
20
+
21
+ def path
22
+ raise NoMethodError
23
+ end
24
+ end
25
+
26
+ def call
27
+ self.class.call(id)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavix_api'
4
+
5
+ module WavixApi
6
+ module V1
7
+ class BaseSearch
8
+ include WavixApi::BaseMethods
9
+
10
+ class << self
11
+ def call(params = {})
12
+ instance = new(params)
13
+
14
+ instance.validate!
15
+
16
+ instance.get(path)
17
+ end
18
+
19
+ private
20
+
21
+ def path
22
+ raise NoMethodError
23
+ end
24
+ end
25
+
26
+ def call
27
+ self.class.call(@params)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavix_api'
4
+
5
+ module WavixApi
6
+ module V1
7
+ module Billing
8
+ module Invoices
9
+ class Find
10
+ include WavixApi::BaseMethods
11
+
12
+ @params_schema = ::WavixApi::BaseMethods::ONLY_ID_SCHEMA
13
+
14
+ class << self
15
+ def call(id = nil, save_path: nil)
16
+ instance = new({ id: id })
17
+
18
+ instance.validate!
19
+
20
+ instance.download(
21
+ ['v1/billing/invoices', instance.id].join('/'),
22
+ headers: {
23
+ 'Content-Disposition' => 'attachment; filename="invoice.pdf"',
24
+ 'Content-Type' => 'application/octet-stream',
25
+ 'Content-Transfer-Encoding' => 'binary'
26
+ },
27
+ save_path: save_path
28
+ )
29
+ end
30
+ end
31
+
32
+ def initialize(params = {})
33
+ super(params)
34
+ @save_path = @params[:save_path]
35
+ end
36
+
37
+ def call
38
+ self.class.call(id, save_path: @save_path)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavix_api'
4
+
5
+ module WavixApi
6
+ module V1
7
+ module Billing
8
+ module Invoices
9
+ class Search < ::WavixApi::V1::BaseSearch
10
+ class << self
11
+ private
12
+
13
+ def path
14
+ 'v1/billing/invoices'
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavix_api'
4
+
5
+ module WavixApi
6
+ module V1
7
+ module Billing
8
+ module Transactions
9
+ class Search
10
+ include WavixApi::BaseMethods
11
+
12
+ DATE_FIELDS = %i[from_date to_date].freeze
13
+
14
+ @params_schema = {
15
+ type: 'object',
16
+ properties: {
17
+ type: { type: 'integer' }.freeze,
18
+ payments: { type: 'boolean' }.freeze,
19
+ details_contains: { type: 'string' }.freeze,
20
+ **::WavixApi::BaseMethods::PAGINATION_SCHEMA
21
+ },
22
+ required: DATE_FIELDS
23
+ }.freeze
24
+
25
+ class << self
26
+ def call(params = {})
27
+ instance = new(params)
28
+
29
+ instance.validate!
30
+ instance.validate_dates!(DATE_FIELDS)
31
+ instance.stringify_dates!(instance.params, fields: DATE_FIELDS)
32
+ instance.get('v1/billing/transactions')
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WavixApi
4
+ module V1
5
+ module Buy
6
+ module Carts
7
+ class Checkout
8
+ include WavixApi::BaseMethods
9
+
10
+ class << self
11
+ def call(params = {})
12
+ instance = new(params)
13
+
14
+ instance.validate!
15
+
16
+ instance.post('v1/buy/cart/checkout')
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WavixApi
4
+ module V1
5
+ module Buy
6
+ module Carts
7
+ class Find
8
+ include WavixApi::BaseMethods
9
+
10
+ class << self
11
+ def call(params = {})
12
+ instance = new(params)
13
+
14
+ instance.validate!
15
+
16
+ instance.get('v1/buy/cart')
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WavixApi
4
+ module V1
5
+ module Buy
6
+ module Carts
7
+ class Update
8
+ include WavixApi::BaseMethods
9
+
10
+ @params_schema = {
11
+ type: 'object',
12
+ properties: {
13
+ ids: {
14
+ type: 'string',
15
+ pattern: ::WavixApi::BaseMethods::LIST_OF_DIGITS_REGEXP
16
+ }.freeze
17
+ }.freeze,
18
+ required: %i[ids].freeze
19
+ }.freeze
20
+
21
+ class << self
22
+ def call(params = {})
23
+ instance = new(params)
24
+
25
+ instance.validate!
26
+
27
+ instance.patch('v1/buy/cart')
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end