roistat 0.1.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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/CHANGELOG.md +18 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +757 -0
  6. data/Rakefile +12 -0
  7. data/docs/ru/README.md +142 -0
  8. data/lefthook.yml +8 -0
  9. data/lib/generators/roistat/install/install_generator.rb +13 -0
  10. data/lib/generators/roistat/install/templates/roistat.rb +13 -0
  11. data/lib/roistat/client.rb +220 -0
  12. data/lib/roistat/configuration.rb +17 -0
  13. data/lib/roistat/errors.rb +18 -0
  14. data/lib/roistat/resources/access.rb +25 -0
  15. data/lib/roistat/resources/analytics.rb +68 -0
  16. data/lib/roistat/resources/base.rb +31 -0
  17. data/lib/roistat/resources/billing.rb +17 -0
  18. data/lib/roistat/resources/calltracking.rb +102 -0
  19. data/lib/roistat/resources/channels.rb +28 -0
  20. data/lib/roistat/resources/clients.rb +38 -0
  21. data/lib/roistat/resources/dashboards.rb +13 -0
  22. data/lib/roistat/resources/emailtracking.rb +16 -0
  23. data/lib/roistat/resources/events.rb +42 -0
  24. data/lib/roistat/resources/indicators.rb +13 -0
  25. data/lib/roistat/resources/lead_hunter.rb +8 -0
  26. data/lib/roistat/resources/leads.rb +33 -0
  27. data/lib/roistat/resources/managers.rb +33 -0
  28. data/lib/roistat/resources/mediaplan.rb +23 -0
  29. data/lib/roistat/resources/orders.rb +76 -0
  30. data/lib/roistat/resources/projects.rb +30 -0
  31. data/lib/roistat/resources/proxy_leads.rb +18 -0
  32. data/lib/roistat/resources/sms.rb +15 -0
  33. data/lib/roistat/resources/speech.rb +68 -0
  34. data/lib/roistat/resources/statistics.rb +8 -0
  35. data/lib/roistat/resources/visits.rb +23 -0
  36. data/lib/roistat/resources/vpbx.rb +100 -0
  37. data/lib/roistat/resources/widgets.rb +17 -0
  38. data/lib/roistat/response.rb +88 -0
  39. data/lib/roistat/version.rb +5 -0
  40. data/lib/roistat.rb +66 -0
  41. data/mise.toml +14 -0
  42. data/sig/roistat.rbs +251 -0
  43. metadata +187 -0
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "tempfile"
5
+
6
+ class Roistat::Response
7
+ ERROR_MAP = {
8
+ "authentication_failed" => Roistat::AuthenticationError,
9
+ "authorization_failed" => Roistat::AuthorizationError,
10
+ "access_denied" => Roistat::AccessDeniedError,
11
+ "request_limit_error" => Roistat::RateLimitError
12
+ }.freeze
13
+
14
+ def self.parse(http_response, parse:, binary_tempfile_threshold:)
15
+ new(http_response, parse: parse, binary_tempfile_threshold: binary_tempfile_threshold).parse
16
+ end
17
+
18
+ def initialize(http_response, parse:, binary_tempfile_threshold:)
19
+ @http_response = http_response
20
+ @parse = parse
21
+ @binary_tempfile_threshold = binary_tempfile_threshold
22
+ end
23
+
24
+ def parse
25
+ raise_transport_error! if transport_failure?
26
+
27
+ body = @http_response.body.to_s
28
+ return parse_binary(body) if @parse == :binary
29
+
30
+ parsed = parse_json(body)
31
+ raise_api_error!(parsed) if api_error?(parsed)
32
+ parsed
33
+ end
34
+
35
+ private
36
+
37
+ def transport_failure?
38
+ return false unless @http_response.respond_to?(:error) && @http_response.error
39
+
40
+ # HTTP status errors (4xx/5xx) still expose a body — map them via JSON.
41
+ !@http_response.respond_to?(:status) || @http_response.status.nil?
42
+ end
43
+
44
+ def raise_transport_error!
45
+ raise Roistat::Error, @http_response.error.message
46
+ end
47
+
48
+ def parse_json(body)
49
+ return {} if body.nil? || body.empty?
50
+
51
+ JSON.parse(body)
52
+ rescue JSON::ParserError => e
53
+ raise Roistat::Error, "Invalid JSON response: #{e.message}"
54
+ end
55
+
56
+ def api_error?(parsed)
57
+ parsed.is_a?(Hash) && parsed["status"].to_s == "error"
58
+ end
59
+
60
+ def raise_api_error!(parsed)
61
+ code = parsed["error"].to_s
62
+ error_class = ERROR_MAP.fetch(code, Roistat::Error)
63
+ raise error_class.new(
64
+ "Roistat API error: #{code}",
65
+ code: code,
66
+ http_status: @http_response.status,
67
+ response_body: parsed
68
+ )
69
+ end
70
+
71
+ def parse_binary(body)
72
+ size = content_length || body.bytesize
73
+ return body if size <= @binary_tempfile_threshold
74
+
75
+ tempfile = Tempfile.new(["roistat", ".bin"], binmode: true)
76
+ tempfile.write(body.b)
77
+ tempfile.rewind
78
+ tempfile
79
+ end
80
+
81
+ def content_length
82
+ headers = @http_response.headers
83
+ value = headers["content-length"] || headers["Content-Length"]
84
+ Integer(value) if value
85
+ rescue ArgumentError, TypeError
86
+ nil
87
+ end
88
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roistat
4
+ VERSION = "0.1.0"
5
+ end
data/lib/roistat.rb ADDED
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "roistat/version"
4
+ require_relative "roistat/errors"
5
+ require_relative "roistat/configuration"
6
+ require_relative "roistat/response"
7
+ require_relative "roistat/client"
8
+
9
+ module Roistat::Resources
10
+ end
11
+
12
+ require_relative "roistat/resources/base"
13
+ require_relative "roistat/resources/projects"
14
+ require_relative "roistat/resources/access"
15
+ require_relative "roistat/resources/dashboards"
16
+ require_relative "roistat/resources/widgets"
17
+ require_relative "roistat/resources/billing"
18
+ require_relative "roistat/resources/calltracking"
19
+ require_relative "roistat/resources/orders"
20
+ require_relative "roistat/resources/proxy_leads"
21
+ require_relative "roistat/resources/leads"
22
+ require_relative "roistat/resources/managers"
23
+ require_relative "roistat/resources/clients"
24
+ require_relative "roistat/resources/visits"
25
+ require_relative "roistat/resources/events"
26
+ require_relative "roistat/resources/analytics"
27
+ require_relative "roistat/resources/channels"
28
+ require_relative "roistat/resources/statistics"
29
+ require_relative "roistat/resources/indicators"
30
+ require_relative "roistat/resources/lead_hunter"
31
+ require_relative "roistat/resources/emailtracking"
32
+ require_relative "roistat/resources/sms"
33
+ require_relative "roistat/resources/mediaplan"
34
+ require_relative "roistat/resources/speech"
35
+ require_relative "roistat/resources/vpbx"
36
+
37
+ module Roistat
38
+ class << self
39
+ def configuration
40
+ @configuration ||= Configuration.new
41
+ end
42
+
43
+ def configure
44
+ yield configuration
45
+ end
46
+
47
+ def reset_configuration!
48
+ @configuration = Configuration.new
49
+ @client = nil
50
+ end
51
+
52
+ def client
53
+ @client ||= Client.new(
54
+ api_key: configuration.api_key,
55
+ project: configuration.project,
56
+ base_url: configuration.base_url,
57
+ timeout: configuration.timeout,
58
+ open_timeout: configuration.open_timeout,
59
+ binary_tempfile_threshold: configuration.binary_tempfile_threshold
60
+ )
61
+ end
62
+ end
63
+ end
64
+
65
+ module Roistat::Generators
66
+ end
data/mise.toml ADDED
@@ -0,0 +1,14 @@
1
+ [tools]
2
+ ruby = "4.0.6"
3
+
4
+ [tasks.test]
5
+ description = "Run the RSpec suite"
6
+ run = "bundle exec rake spec"
7
+
8
+ [tasks.lint]
9
+ description = "Run RuboCop"
10
+ run = "bundle exec rubocop"
11
+
12
+ [tasks.release]
13
+ description = "Build and publish the gem (rake release)"
14
+ run = "bundle exec rake release"
data/sig/roistat.rbs ADDED
@@ -0,0 +1,251 @@
1
+ module Roistat
2
+ VERSION: String
3
+
4
+ def self.configuration: () -> Configuration
5
+ def self.configure: () { (Configuration) -> void } -> void
6
+ def self.reset_configuration!: () -> void
7
+ def self.client: () -> Client
8
+ end
9
+
10
+ class Roistat::Configuration
11
+ DEFAULT_BASE_URL: String
12
+ attr_accessor api_key: String?
13
+ attr_accessor project: String?
14
+ attr_accessor base_url: String
15
+ attr_accessor timeout: Integer
16
+ attr_accessor open_timeout: Integer
17
+ attr_accessor binary_tempfile_threshold: Integer
18
+ end
19
+
20
+ class Roistat::Client
21
+ def initialize: (
22
+ api_key: String,
23
+ ?project: String?,
24
+ ?project_required: bool,
25
+ ?base_url: String?,
26
+ ?timeout: Integer?,
27
+ ?open_timeout: Integer?,
28
+ ?binary_tempfile_threshold: Integer?
29
+ ) -> void
30
+
31
+ def get: (String, ?params: Hash[Symbol | String, untyped], ?parse: Symbol) -> untyped
32
+ def post: (String, ?params: Hash[Symbol | String, untyped], ?body: untyped, ?parse: Symbol) -> untyped
33
+ def post_multipart: (String, ?params: Hash[Symbol | String, untyped], ?form: Hash[Symbol | String, untyped], ?parse: Symbol) -> untyped
34
+ def request: (Symbol | String, String, ?params: Hash[Symbol | String, untyped], ?body: untyped, ?parse: Symbol) -> untyped
35
+
36
+ def projects: () -> Roistat::Resources::Projects
37
+ def access: () -> Roistat::Resources::Access
38
+ def dashboards: () -> Roistat::Resources::Dashboards
39
+ def widgets: () -> Roistat::Resources::Widgets
40
+ def billing: () -> Roistat::Resources::Billing
41
+ def calltracking: () -> Roistat::Resources::Calltracking
42
+ def orders: () -> Roistat::Resources::Orders
43
+ def proxy_leads: () -> Roistat::Resources::ProxyLeads
44
+ def leads: () -> Roistat::Resources::Leads
45
+ def managers: () -> Roistat::Resources::Managers
46
+ def clients: () -> Roistat::Resources::Clients
47
+ def visits: () -> Roistat::Resources::Visits
48
+ def events: () -> Roistat::Resources::Events
49
+ def analytics: () -> Roistat::Resources::Analytics
50
+ def channels: () -> Roistat::Resources::Channels
51
+ def statistics: () -> Roistat::Resources::Statistics
52
+ def indicators: () -> Roistat::Resources::Indicators
53
+ def lead_hunter: () -> Roistat::Resources::LeadHunter
54
+ def emailtracking: () -> Roistat::Resources::Emailtracking
55
+ def sms: () -> Roistat::Resources::Sms
56
+ def mediaplan: () -> Roistat::Resources::Mediaplan
57
+ def speech: () -> Roistat::Resources::Speech
58
+ def vpbx: () -> Roistat::Resources::Vpbx
59
+ end
60
+
61
+ class Roistat::Resources::Projects
62
+ def list: () -> untyped
63
+ def create: (name: String, currency: String) -> untyped
64
+ def modules_list: (?method: Symbol) -> untyped
65
+ def counter_list: () -> untyped
66
+ end
67
+
68
+ class Roistat::Resources::Access
69
+ def user_list: () -> untyped
70
+ def authorized_users: (?method: Symbol) -> untyped
71
+ def change: (**untyped) -> untyped
72
+ end
73
+
74
+ class Roistat::Resources::Dashboards
75
+ def list: () -> untyped
76
+ def widgets: (dashboard_id: Integer | String) -> untyped
77
+ end
78
+
79
+ class Roistat::Resources::Widgets
80
+ def data: (widget_id: Integer | String, ?method: Symbol, **untyped) -> untyped
81
+ end
82
+
83
+ class Roistat::Resources::Calltracking
84
+ def script_list: (**untyped) -> untyped
85
+ def script_create: (**untyped) -> untyped
86
+ def script_update: (**untyped) -> untyped
87
+ def script_delete: (id: Integer | String) -> untyped
88
+ def phone_list: (**untyped) -> untyped
89
+ def phone_prefix_list: (**untyped) -> untyped
90
+ def phone_create: (phones: Array[String]) -> untyped
91
+ def phone_buy: (prefix: String, count: Integer) -> untyped
92
+ def phone_update: (**untyped) -> untyped
93
+ def phone_delete: (phones: Array[Integer | String]) -> untyped
94
+ def call_list: (**untyped) -> untyped
95
+ def call_update: (**untyped) -> untyped
96
+ def call_delete: (ids: Array[Integer | String]) -> untyped
97
+ def call_file: (call_id: Integer | String) -> untyped
98
+ def call_xls_export: (period: Hash[Symbol | String, untyped]) -> untyped
99
+ def data: (period: Hash[Symbol | String, untyped]) -> untyped
100
+ def phone_call: (**untyped) -> untyped
101
+ end
102
+
103
+ class Roistat::Resources::Orders
104
+ def list: (**untyped) -> untyped
105
+ def add: (Array[untyped]) -> untyped
106
+ def info: (order_id: Integer | String) -> untyped
107
+ def external_url: (order_id: Integer | String) -> untyped
108
+ def status_list: (**untyped) -> untyped
109
+ def set_statuses: (Array[untyped]) -> untyped
110
+ def custom_fields: (**untyped) -> untyped
111
+ def status_update: (order_id: Integer | String, status_id: Integer | String) -> untyped
112
+ def goal_update: (order_id: Integer | String, **untyped) -> untyped
113
+ def update: (orders: Array[untyped]) -> untyped
114
+ def delete: (order_id: Integer | String) -> untyped
115
+ def delete_many: (ids: Array[Integer | String]) -> untyped
116
+ end
117
+
118
+ class Roistat::Resources::ProxyLeads
119
+ def list: (period: String) -> untyped
120
+ def duplicates: (period: String) -> untyped
121
+ def get: (id: Integer | String) -> untyped
122
+ end
123
+
124
+ class Roistat::Resources::Leads
125
+ def list: (**untyped) -> untyped
126
+ def status_list: (**untyped) -> untyped
127
+ def create: (**untyped) -> untyped
128
+ def update: (**untyped) -> untyped
129
+ end
130
+
131
+ class Roistat::Resources::Managers
132
+ def list: (**untyped) -> untyped
133
+ def add: (**untyped) -> untyped
134
+ def update: (**untyped) -> untyped
135
+ def delete: (id: Integer | String) -> untyped
136
+ end
137
+
138
+ class Roistat::Resources::Clients
139
+ def list: (**untyped) -> untyped
140
+ def import: (Array[untyped]) -> untyped
141
+ def detail_feed: (client: Integer | String) -> untyped
142
+ def campaign_list: (**untyped) -> untyped
143
+ def campaign_contact_list: (**untyped) -> untyped
144
+ end
145
+
146
+ class Roistat::Resources::Visits
147
+ def list: (**untyped) -> untyped
148
+ def params_update: (**untyped) -> untyped
149
+ end
150
+
151
+ class Roistat::Resources::Events
152
+ def send_event: (**untyped) -> untyped
153
+ def bulk_send: (Array[untyped]) -> untyped
154
+ def add: (Array[untyped]) -> untyped
155
+ def log: (**untyped) -> untyped
156
+ def archive: (event_id: Integer | String, events: Array[untyped]) -> untyped
157
+ end
158
+
159
+ class Roistat::Resources::Analytics
160
+ def data: (**untyped) -> untyped
161
+ def data_export_excel: (**untyped) -> untyped
162
+ def metrics_new: (**untyped) -> untyped
163
+ def dimensions: (**untyped) -> untyped
164
+ def dimension_values: (**untyped) -> untyped
165
+ def attribution_models: (**untyped) -> untyped
166
+ def list_orders: (**untyped) -> untyped
167
+ def custom_metrics_list: (**untyped) -> untyped
168
+ def custom_manual_value_list: (**untyped) -> untyped
169
+ def custom_manual_value_add: (**untyped) -> untyped
170
+ def custom_manual_value_delete: (**untyped) -> untyped
171
+ def funnel_data: (**untyped) -> untyped
172
+ def event_add: (**untyped) -> untyped
173
+ end
174
+
175
+ class Roistat::Resources::Channels
176
+ def source_list: (**untyped) -> untyped
177
+ def cost_list: (**untyped) -> untyped
178
+ def cost_add: (**untyped) -> untyped
179
+ def cost_update: (**untyped) -> untyped
180
+ def cost_delete: (id: Integer | String) -> untyped
181
+ end
182
+
183
+ class Roistat::Resources::Statistics
184
+ def get_daily: (**untyped) -> untyped
185
+ end
186
+
187
+ class Roistat::Resources::Indicators
188
+ def list: () -> untyped
189
+ def run_script: (indicator_id: Integer | String) -> untyped
190
+ end
191
+
192
+ class Roistat::Resources::LeadHunter
193
+ def list: (**untyped) -> untyped
194
+ end
195
+
196
+ class Roistat::Resources::Emailtracking
197
+ def list: (**untyped) -> untyped
198
+ def attachment: (email_id: Integer | String, attachment_id: Integer | String) -> untyped
199
+ end
200
+
201
+ class Roistat::Resources::Sms
202
+ def set_report_enabled: (enabled: bool | Integer | String) -> untyped
203
+ end
204
+
205
+ class Roistat::Resources::Mediaplan
206
+ def target_list: (**untyped) -> untyped
207
+ def target_create: (**untyped) -> untyped
208
+ def target_update: (**untyped) -> untyped
209
+ def target_delete: (id: Integer | String) -> untyped
210
+ end
211
+
212
+ class Roistat::Resources::Speech
213
+ def call_list: (**untyped) -> untyped
214
+ def call_list_export_excel: (**untyped) -> untyped
215
+ def call_add: (**untyped) -> untyped
216
+ def call_comment_update: (**untyped) -> untyped
217
+ def call_operator_update: (**untyped) -> untyped
218
+ def call_transcription_list: (**untyped) -> untyped
219
+ def dictionary_list: (**untyped) -> untyped
220
+ def dictionary_custom_create: (**untyped) -> untyped
221
+ def dictionary_custom_update: (**untyped) -> untyped
222
+ def dictionary_custom_delete: (**untyped) -> untyped
223
+ def dictionary_custom_phrase_list: (**untyped) -> untyped
224
+ def settings_list: (**untyped) -> untyped
225
+ def settings_update: (**untyped) -> untyped
226
+ end
227
+
228
+ class Roistat::Resources::Vpbx
229
+ def call_list: (**untyped) -> untyped
230
+ def operator_list: (**untyped) -> untyped
231
+ def operator_create: (**untyped) -> untyped
232
+ def operator_update: (**untyped) -> untyped
233
+ def operator_deactivate: (**untyped) -> untyped
234
+ def operator_group_list: (**untyped) -> untyped
235
+ def operator_group_create: (**untyped) -> untyped
236
+ def operator_group_update: (**untyped) -> untyped
237
+ def phone_list: (**untyped) -> untyped
238
+ def phone_create: (**untyped) -> untyped
239
+ def phone_update: (**untyped) -> untyped
240
+ def phone_delete: (**untyped) -> untyped
241
+ def script_list: (**untyped) -> untyped
242
+ def script_create: (**untyped) -> untyped
243
+ def script_update: (**untyped) -> untyped
244
+ def script_delete: (**untyped) -> untyped
245
+ def report_data: (**untyped) -> untyped
246
+ def settings_update: (**untyped) -> untyped
247
+ def settings_file_audio_upload: (file: IO, **untyped) -> untyped
248
+ end
249
+
250
+ class Roistat::Error < StandardError
251
+ end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roistat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexey Poimtsev
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: httpx
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '1.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: lefthook
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rake
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '13.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '13.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: railties
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '7.2'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '7.2'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: simplecov
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.21'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.21'
96
+ - !ruby/object:Gem::Dependency
97
+ name: webmock
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '3.0'
110
+ description: Ruby wrapper for the Roistat REST API. Configure with an API key and
111
+ project id, then call documented Roistat endpoints through resource helpers or low-level
112
+ get/post.
113
+ email:
114
+ - alexey.poimtsev@gmail.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".ruby-version"
120
+ - CHANGELOG.md
121
+ - LICENSE.txt
122
+ - README.md
123
+ - Rakefile
124
+ - docs/ru/README.md
125
+ - lefthook.yml
126
+ - lib/generators/roistat/install/install_generator.rb
127
+ - lib/generators/roistat/install/templates/roistat.rb
128
+ - lib/roistat.rb
129
+ - lib/roistat/client.rb
130
+ - lib/roistat/configuration.rb
131
+ - lib/roistat/errors.rb
132
+ - lib/roistat/resources/access.rb
133
+ - lib/roistat/resources/analytics.rb
134
+ - lib/roistat/resources/base.rb
135
+ - lib/roistat/resources/billing.rb
136
+ - lib/roistat/resources/calltracking.rb
137
+ - lib/roistat/resources/channels.rb
138
+ - lib/roistat/resources/clients.rb
139
+ - lib/roistat/resources/dashboards.rb
140
+ - lib/roistat/resources/emailtracking.rb
141
+ - lib/roistat/resources/events.rb
142
+ - lib/roistat/resources/indicators.rb
143
+ - lib/roistat/resources/lead_hunter.rb
144
+ - lib/roistat/resources/leads.rb
145
+ - lib/roistat/resources/managers.rb
146
+ - lib/roistat/resources/mediaplan.rb
147
+ - lib/roistat/resources/orders.rb
148
+ - lib/roistat/resources/projects.rb
149
+ - lib/roistat/resources/proxy_leads.rb
150
+ - lib/roistat/resources/sms.rb
151
+ - lib/roistat/resources/speech.rb
152
+ - lib/roistat/resources/statistics.rb
153
+ - lib/roistat/resources/visits.rb
154
+ - lib/roistat/resources/vpbx.rb
155
+ - lib/roistat/resources/widgets.rb
156
+ - lib/roistat/response.rb
157
+ - lib/roistat/version.rb
158
+ - mise.toml
159
+ - sig/roistat.rbs
160
+ homepage: https://github.com/alec-c4/roistat
161
+ licenses:
162
+ - MIT
163
+ metadata:
164
+ allowed_push_host: https://rubygems.org
165
+ homepage_uri: https://github.com/alec-c4/roistat
166
+ source_code_uri: https://github.com/alec-c4/roistat
167
+ changelog_uri: https://github.com/alec-c4/roistat/blob/master/CHANGELOG.md
168
+ documentation_uri: https://github.com/alec-c4/roistat/blob/master/README.md
169
+ rubygems_mfa_required: 'true'
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: 3.3.0
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements: []
184
+ rubygems_version: 4.0.17
185
+ specification_version: 4
186
+ summary: Ruby wrapper for the Roistat REST API.
187
+ test_files: []