Skip to content

Commit 424d1f6

Browse files
[Components] Drift. Actions + Sources (#16553)
* Initial * Save just in case * Save just in case2 * alpha * Test actions * [Components] Drift. Actions + Sources * Fix CodeRabbit * Fix folder name * Fix minor * minor fix * Major fix * add new message source * Update components/drift/actions/create-contact/create-contact.mjs --------- Co-authored-by: Luan Cazarine <[email protected]>
1 parent 8832bfe commit 424d1f6

File tree

9 files changed

+630
-4
lines changed

9 files changed

+630
-4
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import drift from "../../drift.app.mjs";
2+
import { removeNullEntries } from "../../common/utils.mjs";
3+
4+
export default {
5+
key: "drift-create-contact",
6+
name: "Create Contact",
7+
description: "Creates a contact in Drift. [See the documentation](https://devdocs.drift.com/docs/creating-a-contact).",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
drift,
12+
email: {
13+
type: "string",
14+
label: "Email",
15+
description: "The contact's email address",
16+
},
17+
name: {
18+
type: "string",
19+
label: "Name",
20+
description: "The contact's full name",
21+
optional: true,
22+
},
23+
phone: {
24+
type: "string",
25+
label: "Phone",
26+
description: "The contact's phone number",
27+
optional: true,
28+
},
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+
},
35+
customAttributes: {
36+
type: "object",
37+
label: "Custom Attributes",
38+
description: "Additional custom attributes to store on the contact",
39+
optional: true,
40+
},
41+
},
42+
43+
async run({ $ }) {
44+
45+
const {
46+
drift, email, name, phone, source,
47+
} = this;
48+
49+
const customAttributes = drift.parseIfJSONString(this.customAttributes);
50+
51+
const attributes = removeNullEntries({
52+
email,
53+
name,
54+
phone,
55+
source,
56+
...customAttributes,
57+
});
58+
59+
const existingContact = await drift.getContactByEmail({
60+
$,
61+
params: {
62+
email,
63+
},
64+
});
65+
66+
if (existingContact && existingContact.data.length > 0) {
67+
throw new Error (`Contact ${email} already exists`);
68+
};
69+
70+
const response = await drift.createContact({
71+
$,
72+
data: {
73+
attributes,
74+
},
75+
});
76+
77+
$.export("$summary", `Contact "${email}" has been created successfully.`);
78+
return response;
79+
},
80+
};
81+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import drift from "../../drift.app.mjs";
2+
3+
export default {
4+
key: "drift-delete-contact",
5+
name: "Delete Contact",
6+
description: "Deletes a contact in Drift by ID or email. [See the documentation](https://devdocs.drift.com/docs/removing-a-contact).",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
drift,
11+
emailOrId: {
12+
type: "string",
13+
label: "Email or Id",
14+
description: "The contact's email address or ID",
15+
},
16+
},
17+
18+
async run({ $ }) {
19+
20+
const {
21+
drift, emailOrId,
22+
} = this;
23+
24+
let contact = await drift.getContactByEmailOrId($, emailOrId);
25+
contact = contact.data[0] || contact.data;
26+
27+
const contactId = contact.id;
28+
const contactEmail = contact.attributes.email;
29+
30+
const response = await drift.deleteContactById({
31+
$,
32+
contactId,
33+
});
34+
35+
$.export("$summary", `Contact "${contactEmail}" ID "${contactId}"
36+
has been deleted successfully.`);
37+
38+
return response;
39+
},
40+
};
41+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import drift from "../../drift.app.mjs";
2+
3+
export default {
4+
key: "drift-get-contact",
5+
name: "Get Contact",
6+
description: "Retrieves a contact in Drift by ID or email. [See the documentation](https://devdocs.drift.com/docs/retrieving-contact)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
drift,
11+
emailOrId: {
12+
type: "string",
13+
label: "Email or Id",
14+
description: "The contact's email address or ID",
15+
},
16+
},
17+
18+
async run({ $ }) {
19+
20+
const {
21+
drift, emailOrId,
22+
} = this;
23+
24+
const response = await drift.getContactByEmailOrId($, emailOrId);
25+
26+
const contact = response.data[0] || response.data;
27+
28+
if (!contact) {
29+
throw new Error("Failed to get contact");
30+
};
31+
32+
$.export("$summary", `Contact ${contact.attributes.email} ID "${contact.id}"`
33+
+ " has been fetched successfully.");
34+
35+
return contact;
36+
},
37+
};
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import drift from "../../drift.app.mjs";
2+
import { removeNullEntries } from "../../common/utils.mjs";
3+
4+
export default {
5+
key: "drift-update-contact",
6+
name: "Update Contact",
7+
description: "Updates a contact in Drift using ID or email. Only changed attributes will be updated. [See Drift API documentation](https://devdocs.drift.com/docs/updating-a-contact)",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
drift,
12+
emailOrId: {
13+
type: "string",
14+
label: "Email or ID",
15+
description: "The contact’s email address or numeric ID.",
16+
},
17+
email: {
18+
type: "string",
19+
label: "Email",
20+
description: "The contact’s email address",
21+
optional: true,
22+
},
23+
name: {
24+
type: "string",
25+
label: "Name",
26+
description: "The contact’s name.",
27+
optional: true,
28+
},
29+
phone: {
30+
type: "string",
31+
label: "Phone",
32+
description: "The contact’s phone number.",
33+
optional: true,
34+
},
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+
},
41+
customAttributes: {
42+
type: "object",
43+
label: "Custom Attributes",
44+
description: "Any custom attributes to update (e.g. company, job title, etc).",
45+
optional: true,
46+
},
47+
},
48+
49+
async run({ $ }) {
50+
const {
51+
drift, name, email, phone, source, emailOrId,
52+
} = this;
53+
54+
const customAttributes = drift.parseIfJSONString(this.customAttributes);
55+
56+
const attributes = removeNullEntries({
57+
name,
58+
phone,
59+
email,
60+
source,
61+
...customAttributes,
62+
});
63+
64+
if (!Object.keys(attributes).length) {
65+
throw new Error("No attributes provided to update.");
66+
};
67+
68+
let contact = await drift.getContactByEmailOrId($, emailOrId);
69+
70+
const contactId = contact.data[0]?.id || contact.data.id;
71+
72+
const response = await drift.updateContact({
73+
$,
74+
contactId,
75+
data: {
76+
attributes,
77+
},
78+
});
79+
80+
$.export("$summary", `Contact ID "${contactId}" has been updated successfully.`);
81+
82+
return response;
83+
},
84+
};
85+

components/drift/common/utils.mjs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
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 =
11+
typeof value === "object" &&
12+
value !== null &&
13+
!Array.isArray(value) &&
14+
Object.keys(value).length !== 0;
15+
isNotEmptyObject && (value = removeNullEntries(value));
16+
return ((value || value === false) &&
17+
(isNotEmpyString || isNotEmptyArray || isNotEmptyObject || isBoolean || isNumber))
18+
? {
19+
...acc,
20+
[key]: value,
21+
}
22+
: acc;
23+
}, {});
24+
25+
function doesContextMatch(inputContext, fetchedContext) {
26+
27+
if (typeof inputContext !== "object" || inputContext === null || Array.isArray(inputContext)) {
28+
throw new Error ("Message context is not an object");
29+
};
30+
31+
for (const key of Object.keys(inputContext)) {
32+
if (!(key in fetchedContext)) {
33+
console.log(`Invalid context field "${key}", emission skipped` );
34+
return false;
35+
}
36+
if (fetchedContext[key] !== inputContext[key]) {
37+
console.log(`Context values of "${key}" do not match, emission skipped` );
38+
return false;
39+
}
40+
}
41+
return true;
42+
};
43+
44+
export {
45+
removeNullEntries,
46+
doesContextMatch,
47+
};
48+

0 commit comments

Comments
 (0)