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.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +18 -0
- data/LICENSE.txt +21 -0
- data/README.md +757 -0
- data/Rakefile +12 -0
- data/docs/ru/README.md +142 -0
- data/lefthook.yml +8 -0
- data/lib/generators/roistat/install/install_generator.rb +13 -0
- data/lib/generators/roistat/install/templates/roistat.rb +13 -0
- data/lib/roistat/client.rb +220 -0
- data/lib/roistat/configuration.rb +17 -0
- data/lib/roistat/errors.rb +18 -0
- data/lib/roistat/resources/access.rb +25 -0
- data/lib/roistat/resources/analytics.rb +68 -0
- data/lib/roistat/resources/base.rb +31 -0
- data/lib/roistat/resources/billing.rb +17 -0
- data/lib/roistat/resources/calltracking.rb +102 -0
- data/lib/roistat/resources/channels.rb +28 -0
- data/lib/roistat/resources/clients.rb +38 -0
- data/lib/roistat/resources/dashboards.rb +13 -0
- data/lib/roistat/resources/emailtracking.rb +16 -0
- data/lib/roistat/resources/events.rb +42 -0
- data/lib/roistat/resources/indicators.rb +13 -0
- data/lib/roistat/resources/lead_hunter.rb +8 -0
- data/lib/roistat/resources/leads.rb +33 -0
- data/lib/roistat/resources/managers.rb +33 -0
- data/lib/roistat/resources/mediaplan.rb +23 -0
- data/lib/roistat/resources/orders.rb +76 -0
- data/lib/roistat/resources/projects.rb +30 -0
- data/lib/roistat/resources/proxy_leads.rb +18 -0
- data/lib/roistat/resources/sms.rb +15 -0
- data/lib/roistat/resources/speech.rb +68 -0
- data/lib/roistat/resources/statistics.rb +8 -0
- data/lib/roistat/resources/visits.rb +23 -0
- data/lib/roistat/resources/vpbx.rb +100 -0
- data/lib/roistat/resources/widgets.rb +17 -0
- data/lib/roistat/response.rb +88 -0
- data/lib/roistat/version.rb +5 -0
- data/lib/roistat.rb +66 -0
- data/mise.toml +14 -0
- data/sig/roistat.rbs +251 -0
- metadata +187 -0
data/README.md
ADDED
|
@@ -0,0 +1,757 @@
|
|
|
1
|
+
# Roistat
|
|
2
|
+
|
|
3
|
+
Ruby wrapper for the [Roistat REST API](https://help-ru.roistat.com/API/methods/about/).
|
|
4
|
+
|
|
5
|
+
**[Документация на русском](docs/ru/README.md)**
|
|
6
|
+
|
|
7
|
+
The gem sends every request with the `Api-key` header (never as a `key` query param). Project-scoped calls also send `project` in the query string.
|
|
8
|
+
|
|
9
|
+
Official docs differ by language. Prefer [help-ru](https://help-ru.roistat.com/API/methods/about/) for the method list. [help-en](https://help.roistat.com/API/methods/about/) documents additional endpoints (dashboards, widgets, and alternate access/counter paths); this gem wraps those as well.
|
|
10
|
+
|
|
11
|
+
## Contents
|
|
12
|
+
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Configuration](#configuration)
|
|
15
|
+
- [Clients](#clients)
|
|
16
|
+
- [Low-level HTTP API](#low-level-http-api)
|
|
17
|
+
- [Resource APIs](#resource-apis)
|
|
18
|
+
- [Projects](#projects--clientprojects)
|
|
19
|
+
- [Access](#access--clientaccess)
|
|
20
|
+
- [Dashboards](#dashboards--clientdashboards)
|
|
21
|
+
- [Widgets](#widgets--clientwidgets)
|
|
22
|
+
- [Billing](#billing--clientbilling)
|
|
23
|
+
- [Calltracking](#calltracking--clientcalltracking)
|
|
24
|
+
- [Orders](#orders--clientorders)
|
|
25
|
+
- [Proxy leads](#proxy-leads--clientproxy_leads)
|
|
26
|
+
- [Leads](#leads--clientleads)
|
|
27
|
+
- [Managers](#managers--clientmanagers)
|
|
28
|
+
- [Clients](#clients--clientclients)
|
|
29
|
+
- [Visits](#visits--clientvisits)
|
|
30
|
+
- [Events](#events--clientevents)
|
|
31
|
+
- [Analytics](#analytics--clientanalytics)
|
|
32
|
+
- [Channels](#channels--clientchannels)
|
|
33
|
+
- [Statistics](#statistics--clientstatistics)
|
|
34
|
+
- [Indicators](#indicators--clientindicators)
|
|
35
|
+
- [Lead hunter](#lead-hunter--clientlead_hunter)
|
|
36
|
+
- [Email tracking](#email-tracking--clientemailtracking)
|
|
37
|
+
- [SMS](#sms--clientsms)
|
|
38
|
+
- [Mediaplan](#mediaplan--clientmediaplan)
|
|
39
|
+
- [Speech analytics](#speech-analytics--clientspeech)
|
|
40
|
+
- [Cloud PBX (VPBX)](#cloud-pbx-vpbx--clientvpbx)
|
|
41
|
+
- [Responses](#responses)
|
|
42
|
+
- [Errors](#errors)
|
|
43
|
+
- [Development](#development)
|
|
44
|
+
- [License](#license)
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
Add the gem to the Gemfile:
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
gem "roistat"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Then run:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bundle install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or install it directly:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
gem install roistat
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Rails
|
|
67
|
+
|
|
68
|
+
Generate the initializer:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
rails generate roistat:install
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This creates `config/initializers/roistat.rb` with all configuration options.
|
|
75
|
+
|
|
76
|
+
## Configuration
|
|
77
|
+
|
|
78
|
+
### Global config (Rails-friendly)
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
Roistat.configure do |config|
|
|
82
|
+
config.api_key = ENV.fetch("ROISTAT_API_KEY")
|
|
83
|
+
config.project = ENV.fetch("ROISTAT_PROJECT_ID")
|
|
84
|
+
|
|
85
|
+
# Optional:
|
|
86
|
+
# config.base_url = "https://cloud.roistat.com/api/v1"
|
|
87
|
+
# config.timeout = 30
|
|
88
|
+
# config.open_timeout = 10
|
|
89
|
+
# config.binary_tempfile_threshold = 1_048_576
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Then use the shared client:
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
Roistat.client.projects.list
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Configuration options
|
|
100
|
+
|
|
101
|
+
| Option | Required | Default | Description |
|
|
102
|
+
|--------|----------|---------|-------------|
|
|
103
|
+
| `api_key` | yes | — | Roistat API key (`Api-key` header) |
|
|
104
|
+
| `project` | yes for project-scoped calls | — | Project id (query `project`) |
|
|
105
|
+
| `base_url` | no | `https://cloud.roistat.com/api/v1` | API base URL |
|
|
106
|
+
| `timeout` | no | `30` | Request timeout in seconds |
|
|
107
|
+
| `open_timeout` | no | `10` | Connection open timeout in seconds |
|
|
108
|
+
| `binary_tempfile_threshold` | no | `1048576` (1 MiB) | Binary bodies larger than this become a `Tempfile` |
|
|
109
|
+
|
|
110
|
+
### Environment variables (install generator)
|
|
111
|
+
|
|
112
|
+
| Variable | Maps to |
|
|
113
|
+
|----------|---------|
|
|
114
|
+
| `ROISTAT_API_KEY` | `config.api_key` |
|
|
115
|
+
| `ROISTAT_PROJECT_ID` | `config.project` |
|
|
116
|
+
| `ROISTAT_BASE_URL` | `config.base_url` (commented in template) |
|
|
117
|
+
| `ROISTAT_TIMEOUT` | `config.timeout` (commented) |
|
|
118
|
+
| `ROISTAT_OPEN_TIMEOUT` | `config.open_timeout` (commented) |
|
|
119
|
+
| `ROISTAT_BINARY_TEMPFILE_THRESHOLD` | `config.binary_tempfile_threshold` (commented) |
|
|
120
|
+
|
|
121
|
+
## Clients
|
|
122
|
+
|
|
123
|
+
### Shared client
|
|
124
|
+
|
|
125
|
+
`Roistat.client` builds a client from the global configuration.
|
|
126
|
+
|
|
127
|
+
### Explicit client
|
|
128
|
+
|
|
129
|
+
Use a dedicated instance when you need another project or key:
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
client = Roistat::Client.new(
|
|
133
|
+
api_key: "…",
|
|
134
|
+
project: "12345",
|
|
135
|
+
timeout: 20
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
client.access.user_list
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### API-key-only client
|
|
142
|
+
|
|
143
|
+
Some account endpoints do not need a project id:
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
client = Roistat::Client.new(api_key: "…", project_required: false)
|
|
147
|
+
client.get("user/projects")
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Resource helpers that are API-key-only (`projects.list`, `projects.create`) create that client internally.
|
|
151
|
+
|
|
152
|
+
Blank or whitespace-only credentials raise `Roistat::ConfigurationError` before any HTTP call.
|
|
153
|
+
|
|
154
|
+
## Low-level HTTP API
|
|
155
|
+
|
|
156
|
+
Use these for any documented Roistat path that does not have a resource method yet:
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
client.get("project/calltracking/phone/list", params: {limit: 10})
|
|
160
|
+
client.post("project/events/send", body: {name: "purchase"})
|
|
161
|
+
client.request(:get, "project/permissions/user/list")
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Method signatures
|
|
165
|
+
|
|
166
|
+
| Method | Purpose |
|
|
167
|
+
|--------|---------|
|
|
168
|
+
| `get(path, params: {}, parse: :json)` | GET request |
|
|
169
|
+
| `post(path, params: {}, body: nil, parse: :json)` | POST request |
|
|
170
|
+
| `request(method, path, params: {}, body: nil, parse: :json)` | Arbitrary verb |
|
|
171
|
+
|
|
172
|
+
Notes:
|
|
173
|
+
|
|
174
|
+
- `path` is relative to `base_url` (leading slash is optional).
|
|
175
|
+
- `params` become query parameters. The client adds `project` automatically when the client has a project id.
|
|
176
|
+
- `body` is JSON-encoded. The gem sets `Content-Type: application/json`.
|
|
177
|
+
- `parse: :json` (default) returns a parsed Hash/Array.
|
|
178
|
+
- `parse: :binary` returns a `String` or `Tempfile` (see [Responses](#responses)).
|
|
179
|
+
|
|
180
|
+
## Resource APIs
|
|
181
|
+
|
|
182
|
+
High-level helpers are available on every client:
|
|
183
|
+
|
|
184
|
+
```ruby
|
|
185
|
+
client.projects
|
|
186
|
+
client.access
|
|
187
|
+
client.dashboards
|
|
188
|
+
client.widgets
|
|
189
|
+
client.billing
|
|
190
|
+
client.calltracking
|
|
191
|
+
client.orders
|
|
192
|
+
client.proxy_leads
|
|
193
|
+
client.leads
|
|
194
|
+
client.managers
|
|
195
|
+
client.clients
|
|
196
|
+
client.visits
|
|
197
|
+
client.events
|
|
198
|
+
client.analytics
|
|
199
|
+
client.channels
|
|
200
|
+
client.statistics
|
|
201
|
+
client.indicators
|
|
202
|
+
client.lead_hunter
|
|
203
|
+
client.emailtracking
|
|
204
|
+
client.sms
|
|
205
|
+
client.mediaplan
|
|
206
|
+
client.speech
|
|
207
|
+
client.vpbx
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Official parameter details live in the [Roistat API docs](https://help-ru.roistat.com/API/methods/about/).
|
|
211
|
+
|
|
212
|
+
### Projects — `client.projects`
|
|
213
|
+
|
|
214
|
+
| Ruby method | HTTP | Path | Auth |
|
|
215
|
+
|-------------|------|------|------|
|
|
216
|
+
| `list` | GET | `/user/projects` | API key only |
|
|
217
|
+
| `create(name:, currency:)` | POST | `/account/project/create` | API key only |
|
|
218
|
+
| `modules_list(method: :get)` | GET or POST | `/project/settings/module/list` | API key + project |
|
|
219
|
+
| `counter_list` | POST | `/project/settings/counter/list` | API key + project (help-en) |
|
|
220
|
+
|
|
221
|
+
Examples:
|
|
222
|
+
|
|
223
|
+
```ruby
|
|
224
|
+
Roistat.client.projects.list
|
|
225
|
+
Roistat.client.projects.create(name: "Demo", currency: "RUB")
|
|
226
|
+
Roistat.client.projects.modules_list
|
|
227
|
+
Roistat.client.projects.modules_list(method: :post)
|
|
228
|
+
Roistat.client.projects.counter_list
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Access — `client.access`
|
|
232
|
+
|
|
233
|
+
| Ruby method | HTTP | Path | Auth |
|
|
234
|
+
|-------------|------|------|------|
|
|
235
|
+
| `user_list` | GET | `/project/permissions/user/list` | API key + project (help-ru) |
|
|
236
|
+
| `authorized_users(method: :get)` | GET or POST | `/project/access/get-authorized-users` | API key + project (help-en) |
|
|
237
|
+
| `change(**body)` | POST | `/project/access/change` | API key + project (help-en) |
|
|
238
|
+
|
|
239
|
+
Examples:
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
Roistat.client.access.user_list
|
|
243
|
+
Roistat.client.access.authorized_users
|
|
244
|
+
Roistat.client.access.authorized_users(method: :post)
|
|
245
|
+
Roistat.client.access.change(email: "user@example.com", permissions: ["access_analytics_base_read"])
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Dashboards — `client.dashboards`
|
|
249
|
+
|
|
250
|
+
Documented on [help-en](https://help.roistat.com/API/methods/about/).
|
|
251
|
+
|
|
252
|
+
| Ruby method | HTTP | Path |
|
|
253
|
+
|-------------|------|------|
|
|
254
|
+
| `list` | GET | `/project/dashboards` |
|
|
255
|
+
| `widgets(dashboard_id:)` | GET | `/project/dashboards/{dashboardId}/widgets` |
|
|
256
|
+
|
|
257
|
+
Examples:
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
Roistat.client.dashboards.list
|
|
261
|
+
Roistat.client.dashboards.widgets(dashboard_id: 1)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Widgets — `client.widgets`
|
|
265
|
+
|
|
266
|
+
Documented on [help-en](https://help.roistat.com/API/methods/about/). Default verb is POST (matches curl examples); pass `method: :get` when needed.
|
|
267
|
+
|
|
268
|
+
| Ruby method | HTTP | Path |
|
|
269
|
+
|-------------|------|------|
|
|
270
|
+
| `data(widget_id:, method: :post, **body)` | GET or POST | `/project/widget/{widgetId}/data` |
|
|
271
|
+
|
|
272
|
+
Examples:
|
|
273
|
+
|
|
274
|
+
```ruby
|
|
275
|
+
Roistat.client.widgets.data(widget_id: 9, period: "2026-01-01-2026-01-31")
|
|
276
|
+
Roistat.client.widgets.data(widget_id: 9, method: :get)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Billing — `client.billing`
|
|
280
|
+
|
|
281
|
+
| Ruby method | HTTP | Path | Auth | Response |
|
|
282
|
+
|-------------|------|------|------|----------|
|
|
283
|
+
| `transactions_list(period:)` | POST | `/user/billing/transactions/list` | API key + project | JSON |
|
|
284
|
+
| `transactions_export_excel(period:)` | POST | `/user/billing/transactions/list/export/excel` | API key + project | binary |
|
|
285
|
+
|
|
286
|
+
`period` must include `from` and `to` (Roistat date strings).
|
|
287
|
+
|
|
288
|
+
Examples:
|
|
289
|
+
|
|
290
|
+
```ruby
|
|
291
|
+
period = {
|
|
292
|
+
from: "2026-01-01T00:00:00+0300",
|
|
293
|
+
to: "2026-07-22T23:59:59+0300"
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
Roistat.client.billing.transactions_list(period: period)
|
|
297
|
+
|
|
298
|
+
file = Roistat.client.billing.transactions_export_excel(period: period)
|
|
299
|
+
# String if ≤ 1 MiB, otherwise Tempfile
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Calltracking — `client.calltracking`
|
|
303
|
+
|
|
304
|
+
Official docs: [calltracking API](https://help-ru.roistat.com/API/methods/calltracking/). The gem uses POST for these endpoints.
|
|
305
|
+
|
|
306
|
+
| Ruby method | HTTP | Path | Notes |
|
|
307
|
+
|-------------|------|------|-------|
|
|
308
|
+
| `script_list(**body)` | POST | `/project/calltracking/script/list` | optional body (e.g. `is_deleted:`) |
|
|
309
|
+
| `script_create(**body)` | POST | `/project/calltracking/script/create` | |
|
|
310
|
+
| `script_update(**body)` | POST | `/project/calltracking/script/update` | |
|
|
311
|
+
| `script_delete(id:)` | POST | `/project/calltracking/script/delete` | |
|
|
312
|
+
| `phone_list(**body)` | POST | `/project/calltracking/phone/list` | |
|
|
313
|
+
| `phone_prefix_list(**body)` | POST | `/project/calltracking/phone/prefix/list` | |
|
|
314
|
+
| `phone_create(phones:)` | POST | `/project/calltracking/phone/create` | |
|
|
315
|
+
| `phone_buy(prefix:, count:)` | POST | `/project/calltracking/phone/buy` | |
|
|
316
|
+
| `phone_update(**body)` | POST | `/project/calltracking/phone/update` | |
|
|
317
|
+
| `phone_delete(phones:)` | POST | `/project/calltracking/phone/delete` | phone ids |
|
|
318
|
+
| `call_list(**body)` | POST | `/project/calltracking/call/list` | filters, extend, sort, limit, offset |
|
|
319
|
+
| `call_update(**body)` | POST | `/project/calltracking/call/update` | |
|
|
320
|
+
| `call_delete(ids:)` | POST | `/project/calltracking/call/delete` | |
|
|
321
|
+
| `call_file(call_id:)` | POST | `/project/calltracking/call/{id}/file` | binary (MP3) |
|
|
322
|
+
| `call_xls_export(period:)` | POST | `/project/calltracking/call/xls/export` | binary (XLS) |
|
|
323
|
+
| `data(period:)` | POST | `/project/calltracking/data` | dashboard analytics |
|
|
324
|
+
| `phone_call(**body)` | POST | `/project/phone-call` | create call history row |
|
|
325
|
+
|
|
326
|
+
Examples:
|
|
327
|
+
|
|
328
|
+
```ruby
|
|
329
|
+
Roistat.client.calltracking.phone_list
|
|
330
|
+
Roistat.client.calltracking.script_list(is_deleted: 0)
|
|
331
|
+
Roistat.client.calltracking.call_list(
|
|
332
|
+
filters: {and: [["date", ">", "2026-01-01T00:00:00+0000"]]},
|
|
333
|
+
limit: 50
|
|
334
|
+
)
|
|
335
|
+
Roistat.client.calltracking.data(period: period)
|
|
336
|
+
audio = Roistat.client.calltracking.call_file(call_id: 1234)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Orders — `client.orders`
|
|
340
|
+
|
|
341
|
+
Official docs: [orders API](https://help-ru.roistat.com/API/methods/orders/).
|
|
342
|
+
|
|
343
|
+
| Ruby method | HTTP | Path |
|
|
344
|
+
|-------------|------|------|
|
|
345
|
+
| `list(**body)` | POST | `/project/integration/order/list` |
|
|
346
|
+
| `add(orders)` | POST | `/project/add-orders` (JSON array body) |
|
|
347
|
+
| `info(order_id:)` | GET | `/project/orders/{id}/info` |
|
|
348
|
+
| `external_url(order_id:)` | GET | `/project/orders/{id}/external-url` |
|
|
349
|
+
| `status_list(**body)` | POST | `/project/integration/status/list` |
|
|
350
|
+
| `set_statuses(statuses)` | POST | `/project/set-statuses` (JSON array body) |
|
|
351
|
+
| `custom_fields(**body)` | POST | `/project/analytics/order-custom-fields` |
|
|
352
|
+
| `status_update(order_id:, status_id:)` | POST | `/project/integration/order/{id}/status/update` |
|
|
353
|
+
| `goal_update(order_id:, **body)` | POST | `/project/integration/order/{id}/goal/update` |
|
|
354
|
+
| `update(orders:)` | POST | `/project/integration/order/update` |
|
|
355
|
+
| `delete(order_id:)` | POST | `/project/integration/order/{id}/delete` |
|
|
356
|
+
| `delete_many(ids:)` | POST | `/project/integration/order/delete` |
|
|
357
|
+
|
|
358
|
+
Examples:
|
|
359
|
+
|
|
360
|
+
```ruby
|
|
361
|
+
Roistat.client.orders.list(limit: 50)
|
|
362
|
+
Roistat.client.orders.status_list
|
|
363
|
+
Roistat.client.orders.info(order_id: "order_12345")
|
|
364
|
+
Roistat.client.orders.add([
|
|
365
|
+
{id: "1", name: "New order", date_create: "2022-06-19T00:32:12+0000"}
|
|
366
|
+
])
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Proxy leads — `client.proxy_leads`
|
|
370
|
+
|
|
371
|
+
Official docs: [proxy leads API](https://help-ru.roistat.com/API/methods/proxy-leads/).
|
|
372
|
+
`period` is `YYYY-MM-DD-YYYY-MM-DD` in the query string.
|
|
373
|
+
|
|
374
|
+
| Ruby method | HTTP | Path |
|
|
375
|
+
|-------------|------|------|
|
|
376
|
+
| `list(period:)` | GET | `/project/proxy-leads` |
|
|
377
|
+
| `duplicates(period:)` | GET | `/project/proxy-leads/duplicates` |
|
|
378
|
+
| `get(id:)` | GET | `/project/proxy-leads/{id}` |
|
|
379
|
+
|
|
380
|
+
Examples:
|
|
381
|
+
|
|
382
|
+
```ruby
|
|
383
|
+
Roistat.client.proxy_leads.list(period: "2026-01-01-2026-07-22")
|
|
384
|
+
Roistat.client.proxy_leads.get(id: "2")
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Leads — `client.leads`
|
|
388
|
+
|
|
389
|
+
Official docs: [lead management API](https://help-ru.roistat.com/API/methods/lead_management/).
|
|
390
|
+
|
|
391
|
+
| Ruby method | HTTP | Path |
|
|
392
|
+
|-------------|------|------|
|
|
393
|
+
| `list(**body)` | POST | `/project/leads/lead/list` |
|
|
394
|
+
| `status_list(**body)` | POST | `/project/leads/status/list` |
|
|
395
|
+
| `create(**body)` | POST | `/project/leads/lead/create` |
|
|
396
|
+
| `update(**body)` | POST | `/project/leads/lead/update` |
|
|
397
|
+
|
|
398
|
+
Examples:
|
|
399
|
+
|
|
400
|
+
```ruby
|
|
401
|
+
Roistat.client.leads.status_list
|
|
402
|
+
Roistat.client.leads.list(
|
|
403
|
+
period: {from: "2023-10-17T21:00:00.000Z", to: "2023-11-30T20:59:59.999Z"},
|
|
404
|
+
sort_field: "creation_date",
|
|
405
|
+
limit: 20
|
|
406
|
+
)
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Managers — `client.managers`
|
|
410
|
+
|
|
411
|
+
Official docs: [managers API](https://help-ru.roistat.com/API/methods/managers/).
|
|
412
|
+
|
|
413
|
+
| Ruby method | HTTP | Path |
|
|
414
|
+
|-------------|------|------|
|
|
415
|
+
| `list(**body)` | POST | `/project/integration/manager/list` |
|
|
416
|
+
| `add(**body)` | POST | `/project/integration/manager/add` |
|
|
417
|
+
| `update(**body)` | POST | `/project/integration/manager/update` |
|
|
418
|
+
| `delete(id:)` | POST | `/project/integration/manager/delete` |
|
|
419
|
+
|
|
420
|
+
Examples:
|
|
421
|
+
|
|
422
|
+
```ruby
|
|
423
|
+
Roistat.client.managers.list
|
|
424
|
+
Roistat.client.managers.add(id: "12345", name: "Petrov", email: "a@b.c")
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Clients — `client.clients`
|
|
428
|
+
|
|
429
|
+
Official docs: [clients API](https://help-ru.roistat.com/API/methods/clients/).
|
|
430
|
+
|
|
431
|
+
| Ruby method | HTTP | Path |
|
|
432
|
+
|-------------|------|------|
|
|
433
|
+
| `list(**body)` | POST | `/project/clients` |
|
|
434
|
+
| `import(clients)` | POST | `/project/clients/import` (JSON array body) |
|
|
435
|
+
| `detail_feed(client:)` | GET | `/project/clients/detail/feed` (`client` query) |
|
|
436
|
+
| `campaign_list(**body)` | POST | `/project/clients/campaign/list` |
|
|
437
|
+
| `campaign_contact_list(**body)` | POST | `/project/clients/campaign/contact/list` |
|
|
438
|
+
|
|
439
|
+
Examples:
|
|
440
|
+
|
|
441
|
+
```ruby
|
|
442
|
+
Roistat.client.clients.list(limit: 100)
|
|
443
|
+
Roistat.client.clients.detail_feed(client: "123")
|
|
444
|
+
Roistat.client.clients.import([{id: "111", name: "Valera"}])
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Visits — `client.visits`
|
|
448
|
+
|
|
449
|
+
Official docs: [visits API](https://help-ru.roistat.com/API/methods/visit/).
|
|
450
|
+
|
|
451
|
+
| Ruby method | HTTP | Path |
|
|
452
|
+
|-------------|------|------|
|
|
453
|
+
| `list(**body)` | POST | `/project/site/visit/list` |
|
|
454
|
+
| `params_update(**body)` | POST | `/project/site/visit/params/update` |
|
|
455
|
+
|
|
456
|
+
Examples:
|
|
457
|
+
|
|
458
|
+
```ruby
|
|
459
|
+
Roistat.client.visits.list(limit: 100)
|
|
460
|
+
Roistat.client.visits.params_update(visit: "123", roistat_param1: "onlineshop")
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Events — `client.events`
|
|
464
|
+
|
|
465
|
+
Official docs: [events API](https://help-ru.roistat.com/API/methods/events/).
|
|
466
|
+
`send_event` avoids shadowing Ruby `Kernel#send`.
|
|
467
|
+
|
|
468
|
+
| Ruby method | HTTP | Path |
|
|
469
|
+
|-------------|------|------|
|
|
470
|
+
| `send_event(**body)` | POST | `/project/events/send` |
|
|
471
|
+
| `bulk_send(events)` | POST | `/project/events/bulk/send` (JSON array) |
|
|
472
|
+
| `add(events)` | POST | `/project/events/add` (JSON array) |
|
|
473
|
+
| `log(**params)` | GET | `/project/events/log` (filters as query params) |
|
|
474
|
+
| `archive(event_id:, events:)` | POST | `/project/events/meta/{id}/archive` (JSON array) |
|
|
475
|
+
|
|
476
|
+
Examples:
|
|
477
|
+
|
|
478
|
+
```ruby
|
|
479
|
+
Roistat.client.events.log(name: "Cart")
|
|
480
|
+
Roistat.client.events.send_event(name: "Purchase", visit: "100001")
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Analytics — `client.analytics`
|
|
484
|
+
|
|
485
|
+
Official docs: [analytics API](https://help-ru.roistat.com/API/methods/analytics/).
|
|
486
|
+
|
|
487
|
+
| Ruby method | HTTP | Path |
|
|
488
|
+
|-------------|------|------|
|
|
489
|
+
| `data(**body)` | POST | `/project/analytics/data` |
|
|
490
|
+
| `data_export_excel(**body)` | POST | `/project/analytics/data/export/excel` (binary) |
|
|
491
|
+
| `metrics_new(**body)` | POST | `/project/analytics/metrics-new` |
|
|
492
|
+
| `dimensions(**body)` | POST | `/project/analytics/dimensions` |
|
|
493
|
+
| `dimension_values(**body)` | POST | `/project/analytics/dimension-values` |
|
|
494
|
+
| `attribution_models(**body)` | POST | `/project/analytics/attribution-models` |
|
|
495
|
+
| `list_orders(**body)` | POST | `/project/analytics/list-orders` |
|
|
496
|
+
| `custom_metrics_list(**params)` | GET | `/project/analytics/metrics/custom/list` |
|
|
497
|
+
| `custom_manual_value_list(**body)` | POST | `/project/analytics/metrics/custom/manual/value/list` |
|
|
498
|
+
| `custom_manual_value_add(**body)` | POST | `/project/analytics/metrics/custom/manual/value/add` |
|
|
499
|
+
| `custom_manual_value_delete(**body)` | POST | `/project/analytics/metrics/custom/manual/value/delete` |
|
|
500
|
+
| `funnel_data(**body)` | POST | `/project/reports/funnel/data` |
|
|
501
|
+
| `event_add(**body)` | POST | `/project/analytics/event/add` |
|
|
502
|
+
|
|
503
|
+
Examples:
|
|
504
|
+
|
|
505
|
+
```ruby
|
|
506
|
+
Roistat.client.analytics.dimensions
|
|
507
|
+
Roistat.client.analytics.metrics_new
|
|
508
|
+
Roistat.client.analytics.custom_metrics_list
|
|
509
|
+
Roistat.client.analytics.data(
|
|
510
|
+
period: {from: "2026-01-01T00:00:00+0300", to: "2026-07-31T23:59:59+0300"},
|
|
511
|
+
metrics: ["visits"],
|
|
512
|
+
dimensions: ["marker_level_1"]
|
|
513
|
+
)
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Channels — `client.channels`
|
|
517
|
+
|
|
518
|
+
Official docs: [channels / source costs API](https://help-ru.roistat.com/API/methods/channels/).
|
|
519
|
+
|
|
520
|
+
| Ruby method | HTTP | Path |
|
|
521
|
+
|-------------|------|------|
|
|
522
|
+
| `source_list(**body)` | POST | `/project/analytics/source/list` |
|
|
523
|
+
| `cost_list(**body)` | POST | `/project/analytics/source/cost/list` |
|
|
524
|
+
| `cost_add(**body)` | POST | `/project/analytics/source/cost/add` |
|
|
525
|
+
| `cost_update(**body)` | POST | `/project/analytics/source/cost/update` |
|
|
526
|
+
| `cost_delete(id:)` | POST | `/project/analytics/source/cost/delete` |
|
|
527
|
+
|
|
528
|
+
Examples:
|
|
529
|
+
|
|
530
|
+
```ruby
|
|
531
|
+
Roistat.client.channels.source_list
|
|
532
|
+
Roistat.client.channels.cost_list
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### Statistics — `client.statistics`
|
|
536
|
+
|
|
537
|
+
Official docs: [statistics API](https://help-ru.roistat.com/API/methods/statistics/).
|
|
538
|
+
|
|
539
|
+
| Ruby method | HTTP | Path |
|
|
540
|
+
|-------------|------|------|
|
|
541
|
+
| `get_daily(**body)` | POST | `/project/statistics/get-daily` (`period`: `YYYY-MM-DD-YYYY-MM-DD` in UTC; optional `time_zone`, `channel`) |
|
|
542
|
+
|
|
543
|
+
Examples:
|
|
544
|
+
|
|
545
|
+
```ruby
|
|
546
|
+
Roistat.client.statistics.get_daily(period: "2026-01-01-2026-07-22")
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Indicators — `client.indicators`
|
|
550
|
+
|
|
551
|
+
Official docs: [health indicators API](https://help-ru.roistat.com/API/methods/indicators/).
|
|
552
|
+
|
|
553
|
+
| Ruby method | HTTP | Path |
|
|
554
|
+
|-------------|------|------|
|
|
555
|
+
| `list` | GET | `/project/health/indicator/list` |
|
|
556
|
+
| `run_script(indicator_id:)` | POST | `/project/health/indicator/{id}/run-script` |
|
|
557
|
+
|
|
558
|
+
Examples:
|
|
559
|
+
|
|
560
|
+
```ruby
|
|
561
|
+
Roistat.client.indicators.list
|
|
562
|
+
Roistat.client.indicators.run_script(indicator_id: 7)
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Lead hunter — `client.lead_hunter`
|
|
566
|
+
|
|
567
|
+
Official docs: [lead hunter API](https://help-ru.roistat.com/API/methods/lead-hunter/).
|
|
568
|
+
|
|
569
|
+
| Ruby method | HTTP | Path |
|
|
570
|
+
|-------------|------|------|
|
|
571
|
+
| `list(**params)` | GET | `/project/lead-hunter/lead/list` (filters as query params) |
|
|
572
|
+
|
|
573
|
+
Examples:
|
|
574
|
+
|
|
575
|
+
```ruby
|
|
576
|
+
Roistat.client.lead_hunter.list
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Email tracking — `client.emailtracking`
|
|
580
|
+
|
|
581
|
+
Official docs: [email tracking API](https://help-ru.roistat.com/API/methods/emailtracking/).
|
|
582
|
+
|
|
583
|
+
| Ruby method | HTTP | Path |
|
|
584
|
+
|-------------|------|------|
|
|
585
|
+
| `list(**body)` | POST | `/project/emailtracking/email/list` |
|
|
586
|
+
| `attachment(email_id:, attachment_id:)` | GET | `/project/emailtracking/email/{email_id}/attachment/{attachment_id}` (binary) |
|
|
587
|
+
|
|
588
|
+
Examples:
|
|
589
|
+
|
|
590
|
+
```ruby
|
|
591
|
+
Roistat.client.emailtracking.list(limit: 10)
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### SMS — `client.sms`
|
|
595
|
+
|
|
596
|
+
| Ruby method | HTTP | Path |
|
|
597
|
+
|-------------|------|------|
|
|
598
|
+
| `set_report_enabled(enabled:)` | POST | `/project/set-sms-report-enabled` (`enabled`: `"0"` or `"1"`) |
|
|
599
|
+
|
|
600
|
+
Examples:
|
|
601
|
+
|
|
602
|
+
```ruby
|
|
603
|
+
Roistat.client.sms.set_report_enabled(enabled: true)
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Mediaplan — `client.mediaplan`
|
|
607
|
+
|
|
608
|
+
Official docs: [mediaplan API](https://help-ru.roistat.com/API/methods/mediaplan/).
|
|
609
|
+
|
|
610
|
+
| Ruby method | HTTP | Path |
|
|
611
|
+
|-------------|------|------|
|
|
612
|
+
| `target_list(**body)` | POST | `/project/mediaplan/target/list` |
|
|
613
|
+
| `target_create(**body)` | POST | `/project/mediaplan/target/create` |
|
|
614
|
+
| `target_update(**body)` | POST | `/project/mediaplan/target/update` |
|
|
615
|
+
| `target_delete(id:)` | POST | `/project/mediaplan/target/delete` |
|
|
616
|
+
|
|
617
|
+
Examples:
|
|
618
|
+
|
|
619
|
+
```ruby
|
|
620
|
+
Roistat.client.mediaplan.target_list(
|
|
621
|
+
period: {from: "2026-07-01T00:00:00+0300", to: "2026-07-31T23:59:59+0300"}
|
|
622
|
+
)
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### Speech analytics — `client.speech`
|
|
626
|
+
|
|
627
|
+
**RU help only.** Official docs: [speech analytics API](https://help-ru.roistat.com/API/methods/speech/).
|
|
628
|
+
|
|
629
|
+
| Ruby method | HTTP | Path |
|
|
630
|
+
|-------------|------|------|
|
|
631
|
+
| `call_list(**body)` | POST | `/project/speech/call/list` |
|
|
632
|
+
| `call_list_export_excel(**body)` | POST | `/project/speech/call/list/export/excel` (binary) |
|
|
633
|
+
| `call_add(**body)` | POST | `/project/speech/call/add` |
|
|
634
|
+
| `call_comment_update(**body)` | POST | `/project/speech/call/comment/update` |
|
|
635
|
+
| `call_operator_update(**body)` | POST | `/project/speech/call/operator/update` |
|
|
636
|
+
| `call_transcription_list(**body)` | POST | `/project/speech/call/transcription/list` |
|
|
637
|
+
| `dictionary_list(**body)` | POST | `/project/speech/dictionary/list` |
|
|
638
|
+
| `dictionary_custom_create(**body)` | POST | `/project/speech/dictionary/custom/create` |
|
|
639
|
+
| `dictionary_custom_update(**body)` | POST | `/project/speech/dictionary/custom/update` |
|
|
640
|
+
| `dictionary_custom_delete(**body)` | POST | `/project/speech/dictionary/custom/delete` |
|
|
641
|
+
| `dictionary_custom_phrase_list(**body)` | POST | `/project/speech/dictionary/custom/phrase/list` |
|
|
642
|
+
| `settings_list(**body)` | POST | `/project/speech/settings/list` |
|
|
643
|
+
| `settings_update(**body)` | POST | `/project/speech/settings/update` |
|
|
644
|
+
|
|
645
|
+
Examples:
|
|
646
|
+
|
|
647
|
+
```ruby
|
|
648
|
+
Roistat.client.speech.dictionary_list
|
|
649
|
+
Roistat.client.speech.call_list
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
### Cloud PBX (VPBX) — `client.vpbx`
|
|
653
|
+
|
|
654
|
+
**RU help only.** Official docs: [VPBX API](https://help-ru.roistat.com/API/methods/vpbx/).
|
|
655
|
+
|
|
656
|
+
| Ruby method | HTTP | Path |
|
|
657
|
+
|-------------|------|------|
|
|
658
|
+
| `call_list(**body)` | POST | `/project/vpbx/call/list` |
|
|
659
|
+
| `operator_list(**body)` | POST | `/project/vpbx/operator/list` |
|
|
660
|
+
| `operator_create(**body)` | POST | `/project/vpbx/operator/create` |
|
|
661
|
+
| `operator_update(**body)` | POST | `/project/vpbx/operator/update` |
|
|
662
|
+
| `operator_deactivate(**body)` | POST | `/project/vpbx/operator/deactivate` |
|
|
663
|
+
| `operator_group_list(**body)` | POST | `/project/vpbx/operator/group/list` |
|
|
664
|
+
| `operator_group_create(**body)` | POST | `/project/vpbx/operator/group/create` |
|
|
665
|
+
| `operator_group_update(**body)` | POST | `/project/vpbx/operator/group/update` |
|
|
666
|
+
| `phone_list(**params)` | GET | `/project/vpbx/phone/list` |
|
|
667
|
+
| `phone_create(**body)` | POST | `/project/vpbx/phone/create` |
|
|
668
|
+
| `phone_update(**body)` | POST | `/project/vpbx/phone/update` |
|
|
669
|
+
| `phone_delete(**body)` | POST | `/project/vpbx/phone/delete` |
|
|
670
|
+
| `script_list(**params)` | GET | `/project/vpbx/script/list` |
|
|
671
|
+
| `script_create(**body)` | POST | `/project/vpbx/script/create` |
|
|
672
|
+
| `script_update(**body)` | POST | `/project/vpbx/script/update` |
|
|
673
|
+
| `script_delete(**body)` | POST | `/project/vpbx/script/delete` |
|
|
674
|
+
| `report_data(**body)` | POST | `/project/vpbx/report/data` |
|
|
675
|
+
| `settings_update(**body)` | POST | `/project/vpbx/settings/update` |
|
|
676
|
+
| `settings_file_audio_upload(file:, **fields)` | POST | `/project/vpbx/settings/file/audio/upload` (multipart) |
|
|
677
|
+
|
|
678
|
+
`settings_file_audio_upload` sends `multipart/form-data` via `Client#post_multipart`. Pass an IO or open file as `file:`; other keyword args become form fields.
|
|
679
|
+
|
|
680
|
+
Examples:
|
|
681
|
+
|
|
682
|
+
```ruby
|
|
683
|
+
Roistat.client.vpbx.phone_list
|
|
684
|
+
Roistat.client.vpbx.script_list
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
## Responses
|
|
688
|
+
|
|
689
|
+
### JSON
|
|
690
|
+
|
|
691
|
+
Successful JSON responses return the parsed body (usually a Hash with string keys).
|
|
692
|
+
|
|
693
|
+
### Binary
|
|
694
|
+
|
|
695
|
+
With `parse: :binary` (billing Excel export, calltracking XLS export, call audio, email attachments, speech call export):
|
|
696
|
+
|
|
697
|
+
| Body size | Return type |
|
|
698
|
+
|-----------|-------------|
|
|
699
|
+
| ≤ `binary_tempfile_threshold` (default 1 MiB) | `String` |
|
|
700
|
+
| \> threshold | `Tempfile` (caller should close/unlink) |
|
|
701
|
+
|
|
702
|
+
## Errors
|
|
703
|
+
|
|
704
|
+
Roistat API errors with `"status": "error"` map to typed exceptions:
|
|
705
|
+
|
|
706
|
+
| Roistat `error` code | Exception |
|
|
707
|
+
|----------------------|-----------|
|
|
708
|
+
| `authentication_failed` | `Roistat::AuthenticationError` |
|
|
709
|
+
| `authorization_failed` | `Roistat::AuthorizationError` |
|
|
710
|
+
| `access_denied` | `Roistat::AccessDeniedError` |
|
|
711
|
+
| `request_limit_error` | `Roistat::RateLimitError` |
|
|
712
|
+
| other / unknown | `Roistat::Error` |
|
|
713
|
+
|
|
714
|
+
Invalid local config raises `Roistat::ConfigurationError`.
|
|
715
|
+
|
|
716
|
+
Error instances may expose:
|
|
717
|
+
|
|
718
|
+
- `code` — Roistat error code
|
|
719
|
+
- `http_status` — HTTP status
|
|
720
|
+
- `response_body` — parsed body when available
|
|
721
|
+
|
|
722
|
+
## Development
|
|
723
|
+
|
|
724
|
+
```bash
|
|
725
|
+
bin/setup
|
|
726
|
+
bundle exec rake # RSpec + RuboCop
|
|
727
|
+
# or
|
|
728
|
+
mise test
|
|
729
|
+
mise lint
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
Install Lefthook once for pre-commit hooks:
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
bundle exec lefthook install
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
Interactive console:
|
|
739
|
+
|
|
740
|
+
```bash
|
|
741
|
+
bin/console
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
Release:
|
|
745
|
+
|
|
746
|
+
```bash
|
|
747
|
+
mise release
|
|
748
|
+
# or: bundle exec rake release
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
## Contributing
|
|
752
|
+
|
|
753
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/alec-c4/roistat.
|
|
754
|
+
|
|
755
|
+
## License
|
|
756
|
+
|
|
757
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|