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");
}