Skip to content

Instantly share code, notes, and snippets.

@dimroc
Last active April 23, 2023 20:52
Show Gist options
  • Save dimroc/da648d2ccfa22f67694a to your computer and use it in GitHub Desktop.
Save dimroc/da648d2ccfa22f67694a to your computer and use it in GitHub Desktop.
Server side mixpanel analytics implementation in ruby. There are other simple devise controllers that are overridden omitted from gist.
# http://blog.mixcel.io/10-ways-to-get-mixpanel-right-the-first-time-yHNlbz-wbcZz7E7PWMXvRg
class Analytic
module Mixpanelable
extend ActiveSupport::Concern
private
def mp_track(event_name, options = {})
mp_track_for_user(current_user, event_name, options)
end
def mp_track_charge(amount, options = {})
return unless token.present?
options.merge! team: @organization.name if @organization.present?
options.merge! ip: current_user.current_sign_in_ip.to_s
mixpanel.people.track_charge(current_user.id, amount.to_f, options)
end
def mp_track_for_user(user, event_name, options = {})
return unless token.present?
options.merge! team: @organization.name if @organization.present?
options.merge! ip: user.current_sign_in_ip.to_s
mixpanel.track(user.id, event_name, options)
end
def set_mp_cookie_information
# In your case, the cookies will be namespaced differently
# so remember to use your own namespace.
if (mp_cookies = cookies[namespace])
@mp_properties = JSON.parse(mp_cookies)
end
end
def identify_on_mixpanel(user)
return unless token.present?
raise ArgumentError, "User cannot be blank when identifying on mixpanel" if user.blank?
Rails.logger.info "## Identifying User #{user.id} with Mixpanel"
# attributes is existing Mixpanel Params that are cookie'd by
# Mixpanel Javascript
attributes = safely_retrieve_attributes
mixpanel_params = {
'$email': user.email,
'$created': user.created_at.as_json,
'$first_name': user.first_name,
'$last_name': user.last_name,
'$ip': user.current_sign_in_ip.to_s,
'user_id': user.id,
'Teams': user.organizations.map(&:name)
}.merge(attributes)
distinct_id = mixpanel_params['distinct_id']
# Alias the User with the old distinct ID
mixpanel.alias user.id, distinct_id if distinct_id.present?
# Set user properties
Rails.logger.info "## Current Mixpanel User IP: #{user.current_sign_in_ip.to_s}"
mixpanel.people.set user.id, mixpanel_params, user.current_sign_in_ip.to_s
mp_track_for_user user, "Identified"
end
def mixpanel
@mixpanel ||= Mixpanel::Tracker.new(token)
end
def token
!Rails.env.test? && ENV['MIXPANEL_TOKEN']
end
def namespace
"mp_#{token}_mixpanel"
end
def safely_retrieve_attributes
JSON.parse(cookies[namespace]) || {}
rescue JSON::ParserError => e
Honeybadger.notify(
:error_class => "Mixpanel Analytics Cookie Retrieval",
:error_message => e.message,
:parameters => { cookie: cookies[namespace] }
)
{}
end
end
end
class DeviseOverride::RegistrationsController < Devise::RegistrationsController
include Analytic::Mixpanelable
before_filter :set_mp_cookie_information
def create
super do |resource|
Rails.logger.info "## Inside DeviseOverride::RegistrationsController"
if resource.persisted?
resource.mp_properties = @mp_properties
resource.save
identify_on_mixpanel(resource)
end
end
end
private
def sign_up_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation).merge(role: :user)
end
def account_update_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password)
end
end
class DeviseOverride::SessionsController < Devise::SessionsController
include Analytic::Mixpanelable
before_filter :set_mp_cookie_information
def create
super do |resource|
Rails.logger.info "## Inside DeviseOverride::SessionsController"
identify_on_mixpanel(resource) if resource.persisted?
end
end
def update
super do |resource|
identify_on_mixpanel(resource) if resource.persisted?
end
end
end
@davideghz
Copy link

as per MP docs, alias should be called only once after signup, but in your code it's called each time user signin. Am I misunderstanding something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment