Mixpanel Magic Lamp
Rub the magic lamp and your desired Mixpanel ORM will appear!
If you're using Mixpanel for your web site analytics you probably thought
in make reports exporting your data through any Mixpanel API client. This gem is your answer
for not overwarming your head with so many doc, and it will remind you to ActiveRecord
.
Install
You can install this gem by
$ gem install mixpanel_magic_lamp
Or bundle it on your app by adding this line at your Gemfile
gem 'mixpanel_magic_lamp'
Configuration
To setup this gem you should add API keys and other config:
MixpanelMagicLamp.configure do |config|
# Set your API Key/Secret
config.api_key = "YOUR MIXPANEL API KEY"
config.api_secret = "YOUR MIXPANEL API SECRET"
# Run query in parallel (recomended for better performance)
config.parallel = true
# Default interval on from/to dates when dates are not provided
config.interval = 30
end
Rails config generator
Copy base config file on your Rails app by
rails generate mixpanel_magic_lamp:config
Build your query
The most interesting feature from this library is probably the query builder, that let you to build an 'ActiveRecord' like query to run API queries, it will remind you to the Mixpanel UI:
where
Start any query with this keyword, and extend is as long as you need. This method accept a hash as first parameter where each pair of key/value are traslated to "key == value" (equals_to), a second parameter may change union word:
Mixpanel.where(country: 'Spain', gender: 'Female').to_s
=> "(properties[\"country\"] == \"Spain\" and properties[\"gender\"] == \"Female\")"
Mixpanel.where({country: 'Spain', gender: 'Female'}, 'or').to_s
=> "(properties[\"country\"] == \"Spain\" or properties[\"gender\"] == \"Female\")"
Then you may append any existent query build to complete your API query:
Mixpanel.where(country: 'Spain').or.is_set('source').to_s
=> "(properties[\"country\"] == \"Spain\") or (defined (properties[\"source\"]))"
### and/or
Concat as many query builders as you need with and
and or
operators:
Mixpanel.where(country: "Spain", browser: "Chrome")
.and.is_set('device_type')
.and.does_not_equal(user_type: 'bot')
.and.contains(url: '/sales')
=> "(properties[\"country\"] == \"Spain\" and properties[\"browser\"] == \"Chrome\") and (defined (properties[\"device_type\"])) and (properties[\"user_type\"] != \"bot\") and (\"/sales\" in (properties[\"url\"]))">
on
Use it as by statement on your UI, in order to group segmentation:
Mixpanel.on('country')
=> "properties[\"country\"]"
Builders
equals
Mixpanel.where.and.equals(country: 'Spain', user_type: 'human').to_s
=> "(properties[\"country\"] == \"Spain\" and properties[\"user_type\"] == \"human\")"
does_not_equal
Mixpanel.where.and.does_not_equal(country: 'Spain', user_type: 'human')
=> "(properties[\"country\"] != \"Spain\" and properties[\"user_type\"] != \"human\")"
contains
Mixpanel.where.and.contains(country: 'Spain', user_type: 'human').to_s
=> "(\"Spain\" in (properties[\"country\"]) and \"human\" in (properties[\"user_type\"]))"
does_not_contain
Mixpanel.where.and.does_not_contain(country: 'Spain', user_type: 'human').to_s
=> "(not \"Spain\" in (properties[\"country\"]) and not \"human\" in (properties[\"user_type\"]))"
is_set
Mixpanel.where.and.is_set(['country', 'user_type']).to_s
=> "(defined (properties[\"country\"]) and defined (properties[\"user_type\"]))"
is_not_set
Mixpanel.where.and.is_not_set(['country', 'user_type']).to_s
=> "(not defined (properties[\"country\"]) and not defined (properties[\"user_type\"]))"
Actions
Mixpanel API client has a lot of possible actions, so far these are the supported actions:
Segmentation
Classic Mixpanel segmentation action, where you can specify event name, from/to dates and any conditions you want. Prepare and run as many request in parallel you need
interface = Mixpanel::Interface.new
page_visits_query = Mixpanel.where("product" => 'Finances')
.and.is_set("subproduct")
page_visits = interface.segmentation('Page visit', { from: Data.parse('2015-01-31'),
to: Date.today },
{ where: page_visits_query })
login_clicks_query = Mixpanel.where("device_type" => 'mobile')
login_clicks = interface.segmentation('Login', { from: Data.parse('2015-04-01'),
to: Date.today },
{ where: login_clicks_query })
# Run all the queued queries
interface.run!
# Present your data...
p page_visits[:data]
p login_clicks[:data]
Segmentation by
Same as segmentation but grouping the output by any property you want to.
interface = Mixpanel::Interface.new
page_visits_query = Mixpanel.where("product" => 'Finances')
.and.is_set("subproduct")
page_visits = interface.segmentation('Page visit', { from: Data.parse('2015-01-31'),
to: Date.today },
{ where: page_visits_query,
on: Mixpanel.on('device_type') })
# Run all the queued queries
interface.run!
# Present your data...
p page_visits[:data]
Your own interface
Now you master all the above concepts, the best thing you can do is to build your own interface model for extracting your reports:
module Mixpanel
class LandingPagesInterface < Mixpanel::Interface
def initialize
super()
end
def views(from: nil, to: nil)
where_context = Mixpanel.where('page_type' => 'landing')
.and.is_set('device_type')
segmentation 'Page view', { from: from, to: to },
{ where: where_context }
end
def views_by_devices(from: nil, to: nil)
where_context = Mixpanel.where('page_type' => 'landing')
.and.is_set('device_type')
segmentation_interval 'Page view', { from: from, to: to },
{ where: where_context,
on: Mixpanel.on('device_type') }
end
end
end
# Initialize your interface
landing_interface = Mixpanel::LandingPagesInterface.new
# Prepare all the queries
landing_last_week_views = landing_interface.views(from: 14.days.ago, to: 7.days.ago)
landing_this_week_views = landing_interface.views(from: 6.days.ago, to: Date.today)
landing_last_week_view_by_devices = landing_interface.views_by_devices(from: 14.days.ago, to: 7.days.ago)
# Run all the queries
landing_interface.run!
# Retrieve your data!
p landing_last_week_views[:data]
p landing_this_week_views[:data]
p landing_last_week_view_by_devices[:data]
On top of mixpanel_client Gem
This ORM is build on top mixpanel_client gem.
You'll find the oficial mixpanel info here.
Monkey patching
On this gem you'll find a Mixpanel::Client
class monkey patch to avoid exceptions raise
when any of the parallel request fails, i.e all the requests will run until completion and return
their correspondent HTTP status (error or success) and body as usual.
See it here.
Contribution
If you have cool idea for improving this Gem or any bug fix just open a pull request and I'll be glad to have a look and merge it if seems fine.
License
This project rocks and uses MIT-LICENSE.