umami-ruby 0.1.2 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c1694e34f1d6aa0a0c3a29e1a2974102acf06e6080073b24821c067e04017ac
4
- data.tar.gz: 6e8d775b7b7e9d68302f61ff17efb97898eef143520be9cc0c9f46f0cc40da44
3
+ metadata.gz: 8123faece9209e2ead6415c0e396a32853aa69ade5a11af2481c311a6e333e81
4
+ data.tar.gz: ad58c5c87d2e27e92e90b7210a7443e589e4879ab9f9f247648b8c43f6af4a99
5
5
  SHA512:
6
- metadata.gz: 835bf75155867e6fb31d27eace33760ab4969b267543af9df66db6c7d1c8bbab25f2f25ccf487748bb083534d3ceda1d0287dd7bad5b06db85d054d37e925fa7
7
- data.tar.gz: cf11c314d097bd25bbfa5c92f9a34c8a5628df745a2a9b569eba1fd5fb7690eddeae0025d445010065b7026aa7681cb4228fb034981e939b1ed7e0eb714ba163
6
+ metadata.gz: 5cf0256f92097a0b2374205d727f1deb7f20d3dce31ade6783001023cd7512e76b3b4f65c41dc33166a340d4ae2e1dab60fef3f2043860fec9e3a98c1d1c7d3b
7
+ data.tar.gz: 6f9905fc18ac2200c003d620d5f0f2caac972436b43c9b2756fee76547b7a92ced1358662d5a25300c1d41c3a42a2e847c4bca58d5eed727d57fc90eca1de236
data/.env.test ADDED
@@ -0,0 +1,9 @@
1
+ # Test environment configuration (safe to commit)
2
+ # Real credentials should go in .env.test.local (gitignored)
3
+
4
+ UMAMI_ACCESS_TOKEN=test_token_placeholder
5
+ UMAMI_URI_BASE=https://api.umami.is
6
+
7
+ # Test website IDs (using placeholder UUIDs)
8
+ UMAMI_TEST_WEBSITE_ID=00000000-0000-0000-0000-000000000001
9
+ UMAMI_TEST_WEBSITE_ID_ALT=00000000-0000-0000-0000-000000000002
data/.simplecov ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SimpleCov configuration file (auto-loaded before test suite)
4
+ # This keeps test_helper.rb clean and follows best practices
5
+
6
+ SimpleCov.start do
7
+ # Use SimpleFormatter for terminal-only output (no HTML generation)
8
+ formatter SimpleCov::Formatter::SimpleFormatter
9
+
10
+ # Track coverage for the lib directory (gem source code)
11
+ add_filter "/test/"
12
+
13
+ # Track Ruby files in lib directory
14
+ track_files "lib/**/*.rb"
15
+
16
+ # Enable branch coverage for more detailed metrics
17
+ enable_coverage :branch
18
+
19
+ # Set minimum coverage threshold to prevent coverage regression
20
+ # Current coverage: Line ~73%, Branch ~73%
21
+ minimum_coverage line: 70, branch: 65
22
+
23
+ # Disambiguate parallel test runs
24
+ command_name "Job #{ENV['TEST_ENV_NUMBER']}" if ENV['TEST_ENV_NUMBER']
25
+ end
26
+
27
+ # Print coverage summary to terminal after tests complete
28
+ SimpleCov.at_exit do
29
+ SimpleCov.result.format!
30
+ puts "\n" + "=" * 60
31
+ puts "COVERAGE SUMMARY"
32
+ puts "=" * 60
33
+ puts "Line Coverage: #{SimpleCov.result.covered_percent.round(2)}%"
34
+ puts "Branch Coverage: #{SimpleCov.result.coverage_statistics[:branch]&.percent&.round(2) || 'N/A'}%"
35
+ puts "=" * 60
36
+ end
data/CHANGELOG.md CHANGED
@@ -1,4 +1,86 @@
1
- ## [Unreleased]
1
+ ## [0.2.0] - 2026-02-02
2
+
3
+ ### Added
4
+
5
+ **New Endpoint Categories:**
6
+ - **Me endpoints**: `me`, `my_teams`, `my_websites` - Get current user info and resources
7
+ - **Admin endpoints**: `admin_users`, `admin_websites`, `admin_teams` - Admin-only endpoints for self-hosted
8
+ - **Sessions endpoints** (8 new methods):
9
+ - `website_sessions` - Get sessions within a time range
10
+ - `website_sessions_stats` - Get summarized session statistics
11
+ - `website_sessions_weekly` - Get session counts by hour of weekday
12
+ - `website_session` - Get individual session details
13
+ - `website_session_activity` - Get session activity
14
+ - `website_session_properties` - Get session properties
15
+ - `website_session_data_properties` - Get session data property counts
16
+ - `website_session_data_values` - Get session data value counts
17
+ - **Realtime endpoint**: `realtime` - Get live stats for last 30 minutes
18
+ - **Links endpoints**: `links`, `link`, `update_link`, `delete_link`
19
+ - **Pixels endpoints**: `pixels`, `pixel`, `update_pixel`, `delete_pixel`
20
+ - **Reports endpoints** (13 new methods):
21
+ - CRUD: `reports`, `create_report`, `report`, `update_report`, `delete_report`
22
+ - Specialized: `report_attribution`, `report_breakdown`, `report_funnel`, `report_goals`, `report_journey`, `report_retention`, `report_revenue`, `report_utm`
23
+ - **Website stats endpoints**:
24
+ - `website_events_series` - Get events series with time bucketing
25
+ - `website_metrics_expanded` - Get detailed metrics with engagement data
26
+ - **Events endpoints**:
27
+ - `website_events_list` - Get paginated event details
28
+ - `website_event_data` - Get data for individual event
29
+ - `website_event_data_events` - Get event data names and counts
30
+ - `website_event_data_fields` - Get event data fields
31
+ - `website_event_data_properties` - Get event properties
32
+ - `website_event_data_values` - Get event data values
33
+ - `website_event_data_stats` - Get aggregated event stats
34
+
35
+ **Configuration:**
36
+ - `request_timeout=` setter - users can now customize timeout via `Umami.configure` block
37
+ - New `UMAMI_CLOUD_SEND_URL` constant for the Cloud send endpoint URL
38
+ - Optional `user_agent:` parameter to `send_event` method for custom User-Agent strings
39
+
40
+ **Documentation:**
41
+ - Configuration Options table in README with all available options and defaults
42
+ - Report Types reference table in README
43
+
44
+ **Test Suite:**
45
+ - Comprehensive Minitest test suite with 152 tests
46
+ - VCR cassettes for all read API endpoints (33 cassettes)
47
+ - CI workflow for Ruby 3.3, 3.4, 4.0
48
+ - ~72% line and branch coverage
49
+
50
+ ### Changed
51
+
52
+ - Updated `website_metrics` documentation with all current metric types
53
+ - Updated user role documentation to include `view-only` option
54
+ - Updated team role documentation with `team-manager`, `team-member`, `team-view-only` roles
55
+ - Updated `send_event` documentation with `tag` and `id` parameters
56
+ - Improved filter parameter documentation across all endpoints
57
+ - Added optional `id` parameter to `create_user` for UUID control
58
+ - Report endpoints use `startDate`/`endDate` (ISO 8601) instead of `startAt`/`endAt` (timestamps)
59
+ - Added `window` parameter to `report_funnel` for days between steps
60
+ - Added `timezone` parameter (required) to `report_retention`
61
+ - Updated `unit` parameter to include `minute` option
62
+ - Made `timezone` required for `website_sessions_weekly`
63
+ - Made `startAt`/`endAt` required for `website_session_activity`
64
+
65
+ ### Fixed
66
+
67
+ - **Critical**: Fixed `send_event` to use correct Umami Cloud URL (`https://cloud.umami.is/api/send`)
68
+ - **Critical**: Added mandatory `User-Agent` header to `send_event` requests (fixes [#2](https://github.com/rameerez/umami-ruby/issues/2))
69
+ - Fixed `send_event` to not send unnecessary `Authorization` header
70
+ - Fixed event data endpoint paths from `/api/event-data/...` to `/api/websites/:websiteId/event-data/...`
71
+ - Fixed `verify_token` to use POST method instead of GET
72
+ - Fixed `website_event_data_stats` return type documentation
73
+
74
+ ### Deprecated
75
+
76
+ - `event_data_events` - Use `website_event_data_events` instead
77
+ - `event_data_fields` - Use `website_event_data_fields` instead
78
+ - `event_data_stats` - Use `website_event_data_stats` instead
79
+ - `users` - Use `admin_users` instead
80
+
81
+ ## [0.1.3] - 2025-02-19
82
+
83
+ - Bug fixes and improvements
2
84
 
3
85
  ## [0.1.0] - 2024-07-22
4
86
 
data/CLAUDE.md ADDED
@@ -0,0 +1,45 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ `umami-ruby` is a Ruby wrapper for the Umami Analytics API. It works with both Umami Cloud and self-hosted instances.
8
+
9
+ ## Key Files
10
+
11
+ - `lib/umami/client.rb` - Main API client with all endpoint methods
12
+ - `lib/umami/configuration.rb` - Configuration management
13
+ - `lib/umami/errors.rb` - Custom error classes
14
+ - `test/` - Minitest test suite with VCR cassettes
15
+
16
+ ## Development Commands
17
+
18
+ ```bash
19
+ # Install dependencies
20
+ bundle install
21
+
22
+ # Run tests
23
+ bundle exec rake test
24
+
25
+ # Run tests with coverage
26
+ bundle exec rake test # SimpleCov runs automatically
27
+
28
+ # Generate documentation
29
+ yard doc
30
+ yard server
31
+ ```
32
+
33
+ ## Testing Guidelines
34
+
35
+ - All tests use VCR cassettes for HTTP interactions
36
+ - Cassettes are in `test/cassettes/`
37
+ - Use `VCR_RECORD_MODE=new_episodes bundle exec rake test` to record new cassettes
38
+ - Anonymize all sensitive data in cassettes before committing
39
+
40
+ ## Code Style
41
+
42
+ - Follow standard Ruby conventions
43
+ - Use YARD documentation for all public methods
44
+ - Keep methods focused and single-purpose
45
+ - Error handling uses custom error classes inheriting from `Umami::Error`
data/README.md CHANGED
@@ -1,15 +1,18 @@
1
- # Umami Ruby
1
+ # 📊 `umami-ruby` – Ruby client for the Umami Analytics API
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/umami-ruby.svg)](https://badge.fury.io/rb/umami-ruby)
3
+ [![Gem Version](https://badge.fury.io/rb/umami-ruby.svg)](https://badge.fury.io/rb/umami-ruby) [![Build Status](https://github.com/rameerez/umami-ruby/workflows/Tests/badge.svg)](https://github.com/rameerez/umami-ruby/actions)
4
4
 
5
- A Ruby wrapper for the Umami analytics API.
5
+ > [!TIP]
6
+ > **🚀 Ship your next Rails app 10x faster!** I've built **[RailsFast](https://railsfast.com/?ref=umami-ruby)**, a production-ready Rails boilerplate template that comes with everything you need to launch a software business in days, not weeks. Go [check it out](https://railsfast.com/?ref=umami-ruby)!
7
+
8
+ `umami-ruby` is a comprehensive Ruby wrapper for the [Umami Analytics API](https://umami.is/docs/api). Works with both Umami Cloud and self-hosted instances.
6
9
 
7
10
  ## Installation
8
11
 
9
12
  Add this line to your application's Gemfile:
10
13
 
11
14
  ```ruby
12
- gem 'umami-ruby', require: 'umami'
15
+ gem 'umami-ruby'
13
16
  ```
14
17
 
15
18
  And then execute:
@@ -33,79 +36,447 @@ yard doc
33
36
  yard server
34
37
  ```
35
38
 
36
- ## Usage
37
-
38
- ### Configuration
39
+ ## Configuration
39
40
 
40
41
  You can put this config in a handy location within your Rails project, like `config/initializers/umami.rb`
41
42
 
42
- #### For self-hosted Umami instances:
43
+ ### For Umami Cloud
43
44
 
44
45
  ```ruby
45
- # With username and password
46
46
  Umami.configure do |config|
47
- config.uri_base = "https://your-umami-instance.com"
48
- config.credentials = {
49
- username: "your_username",
50
- password: "your_password"
51
- }
47
+ config.access_token = "your_api_key"
48
+ # No need to specify uri_base - automatically uses https://api.umami.is
52
49
  end
50
+ ```
51
+
52
+ ### For Self-Hosted Umami Instances
53
53
 
54
- # Or with an access token
54
+ ```ruby
55
+ # With an access token
55
56
  Umami.configure do |config|
56
57
  config.uri_base = "https://your-umami-instance.com"
57
58
  config.access_token = "your_access_token"
58
59
  end
60
+
61
+ # Or with username and password
62
+ Umami.configure do |config|
63
+ config.uri_base = "https://your-umami-instance.com"
64
+ config.credentials = {
65
+ username: "your_username",
66
+ password: "your_password"
67
+ }
68
+ end
59
69
  ```
60
70
 
61
- #### For Umami Cloud:
71
+ ### Configuration Options
72
+
73
+ | Option | Description | Default |
74
+ |--------|-------------|---------|
75
+ | `access_token` | API key for Umami Cloud or access token for self-hosted | `nil` |
76
+ | `uri_base` | Base URL for self-hosted instances | Auto-detected |
77
+ | `credentials` | Hash with `:username` and `:password` for self-hosted | `nil` |
78
+ | `request_timeout` | Request timeout in seconds | `120` |
62
79
 
63
80
  ```ruby
81
+ # Example with custom timeout
64
82
  Umami.configure do |config|
65
83
  config.access_token = "your_api_key"
66
- # No need to specify uri_base for Umami Cloud
84
+ config.request_timeout = 60 # 60 seconds
67
85
  end
68
86
  ```
69
87
 
70
- ### Using the Client
88
+ ## Usage
71
89
 
72
- After configuration, you can use the client to interact with the Umami API:
90
+ ### Basic Usage
73
91
 
74
92
  ```ruby
75
93
  client = Umami::Client.new
76
94
 
95
+ # Get current user info
96
+ me = client.me
97
+
77
98
  # Get all websites
78
99
  websites = client.websites
79
100
 
80
101
  # Get a specific website
81
102
  website = client.website("website_id")
82
103
 
83
- # Get website stats
84
- stats = client.website_stats("website_id", { startAt: 1656679719687, endAt: 1656766119687 })
85
-
86
104
  # Verify token
87
105
  token_info = client.verify_token
88
106
  ```
89
107
 
108
+ ### Website Statistics
109
+
110
+ ```ruby
111
+ # Get website stats for a time range (timestamps in milliseconds)
112
+ stats = client.website_stats("website_id", {
113
+ startAt: 1656679719687,
114
+ endAt: 1656766119687
115
+ })
116
+
117
+ # Get active visitors (last 5 minutes)
118
+ active = client.website_active_visitors("website_id")
119
+
120
+ # Get pageviews with time grouping
121
+ pageviews = client.website_pageviews("website_id", {
122
+ startAt: 1656679719687,
123
+ endAt: 1656766119687,
124
+ unit: "day",
125
+ timezone: "America/Los_Angeles"
126
+ })
127
+
128
+ # Get metrics by type
129
+ metrics = client.website_metrics("website_id", {
130
+ startAt: 1656679719687,
131
+ endAt: 1656766119687,
132
+ type: "browser" # or: path, referrer, os, device, country, etc.
133
+ })
134
+
135
+ # Get realtime stats (last 30 minutes)
136
+ realtime = client.realtime("website_id")
137
+ ```
138
+
139
+ ### Sending Events
140
+
141
+ Send custom events to Umami for tracking. This is useful for server-side event tracking.
142
+
143
+ ```ruby
144
+ client = Umami::Client.new
145
+
146
+ # Send a basic event
147
+ client.send_event({
148
+ website: "your-website-id",
149
+ url: "/checkout",
150
+ hostname: "example.com",
151
+ name: "purchase_completed"
152
+ })
153
+
154
+ # Send an event with custom data
155
+ client.send_event({
156
+ website: "your-website-id",
157
+ url: "/checkout",
158
+ hostname: "example.com",
159
+ name: "purchase_completed",
160
+ language: "en-US",
161
+ screen: "1920x1080",
162
+ title: "Checkout - Example Store",
163
+ data: {
164
+ order_id: "12345",
165
+ total: 99.99,
166
+ currency: "USD"
167
+ }
168
+ })
169
+
170
+ # Send with a custom User-Agent (optional)
171
+ client.send_event(payload, user_agent: "MyApp/1.0")
172
+ ```
173
+
174
+ **Important notes about `send_event`:**
175
+ - No authentication token is sent (not required by the API)
176
+ - A `User-Agent` header is automatically included (required by Umami)
177
+ - For Umami Cloud, requests go to `https://cloud.umami.is/api/send` (different from other API calls)
178
+ - For self-hosted, requests go to your configured `uri_base`
179
+
180
+ ### Sessions
181
+
182
+ ```ruby
183
+ # Get sessions within a time range
184
+ sessions = client.website_sessions("website_id", {
185
+ startAt: 1656679719687,
186
+ endAt: 1656766119687,
187
+ page: 1,
188
+ pageSize: 20
189
+ })
190
+
191
+ # Get session statistics
192
+ stats = client.website_sessions_stats("website_id", {
193
+ startAt: 1656679719687,
194
+ endAt: 1656766119687
195
+ })
196
+
197
+ # Get individual session details
198
+ session = client.website_session("website_id", "session_id")
199
+
200
+ # Get session activity
201
+ activity = client.website_session_activity("website_id", "session_id", {
202
+ startAt: 1656679719687,
203
+ endAt: 1656766119687
204
+ })
205
+ ```
206
+
207
+ ### Events Data
208
+
209
+ ```ruby
210
+ # Get paginated event list with search
211
+ events = client.website_events_list("website_id", {
212
+ startAt: 1656679719687,
213
+ endAt: 1656766119687,
214
+ search: "click",
215
+ page: 1,
216
+ pageSize: 20
217
+ })
218
+
219
+ # Get event data aggregations
220
+ event_data = client.website_event_data_events("website_id", {
221
+ startAt: 1656679719687,
222
+ endAt: 1656766119687
223
+ })
224
+
225
+ # Get event statistics
226
+ stats = client.website_event_data_stats("website_id", {
227
+ startAt: 1656679719687,
228
+ endAt: 1656766119687
229
+ })
230
+ ```
231
+
232
+ ### Reports
233
+
234
+ ```ruby
235
+ # List reports (optionally filter by website and/or type)
236
+ all_reports = client.reports
237
+ website_reports = client.reports(websiteId: "website_id")
238
+ funnel_reports = client.reports(websiteId: "website_id", type: "funnel")
239
+
240
+ # Create a report
241
+ report = client.create_report({
242
+ websiteId: "website_id",
243
+ type: "funnel",
244
+ name: "Checkout Funnel",
245
+ parameters: {
246
+ startDate: "2024-01-01T00:00:00Z",
247
+ endDate: "2024-01-31T23:59:59Z"
248
+ }
249
+ })
250
+
251
+ # Run specialized reports
252
+ funnel = client.report_funnel({
253
+ websiteId: "website_id",
254
+ startDate: "2024-01-01T00:00:00Z",
255
+ endDate: "2024-01-31T23:59:59Z",
256
+ steps: [
257
+ { type: "path", value: "/" },
258
+ { type: "path", value: "/checkout" },
259
+ { type: "path", value: "/thank-you" }
260
+ ],
261
+ window: 7
262
+ })
263
+
264
+ retention = client.report_retention({
265
+ websiteId: "website_id",
266
+ startDate: "2024-01-01T00:00:00Z",
267
+ endDate: "2024-01-31T23:59:59Z",
268
+ timezone: "America/Los_Angeles"
269
+ })
270
+
271
+ # Available report types: attribution, breakdown, funnel, goal, journey, retention, revenue, utm
272
+ ```
273
+
274
+ **Report types:**
275
+ | Type | Description |
276
+ |------|-------------|
277
+ | `attribution` | Marketing channel attribution analysis |
278
+ | `breakdown` | Multi-dimensional data segmentation |
279
+ | `funnel` | Conversion funnel tracking |
280
+ | `goal` | Goal performance metrics |
281
+ | `journey` | User navigation path analysis |
282
+ | `retention` | Return visitor analysis |
283
+ | `revenue` | Revenue tracking and analysis |
284
+ | `utm` | UTM campaign parameter breakdown |
285
+
286
+ ### User & Team Management
287
+
288
+ ```ruby
289
+ # Get current user info
290
+ me = client.me
291
+ my_teams = client.my_teams(page: 1, pageSize: 10)
292
+ my_websites = client.my_websites(includeTeams: true)
293
+
294
+ # Team management
295
+ teams = client.teams
296
+ team = client.team("team_id")
297
+ client.create_team("My Team")
298
+ client.add_team_user("team_id", "user_id", "team-member")
299
+
300
+ # User management (admin only, self-hosted)
301
+ users = client.admin_users
302
+ client.create_user("username", "password", "user")
303
+ ```
304
+
305
+ ### Website Management
306
+
307
+ ```ruby
308
+ # Create a website
309
+ website = client.create_website({
310
+ name: "My Website",
311
+ domain: "example.com",
312
+ teamId: "optional-team-id"
313
+ })
314
+
315
+ # Update a website
316
+ client.update_website("website_id", {
317
+ name: "Updated Name",
318
+ shareId: "public-share-id"
319
+ })
320
+
321
+ # Reset website data
322
+ client.reset_website("website_id")
323
+
324
+ # Delete a website
325
+ client.delete_website("website_id")
326
+ ```
327
+
328
+ ## Available Methods
329
+
330
+ ### Authentication
331
+ - `verify_token` - Verify the current authentication token
332
+
333
+ ### Me (Current User)
334
+ - `me` - Get current user information
335
+ - `my_teams(params)` - Get user's teams (supports pagination)
336
+ - `my_websites(params)` - Get user's websites
337
+
338
+ ### Admin (Self-hosted only)
339
+ - `admin_users(params)` - List all users
340
+ - `admin_websites(params)` - List all websites
341
+ - `admin_teams(params)` - List all teams
342
+
343
+ ### Users
344
+ - `create_user(username, password, role, id:)` - Create a user
345
+ - `user(user_id)` - Get user by ID
346
+ - `update_user(user_id, params)` - Update user
347
+ - `delete_user(user_id)` - Delete user
348
+ - `user_websites(user_id, params)` - Get user's websites
349
+ - `user_teams(user_id, params)` - Get user's teams
350
+
351
+ ### Teams
352
+ - `teams(params)` - List all teams
353
+ - `create_team(name)` - Create a team
354
+ - `join_team(access_code)` - Join a team
355
+ - `team(team_id)` - Get team by ID
356
+ - `update_team(team_id, params)` - Update team
357
+ - `delete_team(team_id)` - Delete team
358
+ - `team_users(team_id, params)` - List team members
359
+ - `add_team_user(team_id, user_id, role)` - Add user to team
360
+ - `team_user(team_id, user_id)` - Get team member
361
+ - `update_team_user(team_id, user_id, role)` - Update member role
362
+ - `delete_team_user(team_id, user_id)` - Remove user from team
363
+ - `team_websites(team_id, params)` - List team websites
364
+
365
+ ### Websites
366
+ - `websites(params)` - List all websites
367
+ - `create_website(params)` - Create a website
368
+ - `website(website_id)` - Get website by ID
369
+ - `update_website(website_id, params)` - Update website
370
+ - `delete_website(website_id)` - Delete website
371
+ - `reset_website(website_id)` - Reset website data
372
+
373
+ ### Website Statistics
374
+ - `website_stats(website_id, params)` - Get statistics
375
+ - `website_active_visitors(website_id)` - Get active visitors
376
+ - `website_pageviews(website_id, params)` - Get pageviews
377
+ - `website_events(website_id, params)` - Get events (time-series)
378
+ - `website_events_series(website_id, params)` - Get events series
379
+ - `website_metrics(website_id, params)` - Get metrics
380
+ - `website_metrics_expanded(website_id, params)` - Get expanded metrics
381
+
382
+ ### Sessions
383
+ - `website_sessions(website_id, params)` - List sessions
384
+ - `website_sessions_stats(website_id, params)` - Get session stats
385
+ - `website_sessions_weekly(website_id, params)` - Get weekly breakdown
386
+ - `website_session(website_id, session_id)` - Get session details
387
+ - `website_session_activity(website_id, session_id, params)` - Get activity
388
+ - `website_session_properties(website_id, session_id)` - Get properties
389
+ - `website_session_data_properties(website_id, params)` - Get data properties
390
+ - `website_session_data_values(website_id, params)` - Get data values
391
+
392
+ ### Events
393
+ - `website_events_list(website_id, params)` - List events (paginated)
394
+ - `website_event_data(website_id, event_id)` - Get event data
395
+ - `website_event_data_events(website_id, params)` - Get event aggregations
396
+ - `website_event_data_fields(website_id, params)` - Get event fields
397
+ - `website_event_data_properties(website_id, params)` - Get event properties
398
+ - `website_event_data_values(website_id, params)` - Get event values
399
+ - `website_event_data_stats(website_id, params)` - Get event statistics
400
+
401
+ ### Realtime
402
+ - `realtime(website_id)` - Get realtime stats (last 30 minutes)
403
+
404
+ ### Links
405
+ - `links(params)` - List all links
406
+ - `link(link_id)` - Get link by ID
407
+ - `update_link(link_id, params)` - Update link
408
+ - `delete_link(link_id)` - Delete link
409
+
410
+ ### Pixels
411
+ - `pixels(params)` - List all pixels
412
+ - `pixel(pixel_id)` - Get pixel by ID
413
+ - `update_pixel(pixel_id, params)` - Update pixel
414
+ - `delete_pixel(pixel_id)` - Delete pixel
415
+
416
+ ### Reports
417
+ - `reports(params)` - List all reports (filter by `websiteId`, `type`)
418
+ - `create_report(params)` - Create a report
419
+ - `report(report_id)` - Get report by ID
420
+ - `update_report(report_id, params)` - Update report
421
+ - `delete_report(report_id)` - Delete report
422
+ - `report_attribution(params)` - Run attribution report
423
+ - `report_breakdown(params)` - Run breakdown report
424
+ - `report_funnel(params)` - Run funnel report
425
+ - `report_goals(params)` - Run goals report
426
+ - `report_journey(params)` - Run journey report
427
+ - `report_retention(params)` - Run retention report
428
+ - `report_revenue(params)` - Run revenue report
429
+ - `report_utm(params)` - Run UTM report
430
+
431
+ ### Sending Events
432
+ - `send_event(payload, user_agent:)` - Send tracking event
433
+
90
434
  ## Error Handling
91
435
 
92
436
  The gem defines several custom error classes:
93
437
 
94
- - `Umami::ConfigurationError`: Raised for configuration-related issues.
95
- - `Umami::AuthenticationError`: Raised for authentication-related issues.
96
- - `Umami::APIError`: Raised for API request failures.
438
+ ```ruby
439
+ begin
440
+ client.website("non-existent-id")
441
+ rescue Umami::NotFoundError => e
442
+ puts "Website not found: #{e.message}"
443
+ rescue Umami::ClientError => e
444
+ puts "Client error: #{e.message}"
445
+ rescue Umami::ServerError => e
446
+ puts "Server error: #{e.message}"
447
+ rescue Umami::AuthenticationError => e
448
+ puts "Authentication failed: #{e.message}"
449
+ rescue Umami::ConfigurationError => e
450
+ puts "Configuration error: #{e.message}"
451
+ rescue Umami::APIError => e
452
+ puts "API error: #{e.message}"
453
+ end
454
+ ```
455
+
456
+ **Error class hierarchy:**
457
+ - `Umami::Error` - Base error class
458
+ - `Umami::ConfigurationError` - Configuration issues
459
+ - `Umami::AuthenticationError` - Authentication failures
460
+ - `Umami::APIError` - API request failures
461
+ - `Umami::NotFoundError` - Resource not found (404)
462
+ - `Umami::ClientError` - Client errors (4xx)
463
+ - `Umami::ServerError` - Server errors (5xx)
97
464
 
98
465
  ## Logging
99
466
 
100
467
  The gem uses a logger that can be configured:
101
468
 
102
469
  ```ruby
470
+ # Set log level
103
471
  Umami.logger.level = Logger::DEBUG
472
+
473
+ # Use a custom logger
474
+ Umami.logger = Rails.logger
104
475
  ```
105
476
 
106
477
  ## Development
107
478
 
108
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
479
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
109
480
 
110
481
  To install this gem onto your local machine, run `bundle exec rake install`.
111
482
 
data/Rakefile CHANGED
@@ -1,4 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
- task default: %i[]
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ t.warning = false
11
+ end
12
+
13
+ task default: :test