Skip to content

Commit 36b5862

Browse files
committed
init
1 parent a7b1c4e commit 36b5862

File tree

7 files changed

+392
-5
lines changed

7 files changed

+392
-5
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import campaignMonitor from "../../campaign_monitor.app.mjs";
2+
3+
export default {
4+
key: "campaign_monitor-add-subscriber",
5+
name: "Add Subscriber",
6+
description: "Creates a new subscriber on a specific list. [See the documentation](https://www.campaignmonitor.com/api/subscribers/#adding-a-subscriber)",
7+
version: "0.0.{{ts}}",
8+
type: "action",
9+
props: {
10+
campaignMonitor,
11+
email: {
12+
propDefinition: [
13+
campaignMonitor,
14+
"email",
15+
],
16+
},
17+
listId: {
18+
propDefinition: [
19+
campaignMonitor,
20+
"listId",
21+
],
22+
},
23+
name: {
24+
propDefinition: [
25+
campaignMonitor,
26+
"name",
27+
],
28+
optional: true,
29+
},
30+
},
31+
async run({ $ }) {
32+
const response =
33+
await this.campaignMonitor.createSubscriber(this.email, this.listId, this.name);
34+
$.export("$summary", `Successfully added subscriber ${this.email} to list ${this.listId}`);
35+
return response;
36+
},
37+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import campaignMonitor from "../../campaign_monitor.app.mjs";
2+
3+
export default {
4+
key: "campaign_monitor-send-smart-transactional-email",
5+
name: "Send Smart Transactional Email",
6+
description: "Sends an intelligent transactional email to a specified recipient.",
7+
version: "0.0.{{ts}}",
8+
type: "action",
9+
props: {
10+
campaignMonitor,
11+
email: {
12+
type: "string",
13+
label: "Email",
14+
description: "The email of the recipient",
15+
},
16+
subject: {
17+
type: "string",
18+
label: "Subject",
19+
description: "The subject of the email",
20+
},
21+
content: {
22+
type: "string",
23+
label: "Content",
24+
description: "The content of the email",
25+
},
26+
listId: {
27+
type: "string",
28+
label: "List ID",
29+
description: "The ID of the list",
30+
optional: true,
31+
},
32+
},
33+
async run({ $ }) {
34+
const response = await this.campaignMonitor.sendIntelligentEmail(
35+
this.email,
36+
this.subject,
37+
this.content,
38+
this.listId,
39+
);
40+
$.export("$summary", "Successfully sent smart transactional email");
41+
return response;
42+
},
43+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import campaignMonitor from "../../campaign_monitor.app.mjs";
2+
3+
export default {
4+
key: "campaign_monitor-unsubscribe",
5+
name: "Unsubscribe",
6+
description: "Removes a subscriber from a mailing list given their email address.",
7+
version: "0.0.{{ts}}",
8+
type: "action",
9+
props: {
10+
campaignMonitor,
11+
email: {
12+
type: "string",
13+
label: "Email",
14+
description: "The email of the subscriber to remove",
15+
},
16+
listId: {
17+
type: "string",
18+
label: "List ID",
19+
description: "The ID of the mailing list from which to remove the subscriber",
20+
optional: true,
21+
},
22+
},
23+
async run({ $ }) {
24+
const response = await this.campaignMonitor.removeSubscriber(this.email, this.listId);
25+
$.export("$summary", `Successfully unsubscribed ${this.email}`);
26+
return response;
27+
},
28+
};
Lines changed: 112 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,118 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "campaign_monitor",
4-
propDefinitions: {},
6+
propDefinitions: {
7+
campaignId: {
8+
type: "string",
9+
label: "Campaign ID",
10+
description: "The ID of the campaign",
11+
},
12+
subscriberId: {
13+
type: "string",
14+
label: "Subscriber ID",
15+
description: "The ID of the subscriber",
16+
optional: true,
17+
},
18+
listId: {
19+
type: "string",
20+
label: "List ID",
21+
description: "The ID of the list",
22+
},
23+
email: {
24+
type: "string",
25+
label: "Email",
26+
description: "The email of the recipient",
27+
},
28+
subject: {
29+
type: "string",
30+
label: "Subject",
31+
description: "The subject of the email",
32+
},
33+
content: {
34+
type: "string",
35+
label: "Content",
36+
description: "The content of the email",
37+
},
38+
name: {
39+
type: "string",
40+
label: "Name",
41+
description: "The name of the subscriber",
42+
optional: true,
43+
},
44+
},
545
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
46+
_baseUrl() {
47+
return "https://api.createsend.com/api/v3.3";
48+
},
49+
async _makeRequest(opts = {}) {
50+
const {
51+
$ = this,
52+
method = "GET",
53+
path,
54+
headers,
55+
...otherOpts
56+
} = opts;
57+
return axios($, {
58+
...otherOpts,
59+
method,
60+
url: this._baseUrl() + path,
61+
headers: {
62+
...headers,
63+
Authorization: `Bearer ${this.$auth.api_key}`,
64+
},
65+
});
66+
},
67+
async emitCampaignEmailBounce(campaignId) {
68+
return this._makeRequest({
69+
path: `/campaigns/${campaignId}/bounces`,
70+
});
71+
},
72+
async emitCampaignEmailOpen(campaignId, subscriberId) {
73+
return this._makeRequest({
74+
path: `/campaigns/${campaignId}/opens`,
75+
params: {
76+
subscriber_id: subscriberId,
77+
},
78+
});
79+
},
80+
async emitNewSubscriber(listId) {
81+
return this._makeRequest({
82+
path: `/lists/${listId}/active`,
83+
});
84+
},
85+
async sendIntelligentEmail(email, subject, content, listId) {
86+
return this._makeRequest({
87+
method: "POST",
88+
path: "/transactional/send",
89+
data: {
90+
email,
91+
subject,
92+
content,
93+
list_id: listId,
94+
},
95+
});
96+
},
97+
async removeSubscriber(email, listId) {
98+
return this._makeRequest({
99+
method: "DELETE",
100+
path: `/subscribers/${listId}`,
101+
params: {
102+
email,
103+
},
104+
});
105+
},
106+
async createSubscriber(email, listId, name) {
107+
return this._makeRequest({
108+
method: "POST",
109+
path: `/subscribers/${listId}`,
110+
data: {
111+
email,
112+
list_id: listId,
113+
name,
114+
},
115+
});
9116
},
10117
},
11-
};
118+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import campaignMonitor from "../../campaign_monitor.app.mjs";
2+
3+
export default {
4+
key: "campaign_monitor-new-bounce",
5+
name: "New Bounce",
6+
description: "Emits an event when a campaign email bounces",
7+
version: "0.0.{{ts}}",
8+
type: "source",
9+
dedupe: "unique",
10+
props: {
11+
campaignMonitor: {
12+
type: "app",
13+
app: "campaign_monitor",
14+
},
15+
db: "$.service.db",
16+
timer: {
17+
type: "$.interface.timer",
18+
default: {
19+
intervalSeconds: 60 * 15, // 15 minutes
20+
},
21+
},
22+
campaignId: {
23+
propDefinition: [
24+
campaignMonitor,
25+
"campaignId",
26+
],
27+
},
28+
},
29+
hooks: {
30+
async deploy() {
31+
// Get the most recent bounces to initialize the checkpoint.
32+
const bounces = await this.campaignMonitor.emitCampaignEmailBounce(this.campaignId);
33+
if (bounces && bounces.length > 0) {
34+
this.db.set("lastBounceDate", bounces[0].Date);
35+
}
36+
},
37+
},
38+
async run() {
39+
const lastBounceDate = this.db.get("lastBounceDate");
40+
const bounces = await this.campaignMonitor.emitCampaignEmailBounce(this.campaignId);
41+
42+
for (const bounce of bounces) {
43+
if (!lastBounceDate || new Date(bounce.Date) > new Date(lastBounceDate)) {
44+
this.$emit(bounce, {
45+
id: bounce.EmailAddress,
46+
summary: `New bounce for ${bounce.EmailAddress}`,
47+
ts: Date.parse(bounce.Date),
48+
});
49+
this.db.set("lastBounceDate", bounce.Date);
50+
}
51+
}
52+
},
53+
};
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import campaignMonitor from "../../campaign_monitor.app.mjs";
2+
3+
export default {
4+
key: "campaign_monitor-new-email-open",
5+
name: "New Email Open",
6+
description: "Emits a new event when an email from a campaign is opened",
7+
version: "0.0.1",
8+
type: "source",
9+
dedupe: "unique",
10+
props: {
11+
campaignMonitor: {
12+
type: "app",
13+
app: "campaign_monitor",
14+
},
15+
db: "$.service.db",
16+
timer: {
17+
type: "$.interface.timer",
18+
default: {
19+
intervalSeconds: 60 * 15, // 15 minutes
20+
},
21+
},
22+
campaignId: {
23+
propDefinition: [
24+
campaignMonitor,
25+
"campaignId",
26+
],
27+
},
28+
subscriberId: {
29+
propDefinition: [
30+
campaignMonitor,
31+
"subscriberId",
32+
],
33+
optional: true,
34+
},
35+
},
36+
methods: {
37+
_getEventMeta(event) {
38+
const ts = +new Date(event.Date);
39+
const summary = `New email open: ${event.EmailAddress}`;
40+
const id = `${event.EmailAddress}-${ts}`;
41+
return {
42+
id,
43+
summary,
44+
ts,
45+
};
46+
},
47+
},
48+
async run() {
49+
const since = this.db.get("since");
50+
const { Results: events } =
51+
await this.campaignMonitor.emitCampaignEmailOpen(this.campaignId, this.subscriberId);
52+
for (const event of events) {
53+
if (since && new Date(event.Date) <= new Date(since)) {
54+
console.log("This email open event is old, skipping");
55+
continue;
56+
}
57+
this.$emit(event, this._getEventMeta(event));
58+
}
59+
this.db.set("since", new Date());
60+
},
61+
};

0 commit comments

Comments
 (0)