Skip to content

Instantly share code, notes, and snippets.

@ilyakatz
Last active March 5, 2020 12:19
Show Gist options
  • Select an option

  • Save ilyakatz/6175747 to your computer and use it in GitHub Desktop.

Select an option

Save ilyakatz/6175747 to your computer and use it in GitHub Desktop.

Revisions

  1. Ilya Katz revised this gist Aug 7, 2013. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion mixpanel.rb
    Original file line number Diff line number Diff line change
    @@ -5,16 +5,20 @@
    require ::File.join(root, "..", 'lib', 'mixpanel_config')
    require ::File.join(root, "..", 'lib', 'mixpanel_event_number')

    # MixPanel export API doesn't allow for concurrent requests
    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

  2. Ilya Katz revised this gist Aug 7, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Readme.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    ## Description

    Simple [Dashing](http://shopify.github.com/dashing) job to display total number of events in [MixPanel](https://mixpanel.com) followers.
    Simple [Dashing](http://shopify.github.com/dashing) job to display total number of events in [MixPanel](https://mixpanel.com) .

    ##Preview

  3. Ilya Katz revised this gist Aug 7, 2013. 3 changed files with 141 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions mixpanel.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    require 'mixpanel_client'
    require 'date'

    root = ::File.dirname(__FILE__)
    require ::File.join(root, "..", 'lib', 'mixpanel_config')
    require ::File.join(root, "..", 'lib', 'mixpanel_event_number')

    # MixPanel export API doesn't allow for concurrent requests
    def mixpanel_exports
    send_event('mixpanel_signup_greenland', {
    current: number_for_event_using_export("Sign Up", "greenland", true)
    })

    end

    ####### get updates from MixPanel ##########
    SCHEDULER.every '5m', :first_in => 0 do |job|
    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
    12 changes: 12 additions & 0 deletions mixpanel_config.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    #put in lib directory

    class MixPanelConfiguration

    def self.config
    {
    api_key: 'your_key',
    api_secret: 'your_secret'
    }
    end

    end
    103 changes: 103 additions & 0 deletions mixpanel_event_number.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,103 @@
    #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
  4. Ilya Katz created this gist Aug 7, 2013.
    45 changes: 45 additions & 0 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    ## Description

    Simple [Dashing](http://shopify.github.com/dashing) job to display total number of events in [MixPanel](https://mixpanel.com) followers.

    ##Preview

    ![](https://www.evernote.com/shard/s237/sh/40b6ef87-f27d-42ec-aede-2f7ab7a200c7/0bb5e4743c15721ea21afda73fed7918/deep/0/ChallengePost%20KPI.png)


    ##Dependencies

    [mixpanel_client](https://github.com/keolo/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](https://mixpanel.com/docs/api-documentation/data-export-api)

    ## Known issues

    * 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