Skip to content

Instantly share code, notes, and snippets.

@ilyakatz
Last active March 5, 2020 12:19
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ilyakatz/6175747 to your computer and use it in GitHub Desktop.
Save ilyakatz/6175747 to your computer and use it in GitHub Desktop.
MixPanel job for Dashing

Description

Simple Dashing job to display total number of events in MixPanel .

##Preview

##Dependencies

mixpanel_client

Add it to dashing's gemfile:

gem 'mixpanel_client'

and run bundle install.

##Usage

Simplest way is to use the Number widget Add the following snippet to the dashboard layout file:

<li data-row="2" data-col="4" data-sizex="1" data-sizey="1">
  <div data-id="mixpanel_signup"
       data-view="Number"
       data-title="Signups"
       style="background-color:#bb8e98;"
       data-moreinfo="People signed up in the last 30 days"></div>
  <i class="icon-user icon-background"></i>
</li>

##Settings

Update mixpanel_config.rb with your MixPanel API Key and Secret

##More info

MixPanel API doc

Known issues

require 'mixpanel_client'
require 'date'
root = ::File.dirname(__FILE__)
require ::File.join(root, "..", 'lib', 'mixpanel_config')
require ::File.join(root, "..", 'lib', 'mixpanel_event_number')
def mixpanel_exports
send_event('mixpanel_signup_greenland', {
current: number_for_event_using_export("Sign Up", "greenland", true)
})
send_event('mixpanel_signup_portland', {
current: number_for_event_using_export("Sign Up", "portland", true)
})
end
####### get updates from MixPanel ##########
SCHEDULER.every '5m', :first_in => 0 do |job|
# MixPanel export API doesn't allow for concurrent requests to export API, so need to make the sequential
mixpanel_exports
end
SCHEDULER.every '10s', :first_in => 0 do |job|
send_event('mixpanel_signup', {
current: mixpanel_event_number(event_name: "Sign Up", property: "country", value: "USA")
})
end
#put in lib directory
class MixPanelConfiguration
def self.config
{
api_key: 'your_key',
api_secret: 'your_secret'
}
end
end
#put in lib directory
def mixpanel_client
@mixpanel_client ||= Mixpanel::Client.new(MixPanelConfiguration.config)
end
# Public: Returns number of occurrences of the event
# of the date range of [T-num_days, T] where T is today's date
# options - The Hash options used to query MixPanel:
# :event_name - The String name of the event.
# :type - The String analysis type you would like to get data for. Available options are "general", "unique", "average" (optional).
# :num_days - The Integer number of days to look back (optional)
# :property - The String if filtering by property, name of the property. Must provide :value (optional)
# :value - The String if filtering by property, value of the property. Must provide :property (optional)
# https://mixpanel.com/docs/api-documentation/data-export-api
#
# Examples
#
# mixpanel_event_number(event_name: "Created Gist", property: "level", value: "private")
# mixpanel_event_number(event_name: "Created Gist")
# mixpanel_event_number(event_name: "Created Gist", type: "unique")
def mixpanel_event_number(options)
property, value = options[:property], options[:value]
unless (property && value) || (!property && !value)
raise "Must specify both 'property' and 'value' or none"
end
if [TrueClass, FalseClass].include?(value.class)
raise "As of Aug 7, 2013, MixPanel has a bug with querying boolean values\nPlease use number_for_event_using_export until that's fixed"
end
event_name = options[:event_name]
unless event_name
raise "Event name must be provided"
end
type = options[:type] || "general" #MixPanel API uses the term 'general' to mean 'total'
unless ["unique", "general", "average"].include? type
raise "Invalid type #{type}"
end
num_days = options[:num_days] ||30
interval = options[:interval] || "day"
mixpanel_options = {
type: type,
unit: interval,
interval: num_days,
limit: 5,
}
if property && value
mixpanel_endpoint = "events/properties/"
mixpanel_options.merge!({
event: event_name,
values: [value],
name: property
})
else
mixpanel_endpoint = "events/"
mixpanel_options.merge!({
event: [event_name]
})
end
data = mixpanel_client.request(mixpanel_endpoint, mixpanel_options)
total_for_events(data)
end
def total_for_events(data)
counts_per_property = data["data"]["values"].collect do |c, values|
values.collect { |k, v| v }.inject(:+)
end
#now, calculate grand total
counts_per_property.inject(:+)
end
###########################
def number_for_event_using_export(event_name, property, value, num_days = 30)
# TODO:
# MixPanel doesn't understand boolean values for properties
# There is an open ticket, but for now, there is a work around to use export API
# https://mixpanel.com/docs/api-documentation/exporting-raw-data-you-inserted-into-mixpanel
to_date = Date.today
from_date = to_date - num_days
data = mixpanel_client.request('export', {
event: [event_name],
from_date: from_date.to_s,
to_date: to_date.to_s,
where: "boolean(properties[\"#{property}\"]) == #{value} ",
})
data.count
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment