Skip to content

Commit c14d5e4

Browse files
committed
alpha
1 parent 00d7d45 commit c14d5e4

26 files changed

+813
-286
lines changed

components/drift/actions/create-contact/create-contact.mjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "drift-create-contact-test",
66
name: "Create Contact",
77
description: "Creates a contact in Drift. [See the docs](https://devdocs.drift.com/docs/creating-a-contact).",
8-
version: "0.0.10",
8+
version: "0.0.11",
99
type: "action",
1010
props: {
1111
drift,
@@ -26,6 +26,12 @@ export default {
2626
description: "The contact's phone number",
2727
optional: true,
2828
},
29+
source: {
30+
type: "string",
31+
label: "Lead Source",
32+
description: "The value of the 'lead_create_source' custom attribute to match (case-sensitive).",
33+
optional: true,
34+
},
2935
customAttributes: {
3036
type: "object",
3137
label: "Custom Attributes",
@@ -39,7 +45,7 @@ export default {
3945
const warnings = [];
4046

4147
const {
42-
drift, email, name, phone,
48+
drift, email, name, phone, source,
4349
} = this;
4450

4551
warnings.push(...drift.checkIfEmailValid(email));
@@ -50,6 +56,7 @@ export default {
5056
email,
5157
name,
5258
phone,
59+
source,
5360
...customAttributes,
5461
});
5562

components/drift/actions/update-contact/update-contact.mjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "drift-update-contact",
66
name: "Update Contact",
77
description: "Updates a contact in Drift using ID or email. Only changed attributes will be updated. [See Drift API docs](https://devdocs.drift.com/docs/updating-a-contact)",
8-
version: "0.0.5",
8+
version: "0.0.7",
99
type: "action",
1010
props: {
1111
drift,
@@ -32,6 +32,12 @@ export default {
3232
description: "The contact’s phone number.",
3333
optional: true,
3434
},
35+
source: {
36+
type: "string",
37+
label: "Lead Source",
38+
description: "The value of the 'lead_create_source' custom attribute to match (case-sensitive).",
39+
optional: true,
40+
},
3541
customAttributes: {
3642
type: "object",
3743
label: "Custom Attributes",
@@ -43,7 +49,7 @@ export default {
4349
async run({ $ }) {
4450
const warnings = [];
4551
const {
46-
drift, name, email, phone,
52+
drift, name, email, phone, source,
4753
} = this;
4854

4955
const customAttributes = drift.parseIfJSONString(this.customAttributes);
@@ -52,6 +58,7 @@ export default {
5258
name,
5359
phone,
5460
email,
61+
source,
5562
...customAttributes,
5663
});
5764

components/drift/common/utils.mjs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
const removeNullEntries = (obj) =>
2-
obj && Object.entries(obj).reduce((acc, [
3-
key,
4-
value,
5-
]) => {
6-
const isNumber = typeof value === "number";
7-
const isBoolean = typeof value === "boolean";
8-
const isNotEmpyString = typeof value === "string" && value.trim() !== "";
9-
const isNotEmptyArray = Array.isArray(value) && value.length;
10-
const isNotEmptyObject =
2+
obj && Object.entries(obj).reduce((acc, [
3+
key,
4+
value,
5+
]) => {
6+
const isNumber = typeof value === "number";
7+
const isBoolean = typeof value === "boolean";
8+
const isNotEmpyString = typeof value === "string" && value.trim() !== "";
9+
const isNotEmptyArray = Array.isArray(value) && value.length;
10+
const isNotEmptyObject =
1111
typeof value === "object" &&
1212
value !== null &&
1313
!Array.isArray(value) &&
1414
Object.keys(value).length !== 0;
15-
isNotEmptyObject && (value = removeNullEntries(value));
16-
return ((value || value === false) &&
15+
isNotEmptyObject && (value = removeNullEntries(value));
16+
return ((value || value === false) &&
1717
(isNotEmpyString || isNotEmptyArray || isNotEmptyObject || isBoolean || isNumber))
18-
? {
19-
...acc,
20-
[key]: value,
21-
}
22-
: acc;
23-
}, {});
24-
25-
export {
26-
removeNullEntries,
27-
};
28-
18+
? {
19+
...acc,
20+
[key]: value,
21+
}
22+
: acc;
23+
}, {});
24+
25+
export {
26+
removeNullEntries,
27+
};

components/drift/drift.app.mjs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ export default {
77
propDefinitions: {},
88
methods: {
99
...methods,
10+
_mock$() {
11+
return new Proxy({}, {
12+
get() {
13+
return (...args) => console.log(...args);
14+
},
15+
});
16+
},
1017
_baseUrl() {
1118
return "https://driftapi.com";
1219
},
@@ -30,6 +37,16 @@ export default {
3037
});
3138
},
3239

40+
getNextPage($, url) {
41+
return axios($, {
42+
method: "GET",
43+
url,
44+
headers: {
45+
"Authorization": `Bearer ${this.$auth?.oauth_access_token || "iHlC8LmFQiTH0DcWds7ETMRMmo3BvUyP"}`,
46+
},
47+
});
48+
},
49+
3350
getContactByEmail(opts) {
3451
return this._makeRequest({
3552
path: "/contacts",
@@ -111,5 +128,13 @@ export default {
111128

112129
return response;
113130
},
131+
132+
getNewestConversations(arr, lastKnown) {
133+
const firtsNew = arr.indexOf(lastKnown);
134+
if (firtsNew === -1) throw new Error("Id not found");
135+
const newest = arr.slice(0, firtsNew);
136+
return newest.reverse();
137+
},
138+
114139
},
115140
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import drift from "../../drift.app.mjs";
2+
3+
export default {
4+
key: "drift-new-contact-update-test",
5+
name: "New Contact Update",
6+
description: "Emit new event when a contact is updated in Drift. [See the docs](https://devdocs.drift.com/docs/webhook-events-1).",
7+
version: "0.0.1",
8+
type: "source",
9+
props: {
10+
drift,
11+
http: "$.interface.http",
12+
},
13+
async run(event) {
14+
15+
const { body } = event;
16+
17+
if (body?.type !== "contact_updated") {
18+
console.log("Ignored non-contact_updated event:", body?.type);
19+
return;
20+
}
21+
22+
const contactId = body.data.endUserId;
23+
24+
const result = await this.drift.getContactById({
25+
contactId,
26+
});
27+
28+
const email = result.data.attributes.email;
29+
30+
body.data.attributes = result.data.attributes;
31+
32+
console.log(body);
33+
34+
console.log("Contact updated webhook payload:", body);
35+
36+
this.$emit(body, {
37+
summary: `Contact "${email}" ID "${contactId}" updated`,
38+
id: body.data.endUserId,
39+
ts: body.timeStamp,
40+
});
41+
},
42+
};
Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import drift from "../../drift.app.mjs";
22

33
export default {
4-
key: "drift-new-conversation-instant",
4+
key: "drift-new-conversation-instant-test",
55
name: "New Conversation",
6-
description: "Emits an event every time a new conversation is started in Drift.",
6+
description: "Emit new when a new conversation is started in Drift.",
77
version: "0.0.2",
88
type: "source",
99
dedupe: "unique",
@@ -13,44 +13,97 @@ export default {
1313
timer: {
1414
type: "$.interface.timer",
1515
label: "Polling Interval",
16-
description: "How often to poll Drift for new conversations.",
16+
description: "How often to poll Drift for new conversations. [See the docs](https://devdocs.drift.com/docs/retrieve-a-conversation)",
1717
},
18-
limit: {
19-
type: "integer",
20-
label: "Maximum Conversations to Fetch",
21-
description: "The number of most recent conversations to retrieve each time the source runs.",
22-
default: 50,
23-
optional: true,
24-
min: 1,
25-
max: 500,
18+
},
19+
hooks: {
20+
async activate() {
21+
22+
const {
23+
drift,
24+
db,
25+
} = this;
26+
27+
await db.set("lastConversation", null); //reset
28+
29+
const result = await drift._makeRequest({
30+
path: "/conversations/list?limit=100&statusId=1",
31+
});
32+
33+
if (!result.data.length) {
34+
console.log("No conversations found.");
35+
return;
36+
};
37+
38+
await db.set("lastConversation", result.data[0].id);
39+
console.log(`Initialized with ID ${result.data[0].id}.`);
40+
41+
console.log("here");
42+
2643
},
2744
},
2845

2946
async run({ $ }) {
30-
const lastTimestamp = this.db.get("lastCreatedAt") || 0;
47+
const {
48+
db, drift,
49+
} = this;
3150

32-
const res = await this.drift._makeRequest({
51+
const conversations = [];
52+
53+
const result = await drift._makeRequest({
3354
$,
34-
path: `/conversations?limit=${this.limit}&sort=createdAt`,
55+
path: "/conversations/list?limit=100&statusId=1",
3556
});
3657

37-
const conversations = res?.data || [];
58+
if (!result.data.length) {
59+
console.log("No conversations found.");
60+
return;
61+
};
62+
63+
const lastConversation = await db.get("lastConversation");
64+
65+
if (!lastConversation) {
66+
await db.set("lastConversation", result.data[0].id);
67+
console.log(`Initialized with ID ${result.data[0].id}.`);
68+
return;
69+
};
70+
71+
let isEnough = result.data.some((obj) => obj.id === lastConversation);
72+
73+
conversations.push(...result.data);
74+
75+
let nextUrl = result.links?.next;
76+
77+
while (!isEnough && nextUrl) {
78+
const next = await drift.getNextPage($, nextUrl);
79+
isEnough = next.data.some((obj) => obj.id === lastConversation);
80+
conversations.push(...next.data);
81+
nextUrl = next.links?.next;
82+
};
83+
84+
conversations.sort((a, b) => a.id - b.id);
85+
86+
const lastConvIndex = conversations.findIndex((obj) => obj.id === lastConversation);
87+
88+
if (lastConvIndex === -1) {
89+
throw new Error ("lastConversation not found in fetched data. Skipping emit.");
90+
};
91+
92+
if (lastConvIndex + 1 === conversations.length) {
93+
console.log("No new conversations found");
94+
};
3895

39-
for (const conversation of conversations) {
40-
const createdAt = conversation.createdAt || 0;
96+
for (let i = lastConvIndex + 1; i < conversations.length; i++) {
4197

42-
if (createdAt > lastTimestamp) {
43-
this.$emit(conversation, {
44-
id: conversation.id,
45-
summary: `New conversation with ID ${conversation.id}`,
46-
ts: createdAt,
47-
});
48-
}
49-
}
98+
this.$emit(conversations[i], {
99+
id: conversations[i].id,
100+
summary: `New conversation with ID ${conversations[i].contactId}`,
101+
ts: conversations[i].createdAt,
102+
});
50103

51-
const newest = conversations.reduce((max, c) =>
52-
Math.max(max, c.createdAt || 0), lastTimestamp);
104+
};
53105

54-
this.db.set("lastCreatedAt", newest);
106+
const lastConvId = conversations[conversations.length - 1].id;
107+
await db.set("lastConversation", lastConvId);
55108
},
56109
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import drift from "../../drift.app.mjs";
2+
3+
export default {
4+
key: "drift-new-lead-instance-test",
5+
name: "New Lead",
6+
description: "Emit new event when a contact adds their email in chat. [See the docs](https://devdocs.drift.com/docs/webhook-events-1).",
7+
version: "0.0.1",
8+
type: "source",
9+
props: {
10+
drift,
11+
http: "$.interface.http",
12+
},
13+
async run(event) {
14+
15+
const { body } = event;
16+
17+
if (body?.type !== "contact_identified") {
18+
console.log("Ignored non-contact_identified event:", body?.type);
19+
return;
20+
}
21+
22+
const contactId = body.data.endUserId;
23+
24+
const result = await this.drift.getContactById({
25+
contactId,
26+
});
27+
28+
const email = result.data.attributes.email;
29+
30+
body.data.attributes = result.data.attributes; //inject more data
31+
32+
this.$emit(body, {
33+
summary: `Contact "${email}" ID "${contactId}" updated`,
34+
id: body.data.endUserId,
35+
ts: body.timeStamp,
36+
});
37+
},
38+
};

0 commit comments

Comments
 (0)