An open API service indexing awesome lists of open source software.

https://github.com/rameerez/umami-ruby

⚪️ Ruby wrapper for the Umami analytics API
https://github.com/rameerez/umami-ruby

analytics google-analytics ruby ruby-on-rails umami umami-analytics web-analytics web-development

Last synced: 4 months ago
JSON representation

⚪️ Ruby wrapper for the Umami analytics API

Awesome Lists containing this project

README

          

# 📊 `umami-ruby` – Ruby client for the Umami Analytics API

[![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)

> [!TIP]
> **🚀 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)!

`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.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'umami-ruby'
```

And then execute:

```
$ bundle install
```

Or install it yourself as:

```
$ gem install umami-ruby
```

## Documentation

Full API documentation is available [online](https://rameerez.github.io/umami-ruby/) or can be generated using YARD:

```bash
yard doc
yard server
```

## Configuration

You can put this config in a handy location within your Rails project, like `config/initializers/umami.rb`

### For Umami Cloud

```ruby
Umami.configure do |config|
config.access_token = "your_api_key"
# No need to specify uri_base - automatically uses https://api.umami.is
end
```

### For Self-Hosted Umami Instances

```ruby
# With an access token
Umami.configure do |config|
config.uri_base = "https://your-umami-instance.com"
config.access_token = "your_access_token"
end

# Or with username and password
Umami.configure do |config|
config.uri_base = "https://your-umami-instance.com"
config.credentials = {
username: "your_username",
password: "your_password"
}
end
```

### Configuration Options

| Option | Description | Default |
|--------|-------------|---------|
| `access_token` | API key for Umami Cloud or access token for self-hosted | `nil` |
| `uri_base` | Base URL for self-hosted instances | Auto-detected |
| `credentials` | Hash with `:username` and `:password` for self-hosted | `nil` |
| `request_timeout` | Request timeout in seconds | `120` |

```ruby
# Example with custom timeout
Umami.configure do |config|
config.access_token = "your_api_key"
config.request_timeout = 60 # 60 seconds
end
```

## Usage

### Basic Usage

```ruby
client = Umami::Client.new

# Get current user info
me = client.me

# Get all websites
websites = client.websites

# Get a specific website
website = client.website("website_id")

# Verify token
token_info = client.verify_token
```

### Website Statistics

```ruby
# Get website stats for a time range (timestamps in milliseconds)
stats = client.website_stats("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})

# Get active visitors (last 5 minutes)
active = client.website_active_visitors("website_id")

# Get pageviews with time grouping
pageviews = client.website_pageviews("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
unit: "day",
timezone: "America/Los_Angeles"
})

# Get metrics by type
metrics = client.website_metrics("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
type: "browser" # or: path, referrer, os, device, country, etc.
})

# Get realtime stats (last 30 minutes)
realtime = client.realtime("website_id")
```

### Sending Events

Send custom events to Umami for tracking. This is useful for server-side event tracking.

```ruby
client = Umami::Client.new

# Send a basic event
client.send_event({
website: "your-website-id",
url: "/checkout",
hostname: "example.com",
name: "purchase_completed"
})

# Send an event with custom data
client.send_event({
website: "your-website-id",
url: "/checkout",
hostname: "example.com",
name: "purchase_completed",
language: "en-US",
screen: "1920x1080",
title: "Checkout - Example Store",
data: {
order_id: "12345",
total: 99.99,
currency: "USD"
}
})

# Send with a custom User-Agent (optional)
client.send_event(payload, user_agent: "MyApp/1.0")
```

**Important notes about `send_event`:**
- No authentication token is sent (not required by the API)
- A `User-Agent` header is automatically included (required by Umami)
- For Umami Cloud, requests go to `https://cloud.umami.is/api/send` (different from other API calls)
- For self-hosted, requests go to your configured `uri_base`

### Sessions

```ruby
# Get sessions within a time range
sessions = client.website_sessions("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
page: 1,
pageSize: 20
})

# Get session statistics
stats = client.website_sessions_stats("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})

# Get individual session details
session = client.website_session("website_id", "session_id")

# Get session activity
activity = client.website_session_activity("website_id", "session_id", {
startAt: 1656679719687,
endAt: 1656766119687
})
```

### Events Data

```ruby
# Get paginated event list with search
events = client.website_events_list("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
search: "click",
page: 1,
pageSize: 20
})

# Get event data aggregations
event_data = client.website_event_data_events("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})

# Get event statistics
stats = client.website_event_data_stats("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})
```

### Reports

```ruby
# List reports (optionally filter by website and/or type)
all_reports = client.reports
website_reports = client.reports(websiteId: "website_id")
funnel_reports = client.reports(websiteId: "website_id", type: "funnel")

# Create a report
report = client.create_report({
websiteId: "website_id",
type: "funnel",
name: "Checkout Funnel",
parameters: {
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-01-31T23:59:59Z"
}
})

# Run specialized reports
funnel = client.report_funnel({
websiteId: "website_id",
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-01-31T23:59:59Z",
steps: [
{ type: "path", value: "/" },
{ type: "path", value: "/checkout" },
{ type: "path", value: "/thank-you" }
],
window: 7
})

retention = client.report_retention({
websiteId: "website_id",
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-01-31T23:59:59Z",
timezone: "America/Los_Angeles"
})

# Available report types: attribution, breakdown, funnel, goal, journey, retention, revenue, utm
```

**Report types:**
| Type | Description |
|------|-------------|
| `attribution` | Marketing channel attribution analysis |
| `breakdown` | Multi-dimensional data segmentation |
| `funnel` | Conversion funnel tracking |
| `goal` | Goal performance metrics |
| `journey` | User navigation path analysis |
| `retention` | Return visitor analysis |
| `revenue` | Revenue tracking and analysis |
| `utm` | UTM campaign parameter breakdown |

### User & Team Management

```ruby
# Get current user info
me = client.me
my_teams = client.my_teams(page: 1, pageSize: 10)
my_websites = client.my_websites(includeTeams: true)

# Team management
teams = client.teams
team = client.team("team_id")
client.create_team("My Team")
client.add_team_user("team_id", "user_id", "team-member")

# User management (admin only, self-hosted)
users = client.admin_users
client.create_user("username", "password", "user")
```

### Website Management

```ruby
# Create a website
website = client.create_website({
name: "My Website",
domain: "example.com",
teamId: "optional-team-id"
})

# Update a website
client.update_website("website_id", {
name: "Updated Name",
shareId: "public-share-id"
})

# Reset website data
client.reset_website("website_id")

# Delete a website
client.delete_website("website_id")
```

## Available Methods

### Authentication
- `verify_token` - Verify the current authentication token

### Me (Current User)
- `me` - Get current user information
- `my_teams(params)` - Get user's teams (supports pagination)
- `my_websites(params)` - Get user's websites

### Admin (Self-hosted only)
- `admin_users(params)` - List all users
- `admin_websites(params)` - List all websites
- `admin_teams(params)` - List all teams

### Users
- `create_user(username, password, role, id:)` - Create a user
- `user(user_id)` - Get user by ID
- `update_user(user_id, params)` - Update user
- `delete_user(user_id)` - Delete user
- `user_websites(user_id, params)` - Get user's websites
- `user_teams(user_id, params)` - Get user's teams

### Teams
- `teams(params)` - List all teams
- `create_team(name)` - Create a team
- `join_team(access_code)` - Join a team
- `team(team_id)` - Get team by ID
- `update_team(team_id, params)` - Update team
- `delete_team(team_id)` - Delete team
- `team_users(team_id, params)` - List team members
- `add_team_user(team_id, user_id, role)` - Add user to team
- `team_user(team_id, user_id)` - Get team member
- `update_team_user(team_id, user_id, role)` - Update member role
- `delete_team_user(team_id, user_id)` - Remove user from team
- `team_websites(team_id, params)` - List team websites

### Websites
- `websites(params)` - List all websites
- `create_website(params)` - Create a website
- `website(website_id)` - Get website by ID
- `update_website(website_id, params)` - Update website
- `delete_website(website_id)` - Delete website
- `reset_website(website_id)` - Reset website data

### Website Statistics
- `website_stats(website_id, params)` - Get statistics
- `website_active_visitors(website_id)` - Get active visitors
- `website_pageviews(website_id, params)` - Get pageviews
- `website_events(website_id, params)` - Get events (time-series)
- `website_events_series(website_id, params)` - Get events series
- `website_metrics(website_id, params)` - Get metrics
- `website_metrics_expanded(website_id, params)` - Get expanded metrics

### Sessions
- `website_sessions(website_id, params)` - List sessions
- `website_sessions_stats(website_id, params)` - Get session stats
- `website_sessions_weekly(website_id, params)` - Get weekly breakdown
- `website_session(website_id, session_id)` - Get session details
- `website_session_activity(website_id, session_id, params)` - Get activity
- `website_session_properties(website_id, session_id)` - Get properties
- `website_session_data_properties(website_id, params)` - Get data properties
- `website_session_data_values(website_id, params)` - Get data values

### Events
- `website_events_list(website_id, params)` - List events (paginated)
- `website_event_data(website_id, event_id)` - Get event data
- `website_event_data_events(website_id, params)` - Get event aggregations
- `website_event_data_fields(website_id, params)` - Get event fields
- `website_event_data_properties(website_id, params)` - Get event properties
- `website_event_data_values(website_id, params)` - Get event values
- `website_event_data_stats(website_id, params)` - Get event statistics

### Realtime
- `realtime(website_id)` - Get realtime stats (last 30 minutes)

### Links
- `links(params)` - List all links
- `link(link_id)` - Get link by ID
- `update_link(link_id, params)` - Update link
- `delete_link(link_id)` - Delete link

### Pixels
- `pixels(params)` - List all pixels
- `pixel(pixel_id)` - Get pixel by ID
- `update_pixel(pixel_id, params)` - Update pixel
- `delete_pixel(pixel_id)` - Delete pixel

### Reports
- `reports(params)` - List all reports (filter by `websiteId`, `type`)
- `create_report(params)` - Create a report
- `report(report_id)` - Get report by ID
- `update_report(report_id, params)` - Update report
- `delete_report(report_id)` - Delete report
- `report_attribution(params)` - Run attribution report
- `report_breakdown(params)` - Run breakdown report
- `report_funnel(params)` - Run funnel report
- `report_goals(params)` - Run goals report
- `report_journey(params)` - Run journey report
- `report_retention(params)` - Run retention report
- `report_revenue(params)` - Run revenue report
- `report_utm(params)` - Run UTM report

### Sending Events
- `send_event(payload, user_agent:)` - Send tracking event

## Error Handling

The gem defines several custom error classes:

```ruby
begin
client.website("non-existent-id")
rescue Umami::NotFoundError => e
puts "Website not found: #{e.message}"
rescue Umami::ClientError => e
puts "Client error: #{e.message}"
rescue Umami::ServerError => e
puts "Server error: #{e.message}"
rescue Umami::AuthenticationError => e
puts "Authentication failed: #{e.message}"
rescue Umami::ConfigurationError => e
puts "Configuration error: #{e.message}"
rescue Umami::APIError => e
puts "API error: #{e.message}"
end
```

**Error class hierarchy:**
- `Umami::Error` - Base error class
- `Umami::ConfigurationError` - Configuration issues
- `Umami::AuthenticationError` - Authentication failures
- `Umami::APIError` - API request failures
- `Umami::NotFoundError` - Resource not found (404)
- `Umami::ClientError` - Client errors (4xx)
- `Umami::ServerError` - Server errors (5xx)

## Logging

The gem uses a logger that can be configured:

```ruby
# Set log level
Umami.logger.level = Logger::DEBUG

# Use a custom logger
Umami.logger = Rails.logger
```

## Development

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.

To install this gem onto your local machine, run `bundle exec rake install`.

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/rameerez/umami-ruby. Our code of conduct is: just be nice and make your mom proud of what you do and post online.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).