-
Notifications
You must be signed in to change notification settings - Fork 85
Add destination mw #148
Add destination mw #148
Conversation
This bug meant that this code did not send an event with a userId=bar to segment.io. This change will result in this code sending an event with userId=bar to segment.io: f=function(payload, integration, next) { payload.obj.userId = "bar";next(payload); }; analytics.addIntegrationMiddleware(f); analytics.identify();
lib/analytics.js
Outdated
* @param {Function} Middleware | ||
* @return {Analytics} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach looks great! One minor comment.
lib/middleware.js
Outdated
this.applyMiddlewares = function(facade, integration, callback) { | ||
return apply( | ||
function(mw, payload, next) { | ||
mw({ payload, integration, next }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In modern JS you can do mw({ payload, integration, next });
. Unfortunately AJS is retro JS, so this needs to be
mw({
payload: payload,
integration: integration,
next: next,
});
) { | ||
var self = this; | ||
middlewares.forEach(function(middleware) { | ||
if (!self._destinationMiddlewares[integrationName]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could move this block on the method body instead:
var self = this;
var chain = self._destinationMiddlewares[integrationName]
if (!chain) {
chain = self._destinationMiddlewares[
integrationName
] = new DestinationMiddlewareChain();
}
middlewares.forEach(function(middleware) {
chain.add(middleware);
integration_name: integration.name | ||
}); | ||
|
||
integration.invoke.call(integration, method, result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should keeps things DRY and create an internal method for this:
// ...
this._invokeIntegration(method, integration, result)
})
} else {
this._invokeIntegration(method, integration, result)
// ...
Analytics.prototype._invokeIntegration = function (method, integration, payload) {
self.emit("invoke", payload)
metrics.increment("analytics_js.invoke", {
method: method,
})
metrics.increment("analytics_js.integration.invoke", {
method: method,
integration_name: integration.name,
})
integration.invoke.call(integration, method, payload)
}
result = new Facade(result); | ||
} | ||
|
||
self.emit('invoke', result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aultimus thinking more about this, we need to put this back outside in the place that it was before. Right now we are doing self.emit('invoke', result);
multiple times. Let's say the customer has enabled 10 integrations, we will emit the invoke
10 times ( and subsequently segment's own integration will record 10 events ). Right now the invoke
event seems to be integration agnostic (unlike the integration.invoke.call(integration, method, result);
call), therefore it should be triggered regardless of the destination middleware.
@aultimus did some testing on the the |
This reverts commit c515df7.
https://segment.atlassian.net/browse/LIBWEB-168
This pull request adds destination middleware to AJS and deprecates integration middleware. Destination middleware is similar to integration middleware, the key difference being in the interface for how it is added to AJS:
Destination Middleware:
addDestinationMiddleware(integrationName, middlewares)
Integration Middleware:
addIntegrationMiddleware(middleware)
Destination middleware only applies to the specific integration specified in the call to addDestinationMiddleware whereas integration middleware applies to all enabled integrations. The middlewares argument is an array which can contain one or many middlewares to add for this destination.
This is an example of adding a destination middleware that sets the username to 'foo' for the Segment.io destination:
Validation
run this code in the dev console of a source with this version of ajs core deployed, observe that the associated source will display userId of 'foobarcat' in the segment debugger.
Testing completed successfully on staging. ✅ https://www.dropbox.com/s/ptsmf68vtnuwxp2/stage_add_destination_mw.mov?dl=0
Checklist
Please ensure the following are completed to help get your PR merged:
Respect earns Respect 👏
Please respect our Code of Conduct, in short: