@meetelise/chat 1.53.0 → 1.53.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/WebComponent/pubnub-message.d.ts +1 -0
- package/dist/src/googleReserve.d.ts +3 -0
- package/package.json +1 -1
- package/public/dist/index.js +45 -51
- package/src/WebComponent/Scheduler/tour-scheduler.ts +1 -0
- package/src/WebComponent/pubnub-message.ts +28 -14
- package/src/googleReserve.test.ts +10 -3
- package/src/googleReserve.ts +10 -2
- package/src/pubnub-message.test.ts +44 -0
|
@@ -780,6 +780,7 @@ export class TourScheduler extends LitElement {
|
|
|
780
780
|
).map((source) => snakify({ ...source })),
|
|
781
781
|
google_rwg_token: googleReferral?.rwgToken,
|
|
782
782
|
google_referral_building_id: googleReferral?.buildingId,
|
|
783
|
+
google_environment: googleReferral?.environment,
|
|
783
784
|
};
|
|
784
785
|
|
|
785
786
|
const url = `https://app.meetelise.com/platformApi/state/create/v2/scheduleMe`;
|
|
@@ -107,21 +107,25 @@ export class PubnubMessage extends LitElement {
|
|
|
107
107
|
const allWords = this.preserveHTMLTags(sanitizedLine);
|
|
108
108
|
if (!allWords) return html``;
|
|
109
109
|
return html`${allWords.map((word) => {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
const markedLinks = hyperlinks.filter((obj) =>
|
|
111
|
+
word.includes(obj.id)
|
|
112
|
+
);
|
|
113
|
+
if (markedLinks.length) {
|
|
114
|
+
// EliseAI made hyperlink, possibly inside markdown formatting like <b>
|
|
115
|
+
let wordWithLinks = word;
|
|
116
|
+
markedLinks.forEach((link) => {
|
|
117
|
+
imagesToDisplay.push({
|
|
118
|
+
redirectTo: link.link,
|
|
119
|
+
source: link.link,
|
|
120
|
+
});
|
|
121
|
+
wordWithLinks = wordWithLinks.replace(
|
|
122
|
+
link.id,
|
|
123
|
+
this.hyperlinkHTML(link.link, link.hyperlink)
|
|
124
|
+
);
|
|
117
125
|
});
|
|
118
|
-
return html
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
target="_blank"
|
|
122
|
-
rel="noopener noreferrer"
|
|
123
|
-
>${link?.hyperlink}
|
|
124
|
-
</a>`;
|
|
126
|
+
return html`${unsafeHTML(
|
|
127
|
+
DOMPurify.sanitize(wordWithLinks, { ADD_ATTR: ["target"] })
|
|
128
|
+
)} `;
|
|
125
129
|
}
|
|
126
130
|
if (urlRegex.test(word)) {
|
|
127
131
|
// general url
|
|
@@ -145,6 +149,16 @@ export class PubnubMessage extends LitElement {
|
|
|
145
149
|
});
|
|
146
150
|
}
|
|
147
151
|
|
|
152
|
+
private hyperlinkHTML(link: string, hyperlink: string): string {
|
|
153
|
+
const anchor = document.createElement("a");
|
|
154
|
+
anchor.className = "redirect-link";
|
|
155
|
+
anchor.href = link;
|
|
156
|
+
anchor.target = "_blank";
|
|
157
|
+
anchor.rel = "noopener noreferrer";
|
|
158
|
+
anchor.textContent = hyperlink;
|
|
159
|
+
return anchor.outerHTML;
|
|
160
|
+
}
|
|
161
|
+
|
|
148
162
|
private preserveHTMLTags(text: string): string[] {
|
|
149
163
|
const tagRegex = /(<\/?[a-z][^>]*>[^<]*<\/?[a-z]*>|[^\s]+[.,?!]?|\S)/gi;
|
|
150
164
|
const splitTags = text.match(tagRegex);
|
|
@@ -22,26 +22,33 @@ describe("Google Reserve", () => {
|
|
|
22
22
|
visit(originalSearch);
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
it("remembers a click from
|
|
26
|
-
visit("?elise_open=tour&rwg_token=AFd1x%3D%3D");
|
|
25
|
+
it("remembers a click from our Google feed, keeping the token intact", () => {
|
|
26
|
+
visit("?elise_open=tour&elise_google_env=production&rwg_token=AFd1x%3D%3D");
|
|
27
27
|
storeGoogleReserveReferral(7);
|
|
28
28
|
visit("");
|
|
29
29
|
|
|
30
30
|
expect(readGoogleReserveReferral()).to.include({
|
|
31
31
|
rwgToken: "AFd1x==",
|
|
32
|
+
environment: "production",
|
|
32
33
|
buildingId: 7,
|
|
33
34
|
});
|
|
34
35
|
});
|
|
35
36
|
|
|
36
|
-
it("has no referral without
|
|
37
|
+
it("has no referral without our feed's token or once it has expired", () => {
|
|
37
38
|
visit("?utm_source=website");
|
|
38
39
|
storeGoogleReserveReferral(7);
|
|
39
40
|
expect(readGoogleReserveReferral()).to.equal(null);
|
|
40
41
|
|
|
42
|
+
// Another integration's Google link.
|
|
43
|
+
visit("?rwg_token=AFd1x%3D%3D");
|
|
44
|
+
storeGoogleReserveReferral(7);
|
|
45
|
+
expect(readGoogleReserveReferral()).to.equal(null);
|
|
46
|
+
|
|
41
47
|
localStorage.setItem(
|
|
42
48
|
STORAGE_KEY,
|
|
43
49
|
JSON.stringify({
|
|
44
50
|
rwgToken: "AFd1x==",
|
|
51
|
+
environment: "production",
|
|
45
52
|
buildingId: 7,
|
|
46
53
|
expiresAt: Date.now() - 1,
|
|
47
54
|
})
|
package/src/googleReserve.ts
CHANGED
|
@@ -3,9 +3,12 @@ const REFERRAL_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
|
3
3
|
const REFERRAL_STORAGE_KEY = "com.eliseai.webchat.googlereserve.referral";
|
|
4
4
|
// Google "Book" links to a customer's page add this so the widget opens the tour scheduler.
|
|
5
5
|
const OPEN_PARAM = "elise_open";
|
|
6
|
+
// Our Google feed tags its links with the Actions Center environment.
|
|
7
|
+
const ENVIRONMENT_PARAM = "elise_google_env";
|
|
6
8
|
|
|
7
9
|
type GoogleReserveReferral = {
|
|
8
10
|
rwgToken: string;
|
|
11
|
+
environment: string;
|
|
9
12
|
buildingId: number;
|
|
10
13
|
expiresAt: number;
|
|
11
14
|
};
|
|
@@ -16,14 +19,19 @@ export const shouldOpenTourSchedulerFromUrl = (): boolean =>
|
|
|
16
19
|
/**
|
|
17
20
|
* Remembers a click from a building's Google listing, which arrives with an
|
|
18
21
|
* `rwg_token` query param, so a booking within 30 days can be reported back.
|
|
22
|
+
* Only links from our feed count: other integrations' links carry an
|
|
23
|
+
* `rwg_token` too.
|
|
19
24
|
*/
|
|
20
25
|
export const storeGoogleReserveReferral = (buildingId: number): void => {
|
|
21
|
-
const
|
|
22
|
-
|
|
26
|
+
const params = new URLSearchParams(window.location.search);
|
|
27
|
+
const rwgToken = params.get("rwg_token");
|
|
28
|
+
const environment = params.get(ENVIRONMENT_PARAM);
|
|
29
|
+
if (!rwgToken || !environment || !buildingId) {
|
|
23
30
|
return;
|
|
24
31
|
}
|
|
25
32
|
const referral: GoogleReserveReferral = {
|
|
26
33
|
rwgToken,
|
|
34
|
+
environment,
|
|
27
35
|
buildingId,
|
|
28
36
|
expiresAt: Date.now() + REFERRAL_TTL_MS,
|
|
29
37
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { expect } from "@esm-bundle/chai";
|
|
2
|
+
import "../public/dist/index";
|
|
3
|
+
import type { SimpleTextChatMessage } from "./MyPubnub";
|
|
4
|
+
import type { PubnubMessage } from "./WebComponent/pubnub-message";
|
|
5
|
+
|
|
6
|
+
declare const it: (name: string, callback: () => void | Promise<void>) => void;
|
|
7
|
+
|
|
8
|
+
const renderMessage = async (message: string): Promise<ShadowRoot> => {
|
|
9
|
+
const element = document.createElement("pubnub-message") as PubnubMessage;
|
|
10
|
+
element.message = {
|
|
11
|
+
timestamp: 100,
|
|
12
|
+
message,
|
|
13
|
+
isLeadMessage: false,
|
|
14
|
+
chunks: [{ text: message, order: 0, isDone: true }],
|
|
15
|
+
type: "text" as SimpleTextChatMessage["type"],
|
|
16
|
+
};
|
|
17
|
+
document.body.appendChild(element);
|
|
18
|
+
await element.updateComplete;
|
|
19
|
+
await element.updateComplete;
|
|
20
|
+
return element.shadowRoot as ShadowRoot;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
it("renders bolded and plain markdown links as links to the community", async () => {
|
|
24
|
+
const root = await renderMessage(
|
|
25
|
+
"- **[Alder House](https://www.clg-test.com/alder)** apartment 109\n" +
|
|
26
|
+
"- [Cedar Row](https://www.clg-test.com/cedar) apartment 103"
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const boldLink = root.querySelector("b a.redirect-link");
|
|
30
|
+
expect(boldLink?.getAttribute("href")).to.equal(
|
|
31
|
+
"https://www.clg-test.com/alder"
|
|
32
|
+
);
|
|
33
|
+
expect(boldLink?.getAttribute("target")).to.equal("_blank");
|
|
34
|
+
expect(boldLink?.textContent?.trim()).to.equal("Alder House");
|
|
35
|
+
|
|
36
|
+
const plainLink = Array.from(root.querySelectorAll("a.redirect-link")).find(
|
|
37
|
+
(anchor) => anchor.textContent?.trim() === "Cedar Row"
|
|
38
|
+
);
|
|
39
|
+
expect(plainLink?.getAttribute("href")).to.equal(
|
|
40
|
+
"https://www.clg-test.com/cedar"
|
|
41
|
+
);
|
|
42
|
+
expect(plainLink?.getAttribute("target")).to.equal("_blank");
|
|
43
|
+
expect(root.textContent).not.to.match(/[0-9a-f]{32}/);
|
|
44
|
+
});
|