GithubHelp home page GithubHelp logo

keen / keen-tracking.js Goto Github PK

View Code? Open in Web Editor NEW
260.0 36.0 84.0 4.01 MB

A light, fast and flexible javascript tracking library

Home Page: https://keen.io

License: MIT License

JavaScript 94.75% HTML 5.25%
tracking tracking-pixels tracking-plugin tracking-api tracker event-tracker user-tracking customer-tracker analytics click-tracking

keen-tracking.js's Issues

disabling event logging

I'm trying to turn off event-logging in dev environment, but Keen.enabled = false doesn't seem to do the trick (as evidenced by viewing my collections in the keen dash). Is there another step I have to take?

The project is react using webpack


// keen-config.js
import Keen from 'keen-tracking'
export const initKeen = () => {
    const client = new Keen({
        projectId,
        writeKey,
    })

    const sessionCookie = Keen.utils.cookie('wayhome-cookie')
    if (!sessionCookie.get('visitorID')) {
        sessionCookie.set('visitorID', Keen.helpers.getUniqueId())
    }
    const sessionID = Keen.helpers.getUniqueId()
    const sessionTimer = Keen.utils.timer()
    sessionTimer.start()
    client.extendEvents(() => {
       // yadda yadda yadda
    })
 return client
}


// index.js
const client = initKeen()
window.Keen = client
if (process.env.NODE_ENV === 'development') {
    console.log("DISABLING KEEN") 
    Keen.enabled = false
}

The console.log statement fires, so I know my conditional is working.

Document that `getDatetimeIndex()` default is *not* UTC

Hello!

When I started using getDatetimeIndex(), I assumed that it would be returning the time for UTC. I had to read the MDN page for Date() to realize that it was browser-local time. I think it would be handy to document this and perhaps also show how to get the DT in UTC[1]:

var now = new Date(); 
var now_utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(),  now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
var utcDatetimeIndex = Keen.helpers.getDatetimeIndex(now_utc);

Thank you for your time and effort on this!

Cheers,
Fitz

[1] Adapted from: http://stackoverflow.com/a/6777470

Add keen-web-autocollector to this repo

I'm not seeing the web auto collector in any of the keen repos. Maybe I'm blind. I think it just sits on top of keen-tracking. It works great, but I think I need to extend it a bit to add some autofill type features. keen-tracking can pretty much be setup to do what it is doing, but it'd be nice to start somewhere a little higher up.

I can see the non minified code at https://d26b395fwzu5fz.cloudfront.net/keen-web-autocollector-1.0.8.js , but it is all webpackified. Be nice to see the source source.

Thanks!

Remove json3 dependency

It is not up to keen-tracking to attempt to patch the working environment. json3 can be a peer dependency, but it really shouldn't be even that.

Add a note to the ./README.md that for keen-tracking to work, window.JSON must be present.

