Skip to content

Commit a034c21

Browse files
feat: onboard new destination commandbar (#1610)
* feat: onboard new destination commandbar * fix: change isLoaded return statement
1 parent ed862ba commit a034c21

File tree

11 files changed

+315
-2
lines changed

11 files changed

+315
-2
lines changed

packages/analytics-js-common/src/constants/destDisplayNamesToFileNamesMap.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ import {
152152
SprigDirectoryName,
153153
SpotifyPixelDisplayName,
154154
SpotifyPixelDirectoryName,
155+
CommandBarDisplayName,
156+
CommandBarDirectoryName,
155157
} from './destinationNames';
156158

157159
// The destination directory name is used as the destination SDK file name in CDN
@@ -231,7 +233,8 @@ const destDisplayNamesToFileNamesMap: Record<string, string> = {
231233
[TiktokAdsDisplayName]: TiktokAdsDirectoryName,
232234
[ActiveCampaignDisplayName]: ActiveCampaignDirectoryName,
233235
[SprigDisplayName]: SprigDirectoryName,
234-
[SpotifyPixelDisplayName] : SpotifyPixelDirectoryName
236+
[SpotifyPixelDisplayName]: SpotifyPixelDirectoryName,
237+
[CommandBarDisplayName]: CommandBarDirectoryName,
235238
};
236239

237240
export { destDisplayNamesToFileNamesMap };

packages/analytics-js-common/src/constants/destinationNames.ts

+4
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,7 @@ export {
302302
DISPLAY_NAME as SpotifyPixelDisplayName,
303303
DIR_NAME as SpotifyPixelDirectoryName,
304304
} from './integrations/SpotifyPixel/constants';
305+
export {
306+
DISPLAY_NAME as CommandBarDisplayName,
307+
DIR_NAME as CommandBarDirectoryName,
308+
} from './integrations/CommandBar/constants';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const DIR_NAME = 'CommandBar';
2+
const NAME = 'COMMANDBAR';
3+
const DISPLAY_NAME = 'CommandBar';
4+
5+
const DISPLAY_NAME_TO_DIR_NAME_MAP = { [DISPLAY_NAME]: DIR_NAME };
6+
const CNameMapping = {
7+
[NAME]: NAME,
8+
'Command Bar': NAME,
9+
'Commandbar': NAME,
10+
COMMAND_BAR: NAME,
11+
commandbar: NAME,
12+
};
13+
14+
export {
15+
NAME,
16+
CNameMapping,
17+
DISPLAY_NAME_TO_DIR_NAME_MAP,
18+
DISPLAY_NAME,
19+
DIR_NAME,
20+
};
21+

packages/analytics-js-common/src/v1.1/utils/client_server_name.js

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ const clientToServerNames = {
7575
ACTIVE_CAMPAIGN: 'ActiveCampaign',
7676
SPRIG: 'Sprig',
7777
SPOTIFYPIXEL:'Spotify Pixel',
78+
COMMANDBAR:'CommandBar',
7879
};
7980

8081
export { clientToServerNames };

packages/analytics-js-common/src/v1.1/utils/config_to_integration_names.js

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ const configToIntNames = {
7676
ACTIVE_CAMPAIGN: 'ActiveCampaign',
7777
SPRIG: 'Sprig',
7878
SPOTIFYPIXEL: 'SpotifyPixel',
79+
COMMANDBAR: 'CommandBar',
7980
};
8081

8182
export { configToIntNames };

packages/analytics-js-common/src/v1.1/utils/integration_cname.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ import { CNameMapping as TiktokAds } from '../../constants/integrations/TiktokAd
7474
import { CNameMapping as ActiveCampaign } from '../../constants/integrations/ActiveCampaign/constants';
7575
import { CNameMapping as Sprig } from '../../constants/integrations/Sprig/constants';
7676
import { CNameMapping as SpotifyPixel } from '../../constants/integrations/SpotifyPixel/constants';
77+
import { CNameMapping as CommandBar } from '../../constants/integrations/CommandBar/constants';
7778
// for sdk side native integration identification
7879
// add a mapping from common names to index.js exported key names as identified by Rudder
7980
const commonNames = {
@@ -84,6 +85,7 @@ const commonNames = {
8485
...BingAds,
8586
...Braze,
8687
...Bugsnag,
88+
...CommandBar,
8789
...Chartbeat,
8890
...Clevertap,
8991
...Comscore,
@@ -153,7 +155,7 @@ const commonNames = {
153155
...TiktokAds,
154156
...ActiveCampaign,
155157
...Sprig,
156-
...SpotifyPixel
158+
...SpotifyPixel,
157159
};
158160

159161
export { commonNames };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import CommandBar from '../../../src/integrations/CommandBar/browser';
2+
3+
afterAll(() => {
4+
jest.restoreAllMocks();
5+
});
6+
const destinationInfo = {
7+
areTransformationsConnected: false,
8+
destinationId: 'sample-destination-id',
9+
};
10+
11+
describe('CommandBar init tests', () => {
12+
let Commandbar;
13+
14+
test('Testing init call of CommandBar', () => {
15+
Commandbar = new CommandBar({ orgId: '12567839' }, { loglevel: 'debug' }, destinationInfo);
16+
Commandbar.init();
17+
expect(typeof window.CommandBar).toBe('object');
18+
});
19+
});
20+
21+
describe('CommandBar Track event', () => {
22+
let Commandbar;
23+
Commandbar = new CommandBar({ orgId: '12567839' }, { loglevel: 'debug' }, destinationInfo);
24+
Commandbar.init();
25+
window.CommandBar.trackEvent = jest.fn();
26+
test('Testing Track Events', () => {
27+
Commandbar.track({
28+
message: {
29+
context: {},
30+
event: 'dummyEventName',
31+
properties: {
32+
customProp: 'testProp',
33+
},
34+
},
35+
});
36+
expect(window.CommandBar.trackEvent.mock.calls[0][0]).toEqual('dummyEventName');
37+
expect(window.CommandBar.trackEvent.mock.calls[0][1]).toEqual({});
38+
});
39+
});
40+
describe('CommandBar Identify event', () => {
41+
let Commandbar;
42+
Commandbar = new CommandBar({ orgId: '12567839' }, { loglevel: 'debug' }, destinationInfo);
43+
Commandbar.init();
44+
window.CommandBar.boot = jest.fn();
45+
test('Testing Identify sending traits in context and hmacId as well', () => {
46+
Commandbar.identify({
47+
message: {
48+
userId: 'rudder01',
49+
context: {
50+
traits: {
51+
52+
isRudderEvents: true,
53+
hmacId: 'hmacUserId',
54+
},
55+
},
56+
},
57+
});
58+
expect(window.CommandBar.boot.mock.calls[0][0]).toEqual('rudder01');
59+
expect(window.CommandBar.boot.mock.calls[0][1]).toEqual({
60+
61+
isRudderEvents: true,
62+
});
63+
expect(window.CommandBar.boot.mock.calls[0][2]).toEqual({
64+
hmac: 'hmacUserId',
65+
});
66+
});
67+
test('Testing Identify sending traits in message and hmacId in traits.context ', () => {
68+
Commandbar.identify({
69+
message: {
70+
userId: 'rudder01',
71+
context: {
72+
traits: {
73+
74+
isRudderEvents: true,
75+
},
76+
},
77+
traits: {
78+
hmacId: 'hmacUserId',
79+
},
80+
},
81+
});
82+
expect(window.CommandBar.boot.mock.calls[0][0]).toEqual('rudder01');
83+
expect(window.CommandBar.boot.mock.calls[0][1]).toEqual({
84+
85+
isRudderEvents: true,
86+
});
87+
expect(window.CommandBar.boot.mock.calls[0][2]).toEqual({
88+
hmac: 'hmacUserId',
89+
});
90+
});
91+
test('Testing Identify no traits or hmacId passed ', () => {
92+
Commandbar.identify({
93+
message: {
94+
userId: 'rudder01',
95+
context: {
96+
traits: {
97+
98+
isRudderEvents: true,
99+
},
100+
},
101+
traits: {
102+
hmacId: 'hmacUserId',
103+
},
104+
},
105+
});
106+
expect(window.CommandBar.boot.mock.calls[0][0]).toEqual('rudder01');
107+
expect(window.CommandBar.boot.mock.calls[0][1]).toEqual({
108+
109+
isRudderEvents: true,
110+
});
111+
expect(window.CommandBar.boot.mock.calls[0][2]).toEqual({
112+
hmac: 'hmacUserId',
113+
});
114+
});
115+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* eslint-disable class-methods-use-this */
2+
import {
3+
NAME,
4+
DISPLAY_NAME,
5+
} from '@rudderstack/analytics-js-common/constants/integrations/CommandBar/constants';
6+
import Logger from '../../utils/logger';
7+
import { loadNativeSdk } from './nativeSdkLoader';
8+
9+
const logger = new Logger(DISPLAY_NAME);
10+
11+
class CommandBar {
12+
constructor(config, analytics, destinationInfo) {
13+
if (analytics.logLevel) {
14+
logger.setLogLevel(analytics.logLevel);
15+
}
16+
this.analytics = analytics;
17+
this.orgId = config.orgId;
18+
this.name = NAME;
19+
({
20+
shouldApplyDeviceModeTransformation: this.shouldApplyDeviceModeTransformation,
21+
propagateEventsUntransformedOnError: this.propagateEventsUntransformedOnError,
22+
destinationId: this.destinationId,
23+
} = destinationInfo ?? {});
24+
}
25+
26+
init() {
27+
loadNativeSdk(this.orgId);
28+
}
29+
30+
isLoaded() {
31+
return window.CommandBar && typeof window.CommandBar.shareState === 'function';
32+
}
33+
34+
isReady() {
35+
return this.isLoaded();
36+
}
37+
38+
/**
39+
* Idenitfies a user with userId and traits
40+
* Commandbar doc: https://www.commandbar.com/docs/sdk/lifecycle/boot/
41+
* @param {*} rudderElement
42+
* @returns
43+
*/
44+
identify(rudderElement) {
45+
const { message } = rudderElement;
46+
const { traits, userId, context } = message;
47+
const userTraits = { ...context.traits, ...traits };
48+
const { hmacId } = userTraits;
49+
if (!userId) {
50+
logger.error('userId from identify call is missing');
51+
return;
52+
}
53+
54+
const instanceAttributes = {}; // stores commandBar options associated with the current session.
55+
56+
if (hmacId) {
57+
instanceAttributes.hmac = hmacId;
58+
delete userTraits.hmacId;
59+
}
60+
window.CommandBar.boot(userId, userTraits, instanceAttributes);
61+
}
62+
/**
63+
* ref: https://www.commandbar.com/docs/sdk/events/trackevent/
64+
* Track - tracks an event for an user
65+
* @param {Track} track
66+
*/
67+
track(rudderElement) {
68+
const { message } = rudderElement;
69+
const { event } = message;
70+
if (!event) {
71+
logger.error('event name from track call is missing');
72+
return;
73+
}
74+
window.CommandBar.trackEvent(event, {});
75+
}
76+
}
77+
78+
export default CommandBar;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as CommandBar } from './browser';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { LOAD_ORIGIN } from '@rudderstack/analytics-js-common/v1.1/utils/constants';
2+
3+
function loadNativeSdk(orgId) {
4+
var o = orgId,
5+
n = ['Object.assign', 'Symbol', 'Symbol.for'].join('%2C'),
6+
a = window;
7+
function r(o, n) {
8+
void 0 === n && (n = !1),
9+
'complete' !== document.readyState &&
10+
window.addEventListener('load', r.bind(null, o, n), { capture: !1, once: !0 });
11+
var a = document.createElement('script');
12+
a.setAttribute('data-loader', LOAD_ORIGIN);
13+
(a.type = 'text/javascript'), (a.async = n), (a.src = o), document.head.appendChild(a);
14+
}
15+
function t() {
16+
var n;
17+
if (void 0 === a.CommandBar) {
18+
delete a.__CommandBarBootstrap__;
19+
var t = Symbol.for('CommandBar::configuration'),
20+
e = Symbol.for('CommandBar::orgConfig'),
21+
i = Symbol.for('CommandBar::disposed'),
22+
c = Symbol.for('CommandBar::isProxy'),
23+
m = Symbol.for('CommandBar::queue'),
24+
d = Symbol.for('CommandBar::unwrap'),
25+
l = Symbol.for('CommandBar::eventSubscriptions'),
26+
s = [],
27+
u = localStorage.getItem('commandbar.lc'),
28+
f = u && u.includes('local') ? 'http://localhost:8000' : 'https://api.commandbar.com',
29+
p = Object.assign(
30+
(((n = {})[t] = { uuid: o }),
31+
(n[e] = {}),
32+
(n[i] = !1),
33+
(n[c] = !0),
34+
(n[m] = new Array()),
35+
(n[d] = function () {
36+
return p;
37+
}),
38+
(n[l] = void 0),
39+
n),
40+
a.CommandBar,
41+
),
42+
b = ['addCommand', 'boot', 'addEventSubscriber', 'addRecordAction', 'setFormFactor'],
43+
y = p;
44+
Object.assign(p, {
45+
shareCallbacks: function () {
46+
return {};
47+
},
48+
shareContext: function () {
49+
return {};
50+
},
51+
}),
52+
(a.CommandBar = new Proxy(p, {
53+
get: function (o, n) {
54+
return n in y
55+
? p[n]
56+
: 'then' !== n
57+
? b.includes(n)
58+
? function () {
59+
var o = Array.prototype.slice.call(arguments);
60+
return new Promise(function (a, r) {
61+
o.unshift(n, a, r), p[m].push(o);
62+
});
63+
}
64+
: function () {
65+
var o = Array.prototype.slice.call(arguments);
66+
o.unshift(n), p[m].push(o);
67+
}
68+
: void 0;
69+
},
70+
})),
71+
null !== u && s.push('lc='.concat(u)),
72+
s.push('version=2'),
73+
r(''.concat(f, '/latest/').concat(o, '?').concat(s.join('&')), !0);
74+
}
75+
}
76+
void 0 === Object.assign || 'undefined' == typeof Symbol || void 0 === Symbol.for
77+
? ((a.__CommandBarBootstrap__ = t),
78+
r(
79+
'https://polyfill.io/v3/polyfill.min.js?version=3.101.0&callback=__CommandBarBootstrap__&features=' +
80+
n,
81+
))
82+
: t();
83+
}
84+
85+
export { loadNativeSdk };

packages/analytics-js-integrations/src/integrations/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ import * as TiktokAds from './TiktokAds';
7474
import * as ActiveCampaign from './ActiveCampaign';
7575
import * as Sprig from './Sprig';
7676
import * as SpotifyPixel from './SpotifyPixel';
77+
import * as CommandBar from './CommandBar';
7778
// the key names should match the destination.name value to keep parity everywhere
7879
// (config-plan name, native destination.name , exported integration name(this one below))
7980

@@ -88,6 +89,7 @@ const integrations = {
8889
CLEVERTAP: Clevertap.default,
8990
COMSCORE: Comscore.default,
9091
CRITEO: Criteo.default,
92+
COMMANDBAR: CommandBar.default,
9193
CUSTOMERIO: CustomerIO.default,
9294
DCM_FLOODLIGHT: DCMFloodlight.default,
9395
DRIP: Drip.default,

0 commit comments

Comments
 (0)