Giter Club home page Giter Club logo

django-utm-tracker's Introduction

Django UTM Tracker

Django app for extracting and storing UTM tracking values.

Django support

This package support Django 3.2+, and Python 3.8+

Background

This app has been designed to integrate the standard utm_* querystring parameters that are used by online advertisers with your Django project.

It does not replace analytics (e.g. Google Analytics) and Adwords tracking, but does have one crucial difference - it allows you to assign a specific user to a campaign advert.

This may be useful if you are trying to assess the value of multiple channels / campaigns.

Supported querystring parameters

Parameter Definition
utm_medium Identifies what type of link was used.
utm_source Identifies which site sent the traffic, and is a required parameter.
utm_campaign Identifies a specific product promotion or strategic campaign.
utm_term Identifies search terms.
gclid Identifies a google click, is used for ad tracking in Google Analytics via Google Ads.
aclk Identifies a Microsoft Ad click (bing), is used for ad tracking.
msclkid Identifies a Microsoft Ad click (MS ad network), is used for ad tracking.
twclid Identifies a Twitter Ad click, is used for ad tracking.
fbclid Identifies a Facebook Ad click, is used for ad tracking.

In addition to the fixed list above, you can also specify custom tags using the UTM_TRACKER_CUSTOM_TAGS setting. Any querystring params that match these tags are stashed in a JSONField called custom_tags.

How it works

The app works as a pair of middleware classes, that extract utm_ values from any incoming request querystring, and then store those parameters against the request.user (if authenticated), or in the request.session (if not).

The following shows this workflow (pseudocode - see test_utm_and_lead_source for a real example):

client = Client()
# first request stashes values, but does not create a LeadSource as user is anonymous
client.get("/?utm_medium=medium&utm_source=source...")
assert utm_values_in_session
assert LeadSource.objects.count() == 0

# subsequent request, with authenticated user, extracts values and stores LeadSource
user = User.objects.create(username="fred")
client.force_login(user, backend=settings.FORCED_AUTH_BACKEND)
client.get("/")
assert not utm_values_in_session
assert LeadSource.objects.count() == 1

Why split the middleware in two?

By splitting the middleware into two classes, we enable the use case where we can track leads without utm_ querystring parameters. For instance, if you have an internal referral program, using a simple token, you can capture this as a LeadSource by adding sentinel values to the request.session:

def referral(request, token):
    # do token handling
    ...
    # medium and source are mandatory for lead source capture
    request.session["utm_medium"] = "referral"
    request.session["utm_source"] = "internal"
    # campaign, term and content are optional fields
    request.session["utm_campaign"] = "july"
    request.session["utm_term"] = token
    request.session["utm_content"] = "buy-me"
    return render(request, "landing_page.html")

Configuration

Add the app to INSTALLED_APPS:

# settings.py
INSTALLED_APPS = [
    ...
    "utm_tracker"
]

UTM_TRACKER_CUSTOM_TAGS = ["tag1", "tag2"]

and add both middleware classes to MIDDLEWARE:

# settings.py
MIDDLEWARE = [
    ...
    "utm_tracker.middleware.UtmSessionMiddleware",
    "utm_tracker.middleware.LeadSourceMiddleware",
]

The UtmSession middleware must come before LeadSource middleware.

django-utm-tracker's People

Contributors

adamf avatar culshaw avatar djm avatar hugorodgerbrown avatar roniemartinez avatar sarahboyce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-utm-tracker's Issues

Support `gclid` values

In order to effectively track google ads as well as utm parameters we could do with tracking the gclid value too.

stash_utm_params is double-counting on redirects

If a site issues a 300 response and the utm_params are maintained, then the log double-counts, as the stash_utm_params function is "dumb". It should check the session first for existing duplicates (based on utm_ content only).

Add support for multiple (stacked) lead sources

The library currently stores the utm info as soon as it has an authenticated user, but it's quite possible for a user to come through multiple pages before they log in / register. In this situation each new request will eject the previous utm_ params from the session, resulting in only the last set being registered.

It would be good to be able to stack them up (in a list) on the session, and then flush them all out (in order) at once - so you can track where the user had gone.

python 3.6 support

I see that your min version of python is 3.7, we happen to run 3.6 in production. What 3.7 features are you using ?

Why not save all the LeadSource records (even when they are anonymous)

I'm curious why you don't persist all the LeadSource records (with NULL user FKs) so you can see what is generating buzz. Seems like you could store the LeadSource FK in the session as well and when they do login (if they ever do) you would update all the already existing LeadSource records. This would mean you could have request.lead_source available for use inside the views as well so you could tell where people came from and deliver a more customized experience.

The only stopper here would be bots could generate a ton of LeadSource records so you would need to do UserAgent detection and just not persist any LeadSource records from those bots.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.