Skip to content

Commit 335ff74

Browse files
authored
New Components - elastic_email (#15692)
* elastic_email init * [Components] elasticemail #15687 Sources - New Email Open - New Email Click - New Contact Added Actions - Send Email - Add Contact - Unsubscribe Contact * pnpm update * some adjusts * some adjusts * fix template prop
1 parent 2db43fd commit 335ff74

File tree

17 files changed

+702
-20
lines changed

17 files changed

+702
-20
lines changed

components/elastic_email/.gitignore

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { ConfigurationError } from "@pipedream/platform";
2+
import {
3+
CONSENT_TRACKING_OPTIONS,
4+
STATUS_OPTIONS,
5+
} from "../../common/constants.mjs";
6+
import { parseObject } from "../../common/utils.mjs";
7+
import app from "../../elastic_email.app.mjs";
8+
9+
export default {
10+
key: "elastic_email-add-contact",
11+
name: "Add Contact to Mailing List",
12+
description: "Adds a new contact to a mailing list. [See the documentation](https://elasticemail.com/developers/api-documentation/rest-api#operation/contactsPost)",
13+
version: "0.0.1",
14+
type: "action",
15+
props: {
16+
app,
17+
email: {
18+
propDefinition: [
19+
app,
20+
"email",
21+
],
22+
},
23+
listNames: {
24+
propDefinition: [
25+
app,
26+
"listNames",
27+
],
28+
optional: true,
29+
},
30+
status: {
31+
type: "string",
32+
label: "Status",
33+
description: "The initial status of the contact.",
34+
options: STATUS_OPTIONS,
35+
optional: true,
36+
},
37+
firstName: {
38+
type: "string",
39+
label: "First Name",
40+
description: "The contact's first name.",
41+
optional: true,
42+
},
43+
lastName: {
44+
type: "string",
45+
label: "Last Name",
46+
description: "The contact's last name.",
47+
optional: true,
48+
},
49+
customFields: {
50+
type: "object",
51+
label: "Custom Fields",
52+
description: "A key-value collection of custom contact fields which can be used in the system. Only already existing custom fields will be saved.",
53+
optional: true,
54+
},
55+
consentIP: {
56+
type: "string",
57+
label: "Consent IP",
58+
description: "IP address of consent to send this contact(s) your email. If not provided your current public IP address is used for consent.",
59+
optional: true,
60+
},
61+
consentDate: {
62+
type: "string",
63+
label: "Consent Date",
64+
description: "Date of consent to send this contact(s) your email. If not provided current date is used for consent.",
65+
optional: true,
66+
},
67+
consentTracking: {
68+
type: "string",
69+
label: "Consent Tracking",
70+
description: "Tracking of consent to send this contact(s) your email. Defaults to \"Unknown\".",
71+
options: CONSENT_TRACKING_OPTIONS,
72+
optional: true,
73+
},
74+
},
75+
async run({ $ }) {
76+
const response = await this.app.addContact({
77+
$,
78+
params: {
79+
listnames: parseObject(this.listNames),
80+
},
81+
data: [
82+
{
83+
Email: this.email,
84+
Status: this.status,
85+
FirstName: this.firstName,
86+
LastName: this.lastName,
87+
CustomFields: parseObject(this.customFields),
88+
Consent: {
89+
ConsentIP: this.consentIP,
90+
ConsentDate: this.consentDate,
91+
ConsentTracking: this.consentTracking,
92+
},
93+
},
94+
],
95+
});
96+
97+
if (("success" in response) && response.success === "false") {
98+
throw new ConfigurationError(response.error);
99+
}
100+
101+
$.export("$summary", `Successfully added contact ${this.email} to the mailing list`);
102+
return response;
103+
},
104+
};
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import {
2+
BODY_CONTENT_TYPE_OPTIONS,
3+
ENCODING_OPTIONS,
4+
} from "../../common/constants.mjs";
5+
import { parseObject } from "../../common/utils.mjs";
6+
import app from "../../elastic_email.app.mjs";
7+
8+
export default {
9+
key: "elastic_email-send-email",
10+
name: "Send Email",
11+
description: "Sends an email to one or more recipients. [See the documentation](https://elasticemail.com/developers/api-documentation/rest-api#operation/emailsPost)",
12+
version: "0.0.1",
13+
type: "action",
14+
props: {
15+
app,
16+
recipients: {
17+
type: "string[]",
18+
label: "Recipients",
19+
description: "List of recipients",
20+
},
21+
from: {
22+
type: "string",
23+
label: "From",
24+
description: "Your e-mail with an optional name (e.g.: [email protected])",
25+
},
26+
bodyContentType: {
27+
type: "string",
28+
label: "Body Content Type",
29+
description: "Type of body part",
30+
options: BODY_CONTENT_TYPE_OPTIONS,
31+
optional: true,
32+
},
33+
bodyContent: {
34+
type: "string",
35+
label: "Body Content",
36+
description: "Actual content of the body part",
37+
optional: true,
38+
},
39+
merge: {
40+
type: "object",
41+
label: "Merge",
42+
description: "A key-value collection of custom merge fields, shared between recipients. Should be used in e-mail body like so: {firstname}, {lastname} etc.",
43+
optional: true,
44+
},
45+
replyTo: {
46+
type: "string",
47+
label: "Reply To",
48+
description: "To what address should the recipients reply to (e.g. [email protected])",
49+
optional: true,
50+
},
51+
subject: {
52+
type: "string",
53+
label: "Subject",
54+
description: "Default subject of email.",
55+
optional: true,
56+
},
57+
templateName: {
58+
propDefinition: [
59+
app,
60+
"templateName",
61+
],
62+
optional: true,
63+
},
64+
timeOffset: {
65+
type: "integer",
66+
label: "Time Offset",
67+
description: "By how long should an e-mail be delayed (in minutes). Maximum is 35 days.",
68+
optional: true,
69+
},
70+
poolName: {
71+
type: "string",
72+
label: "Pool Name",
73+
description: "Name of your custom IP Pool to be used in the sending process",
74+
optional: true,
75+
},
76+
channelName: {
77+
type: "string",
78+
label: "Channel Name",
79+
description: "Name of selected channel.",
80+
optional: true,
81+
},
82+
encoding: {
83+
type: "string",
84+
label: "Encoding",
85+
description: "Encoding type for the email headers",
86+
options: ENCODING_OPTIONS,
87+
optional: true,
88+
},
89+
trackOpens: {
90+
type: "boolean",
91+
label: "Track Opens",
92+
description: "Should the opens be tracked? If no value has been provided, Account's default setting will be used.",
93+
optional: true,
94+
},
95+
trackClicks: {
96+
type: "boolean",
97+
label: "Track Clicks",
98+
description: "Should the clicks be tracked? If no value has been provided, Account's default setting will be used.",
99+
optional: true,
100+
},
101+
},
102+
async run({ $ }) {
103+
const response = await this.app.sendBulkEmails({
104+
$,
105+
data: {
106+
Recipients: parseObject(this.recipients)?.map((item) => ({
107+
Email: item,
108+
})),
109+
Content: {
110+
From: this.from,
111+
Body: [
112+
{
113+
ContentType: this.bodyContentType,
114+
Body: this.bodyContent,
115+
},
116+
],
117+
Merge: parseObject(this.merge),
118+
ReplyTo: this.replyTo,
119+
Subject: this.subject,
120+
TemplateName: this.templateName,
121+
},
122+
Options: {
123+
TimeOffset: this.timeOffset,
124+
PoolName: this.poolName,
125+
ChannelName: this.channelName,
126+
Encoding: this.encoding,
127+
TrackOpens: this.trackOpens,
128+
TrackClicks: this.trackClicks,
129+
},
130+
},
131+
});
132+
$.export("$summary", `Emails sent successfully to ${this.recipients.join(", ")}`);
133+
return response;
134+
},
135+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { parseObject } from "../../common/utils.mjs";
2+
import app from "../../elastic_email.app.mjs";
3+
4+
export default {
5+
key: "elastic_email-unsubscribe-contact",
6+
name: "Unsubscribe Contact",
7+
description: "Unsubscribes a contact from future emails. [See the documentation](https://elasticemail.com/developers/api-documentation/rest-api#operation/suppressionsUnsubscribesPost)",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
app,
12+
unsubscribeEmails: {
13+
propDefinition: [
14+
app,
15+
"unsubscribeEmails",
16+
],
17+
},
18+
},
19+
async run({ $ }) {
20+
const parsedEmails = parseObject(this.unsubscribeEmails);
21+
const response = await this.app.unsubscribeContact({
22+
$,
23+
data: parsedEmails,
24+
});
25+
$.export("$summary", `Unsubscribed ${parsedEmails.length} contact(s) successfully`);
26+
return response;
27+
},
28+
};

components/elastic_email/app/elastic_email.app.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
export const LIMIT = 100;
2+
3+
export const STATUS_OPTIONS = [
4+
"Transactional",
5+
"Engaged",
6+
"Active",
7+
"Bounced",
8+
"Unsubscribed",
9+
"Abuse",
10+
"Inactive",
11+
"Stale",
12+
"NotConfirmed",
13+
];
14+
15+
export const ENCODING_OPTIONS = [
16+
"UserProvided",
17+
"None",
18+
"Raw7bit",
19+
"Raw8bit",
20+
"QuotedPrintable",
21+
"Base64",
22+
"Uue",
23+
];
24+
25+
export const CONSENT_TRACKING_OPTIONS = [
26+
"Unknown",
27+
"Allow",
28+
"Deny",
29+
];
30+
31+
export const BODY_CONTENT_TYPE_OPTIONS = [
32+
"HTML",
33+
"PlainText",
34+
"AMP",
35+
"CSS",
36+
];
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const parseObject = (obj) => {
2+
if (!obj) return undefined;
3+
4+
if (Array.isArray(obj)) {
5+
return obj.map((item) => {
6+
if (typeof item === "string") {
7+
try {
8+
return JSON.parse(item);
9+
} catch (e) {
10+
return item;
11+
}
12+
}
13+
return item;
14+
});
15+
}
16+
if (typeof obj === "string") {
17+
try {
18+
return JSON.parse(obj);
19+
} catch (e) {
20+
return obj;
21+
}
22+
}
23+
return obj;
24+
};

0 commit comments

Comments
 (0)