1 | import sendgrid from "@sendgrid/client@^7.7.0"; |
2 |
|
3 | |
4 | * According to Sendgrid documentation, this is an asynchronous |
5 | * process and the response will NOT contain immediate feedback, |
6 | * only a `job_id` which then can be used to get the status |
7 | * of the job. |
8 | * The following script from WindmillHub performs this status check: |
9 | * https://hub.windmill.dev/scripts/sendgrid/1449/get-contacts-import-status-sendgrid |
10 | * |
11 | * You can read more of the Sendgrid documentation at |
12 | * https://docs.sendgrid.com/api-reference/contacts/add-or-update-a-contact |
13 | */ |
14 | type Sendgrid = { |
15 | token: string; |
16 | }; |
17 | export async function main( |
18 | api_token: Sendgrid, |
19 | contacts: { |
20 | email: string; |
21 | custom_fields: Record<string, string | number>; |
22 | }[], |
23 | list_ids?: string[], |
24 | ) { |
25 | sendgrid.setApiKey(api_token.token); |
26 |
|
27 | try { |
28 | contacts = contacts.map((c) => { |
29 | return typeof c === "string" ? JSON.parse(c) : c; |
30 | }); |
31 | } catch (error) { |
32 | throw Error(`Tried to parse "contacts" argument because |
33 | it was an array of strings but failed with error:\n${error}`); |
34 | } |
35 |
|
36 | const body = removeObjectEmptyFields({ |
37 | contacts, |
38 | list_ids, |
39 | }); |
40 | const request = { |
41 | url: `/v3/marketing/contacts`, |
42 | method: "PUT", |
43 | body, |
44 | }; |
45 |
|
46 | try { |
47 | const [_, body] = await sendgrid.request(request); |
48 | return body; |
49 | } catch (error) { |
50 | throw Error("\n" + JSON.stringify(error?.response?.body || error)); |
51 | } |
52 | } |
53 |
|
54 | function removeObjectEmptyFields( |
55 | object?: Record<string, any>, |
56 | removeEmptyArraysAndObjects = true, |
57 | createNewObject = true, |
58 | ) { |
59 | if (!object || typeof object !== "object") return {} |
60 | const obj = createNewObject ? { ...object } : object |
61 | const emptyValues = [undefined, null, ""] |
62 | for (const key in obj) { |
63 | const value = obj[key] |
64 | if (emptyValues.includes(value)) { |
65 | delete obj[key] |
66 | } else if (typeof value === "object") { |
67 | if (Object.keys(value).length) { |
68 | obj[key] = removeObjectEmptyFields(value, removeEmptyArraysAndObjects, false) |
69 | } |
70 | if (!Object.keys(value).length && removeEmptyArraysAndObjects) { |
71 | delete obj[key] |
72 | } |
73 | } |
74 | } |
75 | return obj |
76 | } |
77 |
|