Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: "bundler"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 30
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 30
4 changes: 2 additions & 2 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- '3.4'

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up Ruby
uses: ruby/setup-ruby@d697be2f83c6234b20877c3b5eac7a7f342f0d0c # v1.269.0
with:
Expand All @@ -31,7 +31,7 @@ jobs:
- name: Run tests
run: bundle exec rake
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: mixpanel/mixpanel-ruby
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Gemfile.lock
html
mixpanel-ruby*.gem
.bundle
coverage/
Readme.rdoc
158 changes: 158 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# mixpanel-ruby: The official Mixpanel Ruby library

mixpanel-ruby is a library for tracking events and sending Mixpanel profile
updates to Mixpanel from your Ruby applications.

## Installation

```
gem install mixpanel-ruby
```

## Getting Started

```ruby
require 'mixpanel-ruby'

tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)

# Track an event on behalf of user "User1"
tracker.track('User1', 'A Mixpanel Event')

# Send an update to User1's profile
tracker.people.set('User1', {
'$first_name' => 'David',
'$last_name' => 'Bowie',
'Best Album' => 'The Rise and Fall of Ziggy Stardust and the Spiders from Mars'
})
```

The primary class you will use to track events is `Mixpanel::Tracker`. An instance of
`Mixpanel::Tracker` is enough to send events directly to Mixpanel, and get you integrated
right away.

## Importing Events

> **⚠️ Breaking change in v3.1.0:** The `api_key` string argument to `Tracker#import` has been replaced by a credentials Hash supporting Service Account or Project Token authentication.
> More details here: https://developer.mixpanel.com/reference/import-events#authentication and https://developer.mixpanel.com/reference/service-accounts

Use `Mixpanel::Tracker#import` to import historical events. The import endpoint
requires authentication via HTTP Basic Auth using one of the following methods:

### Service Account (recommended)

```ruby
tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)

tracker.import(
{ service_account_username: 'sa@serviceaccount.mixpanel.com',
service_account_password: 'sa-secret',
project_id: '12345' },
'user_id', 'Event Name', { 'time' => 1310111365 }
)
```

### Project Token

The project token is sent as the HTTP Basic Auth username with an empty password.

```ruby
tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)

tracker.import(
{ project_token: YOUR_MIXPANEL_TOKEN },
'user_id', 'Event Name', { 'time' => 1310111365 }
)
```

## Additional Information

For more information please visit:

