wavix-sdk-ruby 1.0.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 (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