Skip to content

Commit

Permalink
Jimo action destination (#2164)
Browse files Browse the repository at this point in the history
* feat(Jimo/Settings): add refetchExperiencesOnTraitsUpdate

* fix(Jimo/SendUserData): use identify instead of user:id and add new setting refetchExperiencesOnTraitsUpdate

* fix(Jimo/Tests): fix & add test for experience refetching
  • Loading branch information
imsamdez authored Jul 16, 2024
1 parent 476d5ba commit 2009c64
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 9 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions packages/browser-destinations/destinations/jimo/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ export const destination: BrowserDestinationDefinition<Settings, JimoSDK> = {
label: 'Id',
type: 'string',
required: true
},
refetchExperiencesOnTraitsUpdate: {
description:
"Enable this option if you'd like Jimo to refetch experiences supposed to be shown to the user after user traits get updated. This is useful when if you have experiences that use segment based on Segment traits.",
label: 'Refetch experiences after traits changes',
type: 'boolean',
default: false
}
},
presets: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,32 @@ describe('Jimo - Send User Data', () => {
})

expect(client.push).toHaveBeenCalled()
expect(client.push).toHaveBeenCalledWith(['set', 'user:id', ['u1']])
expect(client.push).toHaveBeenCalledWith(['do', 'identify', ['u1', expect.any(Function)]])
})
test('user id then email and attributes', async () => {
const client = {
push: jest.fn()
} as any as JimoSDK

const context = new Context({
type: 'identify'
})

await sendUserData.perform(client as any as JimoSDK, {
settings: { projectId: 'unk' },
analytics: jest.fn() as any as Analytics,
context: context,
payload: {
userId: 'u1',
email: 'john@doe.com',
traits: {
foo: 'bar'
}
} as Payload
})

expect(client.push).toHaveBeenCalled()
expect(client.push).toHaveBeenCalledWith(['do', 'identify', ['u1', expect.any(Function)]])
})
test('user email', async () => {
const client = {
Expand Down Expand Up @@ -84,4 +109,41 @@ describe('Jimo - Send User Data', () => {
]
])
})
test('user traits with experience refetching', async () => {
const client = {
push: jest.fn()
} as any as JimoSDK

const context = new Context({
type: 'identify'
})

await sendUserData.perform(client as any as JimoSDK, {
settings: { projectId: 'unk', refetchExperiencesOnTraitsUpdate: true },
analytics: jest.fn() as any as Analytics,
context: context,
payload: {
traits: {
trait1: true,
trait2: 'foo',
trait3: 1
}
} as Payload
})

expect(client.push).toHaveBeenCalled()
expect(client.push).toHaveBeenCalledWith([
'set',
'user:attributes',
[
{
trait1: true,
trait2: 'foo',
trait3: 1
},
true,
true
]
])
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,38 @@ const action: BrowserActionDefinition<Settings, JimoSDK, Payload> = {
}
},
defaultSubscription: 'type = "identify"',
perform: (jimo, { payload }) => {
if (payload.userId != null) {
perform: (jimo, { payload, settings }) => {
const pushEmail = () => {
if (payload.email == null) return
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
jimo.push(['set', 'user:id', [payload.userId]])
jimo.push(['set', 'user:email', [payload.email]])
}
if (payload.email != null) {
const pushTraits = () => {
if (payload.traits == null) return
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
jimo.push(['set', 'user:email', [payload.email]])
jimo.push(['set', 'user:attributes', [payload.traits, settings.refetchExperiencesOnTraitsUpdate ?? false, true]])
}
if (payload.traits != null) {

// If a userId is passed, we need to make sure email and attributes changes only happen in the
// after the identify flow is done, that's why we pass it as a callback of the identify method
if (payload.userId != null) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
jimo.push(['set', 'user:attributes', [payload.traits, false, true]])
jimo.push([
'do',
'identify',
[
payload.userId,
() => {
pushEmail()
pushTraits()
}
]
])
}
// If no user id passed, there is no identify flow trigger, we can just execute the methods directly
else {
pushEmail()
pushTraits()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export interface JimoSDK {
push: (params: Array<string | (string | { [k: string]: unknown } | boolean)[]>) => Promise<void>
push: (params: Array<string | (string | { [k: string]: unknown } | boolean | Function)[]>) => Promise<void>
}

0 comments on commit 2009c64

Please sign in to comment.