Added support for native apps
Andrew Kane
committed Apr 21, 2014
commit ef52f0d0e6b0572a21c9a534360cae0e72719dee
Showing 4
changed files with
60 additions
and 33 deletions
README.md
+30
-0
| @@ | @@ -121,6 +121,36 @@ To track visits across multiple subdomains, add this to your layout **before** t |
| </script> | |
| ``` | |
| + | ### Native Apps [master] |
| + | |
| + | When a user launches the app, create a visit. Send a `POST` request to `/ahoy/visits` with: |
| + | |
| + | - platform - `iOS`, `Android`, etc. |
| + | - app_version - `1.0.0` |
| + | - os_version - `7.0.6` |
| + | - visitor_token - if you have one |
| + | |
| + | The endpoint will return a JSON response like: |
| + | |
| + | ```json |
| + | { |
| + | "visit_token": "8tx2ziymkwa1WlppnkqxyaBaRlXrEQ3K", |
| + | "visitor_token": "hYBIV0rBfrIUAiArWweiECt4N9pyiygN" |
| + | } |
| + | ``` |
| + | |
| + | Send the visit token in the `Ahoy-Visit` header for all requests. |
| + | |
| + | After 4 hours, create another visit and use the updated visit token. |
| + | |
| + | To change the platform on the web, use: |
| + | |
| + | ```html |
| + | <script> |
| + | var Ahoy = {"platform": "Mobile Web"} |
| + | </script> |
| + | ``` |
| + | |
| ### More | |
| - Excludes bots | |
app/controllers/ahoy/visits_controller.rb
+13
-3
| @@ | @@ -3,23 +3,33 @@ module Ahoy |
| before_filter :halt_bots | |
| def create | |
| + | visit_token = generate_token |
| + | visitor_token = params[:visitor_token] || generate_token |
| + | |
| visit = | |
| Ahoy.visit_model.new do |v| | |
| - | v.visit_token = params[:visit_token] |
| - | v.visitor_token = params[:visitor_token] |
| + | v.visit_token = visit_token |
| + | v.visitor_token = visitor_token |
| v.ip = request.remote_ip if v.respond_to?(:ip=) | |
| v.user_agent = request.user_agent if v.respond_to?(:user_agent=) | |
| v.referrer = params[:referrer] if v.respond_to?(:referrer=) | |
| v.landing_page = params[:landing_page] if v.respond_to?(:landing_page=) | |
| v.user = current_user if respond_to?(:current_user) and v.respond_to?(:user=) | |
| + | v.platform = params[:platform] if v.respond_to?(:platform=) |
| + | v.app_version = params[:app_version] if v.respond_to?(:app_version=) |
| + | v.os_version = params[:os_version] if v.respond_to?(:os_version=) |
| end | |
| visit.save! | |
| - | render json: {visit_token: visit.visit_token} |
| + | render json: {visit_token: visit.visit_token, visitor_token: visit.visitor_token} |
| end | |
| protected | |
| + | def generate_token |
| + | SecureRandom.urlsafe_base64(32).gsub(/[\-_]/, "").first(32) |
| + | end |
| + | |
| def browser | |
| @browser ||= Browser.new(ua: request.user_agent) | |
| end | |
generators/ahoy/templates/install.rb b/lib/generators/ahoy/templates/install.rb
+5
-0
| @@ | @@ -39,6 +39,11 @@ class <%= migration_class_name %> < ActiveRecord::Migration |
| t.string :utm_content | |
| t.string :utm_campaign | |
| + | # native apps |
| + | # t.string :platform |
| + | # t.string :app_version |
| + | # t.string :os_version |
| + | |
| t.timestamp :created_at | |
| end | |
vendor/assets/javascripts/ahoy.js
+12
-30
| @@ | @@ -3,7 +3,7 @@ |
| (function (window) { | |
| "use strict"; | |
| - | var debugMode = false; |
| + | var debugMode = true; |
| var options = window.Ahoy || {}; | |
| var $ = window.jQuery || window.Zepto || window.$; | |
| var visitToken, visitorToken; | |
| @@ | @@ -50,23 +50,6 @@ |
| return null; | |
| } | |
| - | // ids |
| - | |
| - | // https://github.com/klughammer/node-randomstring |
| - | function generateToken() { |
| - | var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz'; |
| - | var length = 32; |
| - | var string = ''; |
| - | var i, randomNumber; |
| - | |
| - | for (i = 0; i < length; i++) { |
| - | randomNumber = Math.floor(Math.random() * chars.length); |
| - | string += chars.substring(randomNumber, randomNumber + 1); |
| - | } |
| - | |
| - | return string; |
| - | } |
| - | |
| function debug(message) { | |
| if (debugMode) { | |
| window.console.log(message, visitToken, visitorToken); | |
| @@ | @@ -78,26 +61,18 @@ |
| visitToken = getCookie("ahoy_visit"); | |
| visitorToken = getCookie("ahoy_visitor"); | |
| - | if (visitToken && visitorToken) { |
| + | if (visitToken && visitorToken && visitToken != "test") { |
| // TODO keep visit alive? | |
| debug("Active visit"); | |
| } else { | |
| - | if (!visitorToken) { |
| - | visitorToken = generateToken(); |
| - | setCookie("ahoy_visitor", visitorToken, visitorTtl, options.domain); |
| - | } |
| - | |
| - | // always generate a new visit id here |
| - | visitToken = generateToken(); |
| - | setCookie("ahoy_visit", visitToken, visitTtl, options.domain); |
| + | setCookie("ahoy_visit", "test", 1, options.domain); |
| // make sure cookies are enabled | |
| if (getCookie("ahoy_visit")) { | |
| debug("Visit started"); | |
| var data = { | |
| - | visit_token: visitToken, |
| - | visitor_token: visitorToken, |
| + | platform: options.platform || "Web", |
| landing_page: window.location.href | |
| }; | |
| @@ | @@ -106,9 +81,16 @@ |
| data.referrer = document.referrer; | |
| } | |
| + | if (visitorToken) { |
| + | data.visitor_token = visitorToken; |
| + | } |
| + | |
| debug(data); | |
| - | $.post("/ahoy/visits", data); |
| + | $.post("/ahoy/visits", data, function(response) { |
| + | setCookie("ahoy_visit", response.visit_token, visitTtl, options.domain); |
| + | setCookie("ahoy_visitor", response.visitor_token, visitorTtl, options.domain); |
| + | }, "json"); |
| } else { | |
| debug("Cookies disabled"); | |
| } | |