* [Our Ruby API Integration page](https://mixpanel.com/help/reference/ruby#introduction)
* [The usage demo](https://github.com/mixpanel/mixpanel-ruby/tree/master/demo)
* [The documentation](http://mixpanel.github.io/mixpanel-ruby/)

The official Mixpanel gem is built with simplicity and broad applicability in
mind, but there are also third party Ruby libraries that can work with the library
to provide useful features in common situations, and support different development
points of view.

In particular, for Rails apps, the following projects are currently actively maintained:

* [MetaEvents](https://github.com/swiftype/meta_events)
* [Mengpaneel](https://github.com/DouweM/mengpaneel)

## Changes

### 3.1.0
* Add service account and project token authentication for the `/import` endpoint
(breaking change: the first argument to `Tracker#import` has changed from an `api_key` string
to a credentials Hash — all other methods are unaffected)

### 3.0.0
* Implement feature flags provider

### 2.3.1
* Convert timestamps to milliseconds and update Ruby compatibility

### 2.3.0
* Clear submitted slices during `BufferedConsumer#flush`
* Groups analytics support
* Use millisecond precision for time properties

### 2.2.2
* Add Group Analytics support with `Mixpanel::Groups`

### 2.2.1
* Fix buffer clearing on partially successful writes in `BufferedConsumer`

### 2.2.0
* Add `Mixpanel::ErrorHandler` to simplify custom error handling
* Modify `Mixpanel::People#fix_property_dates` to handle `ActiveSupport::TimeWithZone`
* Increase open and ssl timeouts from 2s to 10s
* Fix doc inconsistency: always pass token on `Mixpanel::Tracker.new`

### 2.1.0
* Add `Mixpanel::Tracker#generate_tracking_url`, which generates [pixel tracking urls](https://mixpanel.com/docs/api-documentation/pixel-based-event-tracking)
* Rescue JSONErrors in the consumer and raise `Mixpanel::ServerError` in `Mixpanel::Consumer#send!`
* Make it clear how to import events with custom timestamp
* Update dependencies in gemspec

### 2.0.1
* Add deprecated version of `Mixpanel::BufferedConsumer#send`

### 2.0.0
* Raise Mixpanel server and connection errors in `Mixpanel::Consumer`
* All public methods in `Mixpanel::Event`, `Mixpanel::People`, and subsequently `Mixpanel::Tracker`
rescue Mixpanel errors and return false in the case of an error, return true otherwise
* Deprecate `Mixpanel::Consumer#send`, replace with `Mixpanel::Consumer#send!`
* Require Ruby version minimum of 2.0.0

### 1.4.0
* Allow unset to unset multiple properties

### 1.3.0
* Added `Consumer#request` method, demo with Faraday integration

### 1.2.0
* All objects with a `strftime` method will be formatted as dates in people updates

### 1.1.0
* The default consumer now sends requests (and expects responses) in verbose, JSON mode,
which may improve error reporting

### 1.0.2
* Allow ip and optional_params arguments to be accepted by all `Mixpanel::People` methods
(except `#destroy_user`)

### 1.0.1
* Compatibility with earlier versions of Ruby

### 1.0.0
* `tracker#import` added
* Change to internal tracking message format. Messages written by earlier versions of the
library will not work with 1.0.0 consumer classes
* alias bugfixed
* Fixes to tests to allow for different timezones
* Support for optional/experimental people API properties in people calls
115 changes: 0 additions & 115 deletions Readme.rdoc

This file was deleted.

57 changes: 57 additions & 0 deletions demo/import_project_token_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env ruby
# Example 02: Import Historical Events — Project Token Auth
#
# Use tracker.import with a project token when you don't have a service account.
# The token is sent as the HTTP Basic Auth username with an empty password.
#
# Run: bundle exec ruby demo/import_project_token_example.rb

$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
require 'mixpanel-ruby'

# ── Configuration ─────────────────────────────────────────────────────────────
PROJECT_TOKEN = 'your_project_token'
# ──────────────────────────────────────────────────────────────────────────────

tracker = Mixpanel::Tracker.new(PROJECT_TOKEN)

credentials = { project_token: PROJECT_TOKEN }

puts '--- Import a single historical event ---'
result = tracker.import(credentials, 'user_001', 'Subscription Started', {
'plan' => 'Pro',
'billing_period' => 'monthly',
'time' => Time.parse('2024-03-10 12:00:00 UTC').to_i,
})
puts "Success: #{result}"

puts "\n--- Import with no explicit timestamp (defaults to now) ---"
result = tracker.import(credentials, 'user_002', 'Feature Used', {
'feature_name' => 'dark_mode',
})
puts "Success: #{result}"

puts "\n--- Import multiple distinct users ---"
users = %w[user_100 user_101 user_102 user_103]
users.each_with_index do |user_id, idx|
timestamp = (Time.now - (idx * 86_400)).to_i # each event one day apart
result = tracker.import(credentials, user_id, 'Daily Active', {
'day_offset' => idx,
'time' => timestamp,
})
puts " #{user_id}: #{result ? 'ok' : 'FAILED'}"
end

puts "\n--- Import with rich properties ---"
result = tracker.import(credentials, 'user_050', 'Order Placed', {
'order_id' => 'ORD-9876',
'items' => 3,
'total_usd' => 124.50,
'coupon_used' => true,
'channel' => 'email_campaign',
'campaign_id' => 'summer_sale_2024',
'time' => Time.parse('2024-07-04 18:30:00 UTC').to_i,
})
puts "Success: #{result}"

puts "\nDone."
Loading
Loading