Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Unreleased
## 19.3.4
New: the widget can switch the visitor to a contact after the "Verify email" workflow step confirmed their email (`adopt-session`). The SDK checks the handed-over session with the server first and never replaces a user your app identified.
New: custom actions from chat messages and message cards now pass their data to your `Gleap.registerCustomAction` callback as `data` (next to `name` and `shareToken`), with a Messenger that sends it. Callbacks that only read `name` keep working.

## 19.3.3
Expand Down
2 changes: 1 addition & 1 deletion build/browser/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/browser/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/cjs/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/cjs/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/esm/index.mjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/esm/index.mjs.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"description": "JavaScript and TypeScript SDK for Gleap, an Intercom alternative with AI customer support, live chat, in-app bug reporting and customer feedback.",
"name": "gleap",
"version": "19.3.3",
"version": "19.3.4",
"main": "build/cjs/index.js",
"module": "build/esm/index.mjs",
"exports": {
Expand Down
2 changes: 2 additions & 0 deletions published/19.3.4/index.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions published/19.3.4/index.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions published/19.3.4/survey-embed.js

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

2 changes: 1 addition & 1 deletion published/latest/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion published/latest/index.js.map

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions src/GleapFrameManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,8 @@ export default class GleapFrameManager {
apiUrl: GleapSession.getInstance().apiUrl,
realtimeHost: GleapSession.getInstance().realtimeHost,
sdkKey: GleapSession.getInstance().sdkKey,
// The widget may ask this SDK to switch sessions ("adopt-session").
capabilities: { adoptSession: true },
},
});
}
Expand Down Expand Up @@ -1217,6 +1219,12 @@ export default class GleapFrameManager {
this.hideWidget();
}

// A verified email moved the conversation to another contact: continue
// as that contact (the widget's "Verify email" workflow step).
if (data.name === 'adopt-session') {
GleapSession.getInstance().adoptSession(data.data);
}

if (data.name === 'set-widget-expanded') {
this.setWidgetExpanded(data.data && data.data.expanded);
}
Expand Down Expand Up @@ -1397,6 +1405,11 @@ export default class GleapFrameManager {
return;
}

// Only the Messenger frame may switch the session, never a banner.
if (data?.name === 'adopt-session' && !sourceMatchesGleapFrame && !originMatchesGleapFrame) {
return;
}

for (var i = 0; i < this.listeners.length; i++) {
if (this.listeners[i]) {
this.listeners[i](data);
Expand Down
44 changes: 44 additions & 0 deletions src/GleapSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,50 @@ export default class GleapSession {
);
};

/**
* Switches to another contact's session, handed over by the widget after a
* verified email (the "Verify email" workflow step). The server checks the
* gleapId/gleapHash pair; anything it refuses leaves the current session as
* it is. An app that identifies its users keeps its own identity.
*/
adoptSession = (data) => {
if (!data || typeof data.gleapId !== 'string' || typeof data.gleapHash !== 'string') {
return;
}
if (this.lastIdentify && this.lastIdentify.userId) {
return;
}
if (this.session && this.session.gleapId === data.gleapId) {
return;
}

const self = this;
const http = new XMLHttpRequest();
http.open('POST', self.apiUrl + '/sessions');
http.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
http.setRequestHeader('Api-Token', self.sdkKey);
http.setRequestHeader('Gleap-Id', data.gleapId);
http.setRequestHeader('Gleap-Hash', data.gleapHash);
http.onreadystatechange = function () {
if (http.readyState === 4 && (http.status === 200 || http.status === 201)) {
try {
const sessionData = JSON.parse(http.responseText);
if (sessionData && sessionData.gleapId === data.gleapId) {
self.contactVersion++;
self.validateSession(sessionData);
}
} catch (exp) {}
}
};
http.send(
JSON.stringify({
lang: GleapTranslationManager.getInstance().getActiveLanguage(),
deviceType: getDeviceType(),
platform: 'web',
})
);
};

notifySessionReady() {
if (this.onSessionReadyListener.length > 0) {
for (var i = 0; i < this.onSessionReadyListener.length; i++) {
Expand Down
Loading