segmentio / analytics.js-integration Goto Github PK
View Code? Open in Web Editor NEWThe base integration factory used to create custom analytics integrations for analytics.js.
License: MIT License
The base integration factory used to create custom analytics integrations for analytics.js.
License: MIT License
some people are getting errors on ie8, i think the reason is that some browsers (ie) emits script complete|loaded
before the script is evaluated.
a simple solution would be to call .loaded()
after .load()
completed with no errors, and if .loaded()
returns false, we should retry X
times until Xms
and then error if .loaded()
still returns false.
what do you guys think ?
so when load is stubbed, it doesn't emit ready before the load callback occurs, which may be needed inside of an initialize function
and add ie7
There's a known vulnerability in [email protected]
https://nvd.nist.gov/vuln/detail/CVE-2018-16492
Updating to 3.0.2 should remove this vulnerability.
It would be great if this package could be updated as this is being flagged as a high vulnerability in my project.
so we can clean up this stuff:
afterEach(function() {
hellobar.reset();
var el = document.getElementById('hellobar_container');
if (el) el.parentNode.removeChild(el);
});
maybe
integration.selector('#hellobar_container')
or maybe it can figure it out from the .script(<tag>)
code
currently the package is not installable via NPM due to missing version number in package.json
"version": ""
returned error:
npm ERR! No version provided in package.json
when an integration assumes page view it original page()
will be called only if you call analytics.page()
twice.
not sure if that's a bug or required behavior...
/cc @ianstormtaylor
so we can stub out specifically the loading stuff, and at the same time make it possible to use the script names/information later.
script paths should include interpolation
Hey!
There is no version in the package.json file, so when trying to install this integration directly it errors out. Seems this is the same for most the integrations. Thanks!!!
@ianstormtaylor seem to still be getting that date error occasionally:
should we add this here?
var setTimeout = window.setTimeout;
var setInterval = window.setInterval;
var onerror = undefined;
var onload = undefined;
exports.reset = function(){
for (var i = 0, key; key = this.globals[i]; i++) window[key] = undefined;
window.setTimeout = setTimeout;
window.setInterval = setInterval;
window.onerror = onerror;
window.onload = onload;
};
if not here, where should we put this? didn't want to put it into analytics.js-integration-tester because sometimes you want to wait until multiple tests have run (at least for now). doesn't seem ideal to have to define this for each integration though, since we could just removing the .global
property?
Migrated from #12 by @CarlosMecha
Foo Foo Foo
Migrated from #12 by @CarlosMecha
Foo Foo Foo
sorry couldn't quite figure it out from the comments :)
https://github.com/segmentio/analytics.js-integration/blob/master/lib/statics.js#L54-L75
The .mapping
feature looks really awesome, but seems a bit hamstrung. As a consumer, I would expect to be able to map not only the event name (for a particular integration) but also the attributes for a given track call. For example, GTM is quite happy accepting a nested json structure of attributes; however, Optimizely cannot. So in order to send the "same" data to optimizely as GTM, the attribute structure must be mutated for one or the other (or both) of the integrations.
It would be fantastic if there were a feature like .mapping
but for attributes as well. Has there been any thought about this type of feature in the past? Any recommended alternatives? As best as I can tell, it would be presently implemented as a per-integration option. But having the capability to define it for all integrations would be fantastic.
Migrated from #12 by @CarlosMecha
Foo Foo Foo
such as storing all globals before, and after a script is loaded
Some random things that could potentially cleanup some repetitive code and simplify things for testing and whatnot.
First is what about removing the plugin code block? We can still figure out a way to make it pluggable without needing this:
/**
* Expose plugin.
*/
module.exports = exports = function(analytics){
analytics.addIntegration(AdRoll);
};
If the Integration
constructor just looked something like this, it would work too:
function Integration(opts) {
if (opts instanceof Analytics) return opts.addIntegration(Integration);
// ...
}
Then to handle the other couple things you find in those code blocks, such as this:
/**
* Expose plugin.
*/
module.exports = exports = function(analytics){
analytics.addIntegration(AdRoll);
ajs = analytics;
user = analytics.user(); // store for later
};
We could just set those as variables on every integration. That would make it much easier to test as well. Any reasons why we don't want to do that? That way you could just do this:
AdRoll.prototype.track = function(track){
var user = this.user;
var data = {};
if (user.id()) data.user_id = user.id();
// ...
};
Right now it feels hard to access and work with the user object, and it could be just this simple.
Also, we can potentially move all of those push
blocks to the DSL, and then make a .push
method on the integration prototype. So go from this:
var push = require('global-queue')('_curebitq');
// ...
Curebit.prototype.page = function(page){
// ...
push('register_affiliate', settings);
};
to something like this:
Curebit.queue('_curebitq');
// ...
Curebit.prototype.page = function(page){
// ...
this.push('register_affiliate', settings);
};
This would make it so we can use that information in the tests as well, and also for scraping pages. It would also kind of keep it consistent with the rest of the declarative definition.
So then integrations would start just looking like this:
/**
* Module dependencies.
*/
var integration = require('analytics.js-integration');
/**
* Expose `WebEngage` integration.
*/
var WebEngage = module.exports = integration('WebEngage')
.assumesPageview()
.global('_weq')
.global('webengage')
.option('widgetVersion', '4.0')
.option('licenseCode', '')
.tag('<script src="http://cdn.widgets.webengage.com/js/widget/webengage-min-v-4.0.js">');
/**
* Initialize.
*
* @param {Object} page
*/
WebEngage.prototype.initialize = function(page){
var _weq = window._weq = window._weq || {};
_weq['webengage.licenseCode'] = this.options.licenseCode;
_weq['webengage.widgetVersion'] = this.options.widgetVersion;
this.load(this.ready);
};
Thoughts?
Hi,
I have trouble completing a make
from a fresh clone. Here is what I get:
...[npm completed + other installed]...
installed : [email protected]
installed : [email protected]
installed : ianstormtaylor-sinon@duo
installed : [email protected]
installed : [email protected]
installed : [email protected]
error : Error: segmentio/stub@*: Not Found
Am I missing something?
Building from the latest tag (0.2.2
) instead of master
yields some other errors.
Thanks for your help,
@ianstormtaylor did we decide to go with this ?
here's how i think it should be implemented:
this lib receives track
calls with events, it will lowercase / normalize them and check for methods like checkedout
, removedProduct
, addedProduct
etc..
if the integration support those it will call them, otherwise it will fallback to just calling track.
since we don't want to do if (/removed product/i.test(track.event())) do()
inside every integration that supports ecommerce.
any thoughts ?
@ianstormtaylor segmentio/analytics.js-integrations#353
I think it used to not do the callback, but then with the changes we removed that. We could just do this:
exports.load = function(name, locals, fn){
if ('function' == typeof name) fn = name, locals = null, name = null;
if (name && 'object' == typeof name) fn = locals, locals = name, name = null;
if ('function' == typeof locals) fn = locals, locals = null;
name = name || 'library';
locals = locals || {};
locals = this.locals(locals);
var template = this.templates[name];
assert(template, fmt('Template "%s" not defined.', name));
var attrs = render(template, locals);
var el;
function done(err) {
if (err) return; // don't callback at all
fn();
}
switch (template.type) {
case 'img':
attrs.width = 1;
attrs.height = 1;
el = loadImage(attrs, done);
break;
case 'script':
el = loadScript(attrs, done);
// TODO: hack until refactoring load-script
delete attrs.src;
each(attrs, function(key, val){
el.setAttribute(key, val);
});
break;
case 'iframe':
el = loadIframe(attrs, done);
break;
}
return el;
};
But, we really only want this behavior for the global script, the main script for the app. So maybe we have a special load function for initializing? Not sure, what do you think is best?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.