Now you are adding an extra 42.28kB to everyones bundle because some (what? I don't know a single browser that does not implement window.JSON) browsers do not implement it.

JSON.parse is called on invalid json (response from sendEventData)

I got the following error on my production server today:

<html> 
^ 
SyntaxError: Unexpected token < in JSON at position 0 
    at JSON.parse (<anonymous>) 
    at IncomingMessage.<anonymous> (/app/node_modules/keen-tracking/lib/record-events-server.js:206:22) 

The error occurs at /app/node_modules/keen-tracking/lib/record-events-server.js:206:22 where you have: var res = JSON.parse(body), error;

It's been my experience that you should always wrap any call to JSON.parse in a try/catch block.

I'm sure that's not enough for a fix - seems like the keen server is returning an html body instead of json - so you might have a bigger issue here, and I'm not even sure if I was sending something invalid in my request (because the error, as you can see, cannot be parsed).

writePath config option ignored

The README claims there is a writePath config property:

`writePath: '/3.0/projects/YOUR_PROJECT_ID/events'`

host and writePath: these options can be overwritten to make it easier than ever to proxy events through your own intermediary host.

Yet it seems completely ignored. Searching the codebase for writePath only find matches in the README.

Give us a way to stop the queue interval

I'm writing a seed script that records some predefined events for development purpose. But the script never finishes, and I was stuck for a few hours until I find out that this lib sets an interval and that prevents node process from exiting.

It would be great if I could stop that interval when my script finishes sending the events so that the process can exit normally.

For now I'm forcing process.exit() when I'm done.

Base64 data attributes are not url encoded

Base64 strings occasionally contain special characters (most notably, +). Right now keen-tracking does not URL Encode the base64 encoded data attribute before sending it. In certain scenarios this causes the URL to break, and the Keen API barfs.

Script error binding locks up browsers with selective script blocking extensions

  • Install the uBlock Origin Chrome extension.
  • Visit http://parachutehome.com with the dev tools Network tab open.
  • Observe as the page attempts to load the same script, keen-tracking-1.1.3.min.js, as many times as it can per second, completely locking up the tab process indefinitely (unless you're very patient, this usually means killing the whole browser process and all tab memory). On my MacBook Pro that's 200k times in 5-10 minutes.

I believe the reason is this line: https://github.com/keen/keen-tracking.js/blob/master/lib/browser-async.js#L8

s.onload = s.onerror = s['onreadystatechange'] = function () { ...

I think that onerror binding is causing the blocked script to attempt to load in perpetuity when something like uBlock is intercepting the request. This is obviously not okay.

I'd suggest simply killing the onerror binding, I can't think why it'd be necessary.

image

Build and test recordEvent(s) functionality

What does this do? #recordEvent and #recordEvents are the core event transmission methods, and do all of the heavy-HTTP-lifting.

// var client = new Keen.Client({ .. });
client.recordEvent("collection", {}, function(err, res){ });
client.recordEvents({ "collection": [{}] }, function(err, res){ });

Todo:

  • Port addEvent(s) functionality over from keen-js
  • Set up browser testing (karma, phantomjs)
  • Set up server testing
  • Set up Travis integration for master branch and activate badge
  • Set up SauceLabs integration (local)
  • Ensure support for IE8-latest

Suggestion: cookie.set could return value instead of this

A very common use case with cookie is to try to get it, and if it does not exist set it instead.

As there is no function getOrSet, it would be great if setwould return the value instead of thisso that we could do that:

const userID = sessionCookie.get('user_id') || sessionCookie.set('user_id', Keen.helpers.getUniqueId())

Is there any internal reason for having set return this ? I haven't found any use case for that.

Missing tag name

I think you are missing the name of the tag here in the text below on README.md. Above which tag should the snippet be pasted?

Copy/paste this snippet of JavaScript above the tag of your page to load the tracking library asynchronously.

IP to Geo parser and dynamic IPs don't play ball

As per documentation:

input: An object with a key of “ip” and a value of the name of the property containing the IP address to parse.
This add-on can be used with the dynamic IP address placeholder.

This doesn't work and results in a 400:

{
   ...anyEvents,
    keen: {
      addons: [
        {
          name: 'keen:ip_to_geo',
          input: {
            ip: '${keen.ip}',
          },
          output: 'geo',
        },
]

This works:

{
   ...anyEvents,
    my_ip: '${keen.ip}',
    keen: {
      addons: [
        {
          name: 'keen:ip_to_geo',
          input: {
            ip: 'my_ip',
          },
          output: 'geo',
        },
]

am I doing it wrong?

Build and test Keen.Client instance

What does this do? Keen.Client is the core client instance constructor for all project-specific functionality. Keen.Client.prototype will carry all of the primary methods.

// Constructor config (optional)
var client = new Keen.Client({
  projectId: "YOUR_PROJECT_ID",
  writeKey: "YOUR_WRITE_KEY",
  host: "api.keen.io/3.0",
  protocol: "https", // "http" || "auto"
  requestType: "xhr" // "jsonp" || "beacon"
});

Miscellaneous methods:

// Config accessors (optional)
client.projectId("YOUR_PROJECT_ID");
client.writeKey("YOUR_WRITE_KEY");

// Get/extend base API URL, with optional params
client.url();
client.url("/events");
client.url("/events/name", { key: "value" });

Event Emitter:

client.on("some event", function(){
});
client.once("another event", function(){
});
client.off("some event");
client.emti("another event", { something: "to", pass: true });

Todo:

  • Build and test core methods
  • Build and test accessor methods (common spec)
  • Build and test misc methods

clearing/checking extendEvents

Is it possible to clear the data set with a call to extendEvents()?

And, related: is it possible to check & see what the current extendEvents() inclusions are? eg

client.extendEvents(() => {
  return {
    time: Keen.helpers.getDateTimeIndex(),
    userId: a9sjkll3,
    sessionID: Keen.helpers.getUniqueId()
  }
})

// and then:
client.getEventExtensions()
/* returns: 
{
         time: 12345134134,
         userId: a9sjkll3,
         sessionID: <random uuid>
}
*/

Build and test Keen.helpers

What does this do? These functions return objects with commonly used sets of properties. See: https://github.com/keen/keen-tracking.js#helpers for an initial list.

Todo:

  • Build initial set of helpers
  • Test initial set of helpers where reasonably possible for v1
Keen.helpers = {
    getBrowserProfile: function(){
        return {
            "cookies" : navigator.cookieEnabled,
            "screen"  : Keen.helpers.getScreenProperties(),
            "window"  : Keen.helpers.getWindowProperties()
            // and many more...
        };
    },
    getDatetimeIndex: function(obj){
        var date = obj || new Date();
        return {
            "hour-of-day"    : date.getHours(),
            "day-of-week"   : parseInt( 1 + date.getDay() ),
            "day-of-month" : date.getDate(),
            "month"            : parseInt( 1 + date.getMonth() ),
            "year"               : date.getFullYear()
        };
    },
    getDomEventProfile: function(e){
        return {
            "innerText": e.target.innerText,
            "path": Keen.helpers.getDomPath(e.target).join(' > '),
            "tagName": e.target.tagName,
            "title": e.target.title
            // and many more...
        };
    },
    getDomNodePath: function(el){
        // http://stackoverflow.com/a/16742828/2511985
        // returns something like "body > div#nav > ul > a#signup"
    },
    getScreenProperties: function(){
      // returns a curated screen profile
    },
    getWindowProperties: function(){
      // returns a curated window profile
    },
    getUniqueId: function(){
      // returns "f342s-3425423-dfsdfsdf12-123124fdvgdf"
    }
};

node utils.cookie is undefined

I try to set utils.cookie like your example in the Readme but I get the error

KeenTracking.utils.cookie is not a function

I am using it exactly like this

const express = require('express')
const app = express()
var KeenTracking = require('keen-tracking');

var client = new KeenTracking({
  projectId: 'x',
  writeKey: 'x'
});

const utils = KeenTracking.utils;

var sessionCookie = KeenTracking.utils.cookie('cookie-session-test')

It looks like cookie is not available.

recordDeferredEvents() sends queued events in bulk, but doesn't handle individual event errors

recordDeferredEvents() utilizes the bulk tracking function, but flushes the entire queue – if an individual event is malformed (or fails for any other reason), it is lost forever.

Current implementation for reference:

    self.recordEvents(currentQueue.events, function(err, res){
      if (err) {
        // Retry once
        self.recordEvents(currentQueue.events);
      }
      else {
        currentQueue = void 0;
      }
    });

A proposed solution would be to walk through the entries in the Keen response, and emit some sort of failure for each invalid event (so the developers can implement any sort of notification/handling they wish).

minor: inconsistent use of snake_case and camelCase in library

Hello!

Most of your documentation uses snake_case key names in events. The getDatetimeIndex() helper, and the ip_to_geo, ua_parser, and url_parser addons all add fields to the event with snake_cased names. However, the getScreenProfile() helper adds camelCased keys (colorDepth, availHeight, etc.) to the event. It's a minor thing, but it would be nice if there was one consistent casing used for documentation and keen-provided addons and helpers, so that when we're writing queries, we don't have to remember which casing applies to which keys. Thank you!

Cheers,
@felliott

Rules re: architecture?

Hey,

This is pretty cool! Might be able to help out here as I'm experimenting with some stuff on our own SDK.

Is it possible to setup a more firm structure around the following:

  • External libraries: e.g.are we able to use jQuery/Zepto/etc. or not?
  • Functions: a template for how we should create one of the proposed functions. (it can get pretty messy otherwise)
  • More clear goals of where you want to take this project (lots of possible overlap of where keen-js is/should be + common-web)

Nima

Queue still prevents process from exiting

The internal event queue used by client.defefEvent() and client.deferEvents() still prevents processes from exiting in NodeJS, because the default queueInterval is greater than 0. This hanging behavior was presumed to be fixed in the previous release, but the issue is still present for use cases where the queue is not actually used.

As a temporary workaround, the following setting will allow processes to exit properly:

const client = new Keen({ 
  /* Configure*/ 
});
client.queueInterval(0);

recordDeferredEvents() flushes the entire current queue, drops them completely recordEvents() fails twice

recordDeferredEvents() utilizes the bulk tracking function, but flushes the entire queue – if the XHR fails twice in a row, these events are lost forever. This is not ideal for clients with potential connectivity issues, such as mobile devices.

Current implementation for reference:

function recordDeferredEvents(){
  var self = this, currentQueue;
  if (self.queue.capacity > 0) {
    currentQueue = JSON.parse(JSON.stringify(self.queue));
    self.queue = queue();
    self.queue.options = currentQueue.options;

    self.emit('recordDeferredEvents', currentQueue.events);
    self.recordEvents(currentQueue.events, function(err, res){
      if (err) {
        // Retry once
        self.recordEvents(currentQueue.events);
      }
      else {
        currentQueue = void 0;
      }
    });
  }
  return self;
}

A proposed solution would be to add the events back into the queue upon 2x failures, rather than simply moving on.

Support HTTP rather than HTTPS

Looks like keen-core supports a 'protocol' option for clients, but keen-tracking enforces HTTPS even if the protocol is set to 'HTTP':

const client = new Keen({
  projectId: 'PROJECT_ID',
  writeKey: 'WRITE_KEY',
  host: 'localhost',
  protocol: 'http'
});

Can you add support for HTTP? Would be very useful for using the keen client against an internal proxy that might not support HTTPS.

initAutoTracking not setting user cookie

What did I do?
I include the code from the Readme in my page to enable autotracking.

What happens?
Each pageview creates a new user unique id. keen cookie is set to {}.

What do I expect to happen?
Cookie should be set once for each user, same unique id should be used for same user.

What I think is happening
Looking at the code for cookie.prototype.set, it doesn't seem to be handling the case where 3 arguments are passed in correctly.

Version 1.0.5 in the CDN

Hello,

The new version 1.0.5 doesn't seem to be available in a Keen CDN, or at least I haven't found any link to it (https://d26b395fwzu5fz.cloudfront.net/keen-tracking-1.0.5.min.js returns a 403 for instance).

Would be nice if the new version was available and the documentation updated in consequence.

Build top-level Keen settings and functions, utils

What does this do? The top-level Keen namespace will carry several sets of goodies that make robust event modeling super easy.

// Set debug to true to see console messages (if supported)
Keen.debug = false;
// Set enabled to false to disable event transmission
Keen.enabled = true;
// Used internally to log messages to the console
Keen.log( /* say something :) */ );
// Relocates current Keen namespace to a given variable and restores previous version
var K2 = Keen.noConflict();

Utilities:

Keen.utils.each(objectOrArray, function(item, indexOrKey){
});
Keen.utils.extend(primaryObject, objectToInherit);
Keen.utils.parseParams("?urlQueryString=true&value=123");

input with name of 'submit' generates error

this is an odd one :)

When using keen-tracking-1.4.0.js for general web tracking, an element of type submit with name of submit (<input name="submit" type="submit" value="Go">) generates following console error and then prevents form from submitting:

Uncaught TypeError: t.submit is not a function at keen-tracking-1.4.0.min.js:1

as a side note, if the name is Submit (note capital 'S') then it works fine.

Update Dev Workflow to Node v8.6

This project fails to start or run tests when running node versions beyond v6.

TypeError: Cannot read property 'prototype' of undefined
    at Object.<anonymous> (/Users/dustinlarimer/dev/keen/keen-tracking.js/node_modules/socket.io/lib/store.js:35:41)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)
    at Module.require (module.js:568:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/dustinlarimer/dev/keen/keen-tracking.js/node_modules/socket.io/lib/manager.js:16:13)
    at Module._compile (module.js:624:30)

This most likely means dependencies are out of date and need to be updated as well.

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.