@pipedream/selzy 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,127 @@
1
+ import { ConfigurationError } from "@pipedream/platform";
2
+ import { clearEmpty } from "../../common/utils.mjs";
3
+ import selzy from "../../selzy.app.mjs";
4
+
5
+ export default {
6
+ key: "selzy-create-campaign",
7
+ name: "Create Campaign",
8
+ description: "Creates a new campaign. [See the documentation](https://selzy.com/en/support/api/messages/createcampaign/)",
9
+ version: "0.0.1",
10
+ type: "action",
11
+ props: {
12
+ selzy,
13
+ messageId: {
14
+ type: "string",
15
+ label: "Message ID",
16
+ description: "Code of the message to be sent. The code returned by the **Create Email Message** method should be transferred.",
17
+ optional: true,
18
+ },
19
+ startTime: {
20
+ type: "string",
21
+ label: "Start Time",
22
+ description: "Campaign launch date and time in the \"YYYY-MM-DD hh:mm\" format, which do not exceed 100 days from the current date. If the argument is not set, the campaign starts immediately. The time zone specified in the settings of the user's personal account is applied. To explicitly specify a time zone, use the **Timezone** argument. To provide additional error protection, you should not schedule two sendings of the same message within an hour.",
23
+ optional: true,
24
+ },
25
+ trackRead: {
26
+ type: "boolean",
27
+ label: "Track Read",
28
+ description: "Whether to track the fact of reading the email message. The default value is `false` (do not track). If `true`, a link to a small image tracking the reference will be added to the email. The **Track Read** argument is ignored for SMS messages.",
29
+ optional: true,
30
+ },
31
+ trackLinks: {
32
+ type: "boolean",
33
+ label: "Track Links",
34
+ description: "To track whether there are any click-throughs in email messages, the default value is `false` (do not track). If `true`, all external links will be replaced with special ones that allow you to track the fact of a click-through, and then forward the user to the desired page. The **Track Links** argument is ignored for SMS messages.",
35
+ optional: true,
36
+ },
37
+ contactsUrl: {
38
+ type: "string",
39
+ label: "Contacts URL",
40
+ description: "Instead of the contacts parameter containing the actual email addresses or phone numbers, in this parameter you can specify the URL of the file from which the addresses (phone numbers) will be read. The URL must start with \"http://\", \"https://\" or \"ftp://\". The file must contain one contact per string, without commas; strings must be separated by \"n\" or \"rn\" (Mac format — only \"r\" — not supported). The file can be deleted after the campaign has shifted to the 'scheduled' status.",
41
+ optional: true,
42
+ },
43
+ trackGa: {
44
+ type: "boolean",
45
+ label: "Track GA",
46
+ description: "Whether to enable Google Analytics integration for this campaign. Only explicitly indicated values are valid, default usage parameters are not applied. The default value is `false` (disabled).",
47
+ optional: true,
48
+ reloadProps: true,
49
+ },
50
+ gaMedium: {
51
+ type: "string",
52
+ label: "GA Medium",
53
+ description: "Integration parameters with Google Analytics (valid if track_ga=1). Only explicitly indicated values are valid, default usage parameters are not applied.",
54
+ optional: true,
55
+ hidden: true,
56
+ },
57
+ gaSource: {
58
+ type: "string",
59
+ label: "GA Source",
60
+ description: "Integration parameters with Google Analytics (valid if track_ga=1). Only explicitly indicated values are valid, default usage parameters are not applied.",
61
+ optional: true,
62
+ hidden: true,
63
+ },
64
+ gaCampaign: {
65
+ type: "string",
66
+ label: "GA Campaign",
67
+ description: "Integration parameters with Google Analytics (valid if track_ga=1). Only explicitly indicated values are valid, default usage parameters are not applied.",
68
+ optional: true,
69
+ hidden: true,
70
+ },
71
+ gaContent: {
72
+ type: "string",
73
+ label: "GA Content",
74
+ description: "Integration parameters with Google Analytics (valid if track_ga=1). Only explicitly indicated values are valid, default usage parameters are not applied.",
75
+ optional: true,
76
+ hidden: true,
77
+ },
78
+ gaTerm: {
79
+ type: "string",
80
+ label: "GA Term",
81
+ description: "Integration parameters with Google Analytics (valid if track_ga=1). Only explicitly indicated values are valid, default usage parameters are not applied.",
82
+ optional: true,
83
+ hidden: true,
84
+ },
85
+ },
86
+ async additionalProps(props) {
87
+ const gaAllowed = this.trackGa;
88
+ props.gaMedium.hidden = !gaAllowed;
89
+ props.gaSource.hidden = !gaAllowed;
90
+ props.gaCampaign.hidden = !gaAllowed;
91
+ props.gaContent.hidden = !gaAllowed;
92
+ props.gaTerm.hidden = !gaAllowed;
93
+
94
+ return {};
95
+ },
96
+ async run({ $ }) {
97
+ if (this.contacts && this.contactsUrl) {
98
+ throw new ConfigurationError("You can't set both contacts and contactsUrl parameters at the same time");
99
+ }
100
+
101
+ const response = await this.selzy.createCampaign({
102
+ $,
103
+ params: clearEmpty({
104
+ message_id: this.messageId,
105
+ start_time: this.startTime,
106
+ track_read: this.trackRead
107
+ ? 1
108
+ : 0,
109
+ track_links: this.trackLinks
110
+ ? 1
111
+ : 0,
112
+ contacts_url: this.contactsUrl,
113
+ track_ga: this.trackGa && +this.trackGa,
114
+ ga_medium: this.gaMedium,
115
+ ga_source: this.gaSource,
116
+ ga_campaign: this.gaCampaign,
117
+ ga_content: this.gaContent,
118
+ ga_term: this.gaTerm,
119
+ }),
120
+ });
121
+
122
+ if (response.error) throw new ConfigurationError(response.error);
123
+
124
+ $.export("$summary", `Successfully created email campaign with ID: ${response.result.campaign_id}`);
125
+ return response;
126
+ },
127
+ };
@@ -0,0 +1,135 @@
1
+ import { ConfigurationError } from "@pipedream/platform";
2
+ import {
3
+ MESSAGE_FORMAT_OPTIONS, WRAP_TYPE_OPTIONS,
4
+ } from "../../common/constants.mjs";
5
+ import { parseObject } from "../../common/utils.mjs";
6
+ import selzy from "../../selzy.app.mjs";
7
+
8
+ export default {
9
+ key: "selzy-create-email-message",
10
+ name: "Create Email Message",
11
+ description: "Adds a new email message. [See the documentation](https://selzy.com/en/support/category/api/messages/)",
12
+ version: "0.0.1",
13
+ type: "action",
14
+ props: {
15
+ selzy,
16
+ senderName: {
17
+ type: "string",
18
+ label: "Sender's name",
19
+ description: "It is a string that does not match the email address (the sender_email argument).",
20
+ },
21
+ senderEmail: {
22
+ type: "string",
23
+ label: "Sender's email address",
24
+ description: "This email must be checked (to do this, you need to manually create at least one email with this return address via the web interface, then click on the \"send the confirmation request\" link and follow the link from the email).",
25
+ },
26
+ subject: {
27
+ type: "string",
28
+ label: "Subject",
29
+ description: "String with the letter subject. It may include substitution fields. If you wish to use substitution fields, specify a string within a Pipedream Custom Expression and escape the curly brackets with a backslash. For example: `{{ \"Welcome to Our Newsletter, \\{\\{Name\\}\\}!\" }}`. The parameter is optional if Template Id is indicated.",
30
+ },
31
+ body: {
32
+ type: "string",
33
+ label: "Body",
34
+ description: "HTML body of the letter. It may include substitution fields. If you wish to use substitution fields, specify an HTML string within a Pipedream Custom Expression and escape the curly brackets with a backslash. For example: `{{ \"<p>Hello \\{\\{Name\\}\\},</p><p>Here is your update.</p>\" }}`.",
35
+ },
36
+ listId: {
37
+ propDefinition: [
38
+ selzy,
39
+ "listId",
40
+ ],
41
+ },
42
+ textBody: {
43
+ type: "string",
44
+ label: "Text Body",
45
+ description: "Text body of the letter. It may include substitution fields. If you wish to use substitution fields, specify a text string within a Pipedream Custom Expression and escape the curly brackets with a backslash. For example: `{{ \"Hello \\{\\{Name\\}\\},\\nHere is your update.\" }}`.",
46
+ optional: true,
47
+ },
48
+ generateText: {
49
+ type: "boolean",
50
+ label: "Generate Text",
51
+ description: "`True` means that the text part of the letter will be generated automatically based on the HTML part. If you do not provide the text version along with the HTML version, you are recommended to set the **Generate Text** parameter to `true` for automatic generation of the text part of the letter. If the text variant of the letter is provided using the **Text Body** parameter, the **Generate Text** parameter is ignored. Thus, if the **Generate Text** value has been set to `true`, the server's response will contain a warning.",
52
+ },
53
+ rawBody: {
54
+ type: "string",
55
+ label: "Raw Body",
56
+ description: "It is intended to save the json structure of the block editor data structure (if the value is **Message Format** = block) The parameter obtains only the JSON structure, otherwise it will not be transferred.",
57
+ optional: true,
58
+ },
59
+ messageFormat: {
60
+ type: "string",
61
+ label: "Message Format",
62
+ description: `It defines the manner of creating a letter.
63
+ \n 1 - If you transfer the \`text\` value in this parameter and both the body and **Text Body** parameters are filled, the body parameter will be ignored, and the letter will be created from the data, transferred in the **Text Body** parameter.
64
+ \n 2 - If you transfer the \`block\` value in this parameter but do not specify **Raw Body**, the letter will be saved as **Raw HTML**.
65
+ \n 3 - If you transfer the \`block\` value in this parameter, the **body** and **Raw Body** parameters must be transferred so taht you can save the message in the block editor format.`,
66
+ options: MESSAGE_FORMAT_OPTIONS,
67
+ optional: true,
68
+ },
69
+ lang: {
70
+ type: "string",
71
+ label: "Lang",
72
+ description: `Two-letter language code for the string with the unsubscribe link that is added to each letter automatically.
73
+ If it is not specified, the language code from the API URL is used.
74
+ In addition to the string with the unsubscribe link, this language also affects the interface of the unsubscribe page. Languages en, it, ua and ru are fully supported, and in case of some other languages (da, de, es, fr, nl, pl, pt, tr), the string with a link will be translated, and the control interface will be in English.`,
75
+ optional: true,
76
+ },
77
+ templateId: {
78
+ propDefinition: [
79
+ selzy,
80
+ "templateId",
81
+ ],
82
+ optional: true,
83
+ },
84
+ systemTemplateId: {
85
+ propDefinition: [
86
+ selzy,
87
+ "systemTemplateId",
88
+ ],
89
+ optional: true,
90
+ },
91
+ wrapType: {
92
+ type: "string",
93
+ label: "Wrap Type",
94
+ description: "Alignment of the message text on the specified side. If the argument is missing, the text will not be aligned.",
95
+ options: WRAP_TYPE_OPTIONS,
96
+ optional: true,
97
+ },
98
+ categories: {
99
+ type: "string[]",
100
+ label: "Categories",
101
+ description: "A list of letter categories.",
102
+ optional: true,
103
+ },
104
+ },
105
+ async run({ $ }) {
106
+ if (this.templateId && this.systemTemplateId) {
107
+ throw new ConfigurationError("You can only use one of the Template Id or System Template Id parameters.");
108
+ }
109
+ const response = await this.selzy.createEmailMessage({
110
+ $,
111
+ params: {
112
+ sender_name: this.senderName,
113
+ sender_email: this.senderEmail,
114
+ subject: this.subject,
115
+ body: this.body,
116
+ list_id: this.listId,
117
+
118
+ text_body: this.textBody,
119
+ generate_text: +this.generateText,
120
+ raw_body: this.rawBody,
121
+ message_format: this.messageFormat,
122
+ lang: this.lang,
123
+ template_id: this.templateId,
124
+ system_template_id: this.systemTemplateId,
125
+ wrap_type: this.wrapType,
126
+ categories: parseObject(this.categories)?.join(","),
127
+ },
128
+ });
129
+
130
+ if (response.error) throw new ConfigurationError(response.error);
131
+
132
+ $.export("$summary", `Email message created successfully with ID ${response.result.message_id}.`);
133
+ return response;
134
+ },
135
+ };
@@ -0,0 +1,35 @@
1
+ export const LIMIT = 100;
2
+
3
+ export const MESSAGE_FORMAT_OPTIONS = [
4
+ {
5
+ label: "Raw HTML",
6
+ value: "raw_html",
7
+ },
8
+ {
9
+ label: "Block",
10
+ value: "block",
11
+ },
12
+ {
13
+ label: "Text",
14
+ value: "text",
15
+ },
16
+ ];
17
+
18
+ export const WRAP_TYPE_OPTIONS = [
19
+ {
20
+ label: "Skip (Do not apply)",
21
+ value: "skip",
22
+ },
23
+ {
24
+ label: "Right (Right alignment)",
25
+ value: "right",
26
+ },
27
+ {
28
+ label: "Left (Left alignment)",
29
+ value: "left",
30
+ },
31
+ {
32
+ label: "Center (Center alignment)",
33
+ value: "center",
34
+ },
35
+ ];
@@ -0,0 +1,38 @@
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
+ };
25
+
26
+ export const clearEmpty = (obj) => {
27
+ if (!obj) return undefined;
28
+
29
+ const newObj = {
30
+ ...obj,
31
+ };
32
+ Object.keys(newObj).forEach((key) => {
33
+ if (newObj[key] === "" || newObj[key] === null || newObj[key] === undefined) {
34
+ delete newObj[key];
35
+ }
36
+ });
37
+ return newObj;
38
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/selzy",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "Pipedream Selzy Components",
5
5
  "main": "selzy.app.mjs",
6
6
  "keywords": [
@@ -11,5 +11,8 @@
11
11
  "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
12
12
  "publishConfig": {
13
13
  "access": "public"
14
+ },
15
+ "dependencies": {
16
+ "@pipedream/platform": "^3.0.3"
14
17
  }
15
18
  }
package/selzy.app.mjs CHANGED
@@ -1,11 +1,198 @@
1
+ import { axios } from "@pipedream/platform";
2
+ import { LIMIT } from "./common/constants.mjs";
3
+
1
4
  export default {
2
5
  type: "app",
3
6
  app: "selzy",
4
- propDefinitions: {},
7
+ propDefinitions: {
8
+ listId: {
9
+ type: "string",
10
+ label: "List ID",
11
+ description: "Code of the list on which the mailing will be sent.",
12
+ async options() {
13
+ const { result } = await this.listLists();
14
+
15
+ return result.map(({
16
+ id: value, title: label,
17
+ }) => ({
18
+ label,
19
+ value,
20
+ }));
21
+ },
22
+ },
23
+ templateId: {
24
+ type: "string",
25
+ label: "Template Id",
26
+ description: "ID of the user letter template created before, on the basis of which a letter can be created. If you have transferred this parameter, you may skip the mandatory **Subject**, **Body**, as well as **Text Body** and **Lang** parameters. These values will be taken from the corresponding parameters of the template the id of which was specified. If any of the above parameters is still transferred, the system will ignore the parameter that is taken from the template parameters, and the parameter explicitly transferred in this method will be used.",
27
+ async options({ page }) {
28
+ const { result } = await this.listTemplates({
29
+ params: {
30
+ limit: LIMIT,
31
+ offset: LIMIT * page,
32
+ type: "user",
33
+ },
34
+ });
35
+
36
+ return result.map(({
37
+ id: value, title: label,
38
+ }) => ({
39
+ label,
40
+ value,
41
+ }));
42
+ },
43
+ },
44
+ systemTemplateId: {
45
+ type: "string",
46
+ label: "System Template Id",
47
+ description: "ID of the system letter template created before, on the basis of which a letter can be created. If you have transferred this parameter, you may skip the mandatory **Subject**, **Body**, as well as **Text Body** and **Lang** parameters. These values will be taken from the corresponding parameters of the template the id of which was specified. If any of the above parameters is still transferred, the system will ignore the parameter that is taken from the template parameters, and the parameter explicitly transferred in this method will be used. If none of the **Template Id** or **System Template Id** parameters is specified, templates will not be used to create the letter.",
48
+ async options({ page }) {
49
+ const { result } = await this.listTemplates({
50
+ params: {
51
+ limit: LIMIT,
52
+ offset: LIMIT * page,
53
+ type: "system",
54
+ },
55
+ });
56
+
57
+ return result.map(({
58
+ id: value, title: label,
59
+ }) => ({
60
+ label,
61
+ value,
62
+ }));
63
+ },
64
+ },
65
+ messageId: {
66
+ type: "string",
67
+ label: "Message Id",
68
+ description: "Code of the message to be sent.",
69
+ async options({ page }) {
70
+ const { result } = await this.listTemplates({
71
+ params: {
72
+ limit: LIMIT,
73
+ offset: LIMIT * page,
74
+ type: "system",
75
+ },
76
+ });
77
+
78
+ return result.map(({
79
+ id: value, title: label,
80
+ }) => ({
81
+ label,
82
+ value,
83
+ }));
84
+ },
85
+ },
86
+
87
+ campaignId: {
88
+ type: "string",
89
+ label: "Campaign ID",
90
+ description: "Select or enter the Campaign ID to monitor",
91
+ async options() {
92
+ const campaigns = await this.getCampaigns();
93
+ return campaigns.map((campaign) => ({
94
+ label: campaign.name,
95
+ value: campaign.id,
96
+ }));
97
+ },
98
+ },
99
+ messageContent: {
100
+ type: "string",
101
+ label: "Message Content",
102
+ description: "Content of the email message",
103
+ },
104
+ },
5
105
  methods: {
6
- // this.$auth contains connected account data
7
- authKeys() {
8
- console.log(Object.keys(this.$auth));
106
+ _baseUrl() {
107
+ return "https://api.selzy.com/en/api";
108
+ },
109
+ _params(params = {}) {
110
+ return {
111
+ api_key: `${this.$auth.api_key}`,
112
+ format: "json",
113
+ ...params,
114
+ };
115
+ },
116
+ _makeRequest({
117
+ $ = this, path, params, ...opts
118
+ }) {
119
+ return axios($, {
120
+ url: this._baseUrl() + path,
121
+ params: this._params(params),
122
+ ...opts,
123
+ });
124
+ },
125
+ listLists(opts = {}) {
126
+ return this._makeRequest({
127
+ path: "/getLists",
128
+ ...opts,
129
+ });
130
+ },
131
+ listTemplates(opts = {}) {
132
+ return this._makeRequest({
133
+ path: "/listTemplates",
134
+ ...opts,
135
+ });
136
+ },
137
+ getCampaigns(opts = {}) {
138
+ return this._makeRequest({
139
+ path: "/getCampaigns",
140
+ ...opts,
141
+ });
142
+ },
143
+ createEmailMessage(opts = {}) {
144
+ return this._makeRequest({
145
+ method: "POST",
146
+ path: "/createEmailMessage",
147
+ ...opts,
148
+ });
149
+ },
150
+ createCampaign(opts = {}) {
151
+ return this._makeRequest({
152
+ method: "POST",
153
+ path: "/createCampaign",
154
+ ...opts,
155
+ });
156
+ },
157
+ createWebhook(opts = {}) {
158
+ return this._makeRequest({
159
+ method: "POST",
160
+ path: "/setHook",
161
+ ...opts,
162
+ });
163
+ },
164
+ deleteWebhook(opts = {}) {
165
+ return this._makeRequest({
166
+ method: "POST",
167
+ path: "/removeHook",
168
+ ...opts,
169
+ });
170
+ },
171
+ async *paginate({
172
+ fn, params = {}, maxResults = null, ...opts
173
+ }) {
174
+ let hasMore = false;
175
+ let count = 0;
176
+ let page = 0;
177
+
178
+ do {
179
+ params.limit = LIMIT;
180
+ params.offset = LIMIT * page++;
181
+ const { result } = await fn({
182
+ params,
183
+ ...opts,
184
+ });
185
+ for (const d of result) {
186
+ yield d;
187
+
188
+ if (maxResults && ++count === maxResults) {
189
+ return count;
190
+ }
191
+ }
192
+
193
+ hasMore = result.length;
194
+
195
+ } while (hasMore);
9
196
  },
10
197
  },
11
- };
198
+ };
@@ -0,0 +1,49 @@
1
+ import selzy from "../../selzy.app.mjs";
2
+
3
+ export default {
4
+ props: {
5
+ selzy,
6
+ http: {
7
+ type: "$.interface.http",
8
+ customResponse: true,
9
+ },
10
+ db: "$.service.db",
11
+ },
12
+ hooks: {
13
+ async activate() {
14
+ await this.selzy.createWebhook({
15
+ params: {
16
+ hook_url: this.http.endpoint,
17
+ event_format: "json_post",
18
+ ...this.getEventType(),
19
+ single_event: 1,
20
+ status: "active",
21
+ },
22
+ });
23
+ },
24
+ async deactivate() {
25
+ await this.selzy.deleteWebhook({
26
+ params: {
27
+ hook_url: this.http.endpoint,
28
+ },
29
+ });
30
+ },
31
+ },
32
+ async run({
33
+ body, method,
34
+ }) {
35
+ if (method === "GET") {
36
+ this.http.respond({
37
+ status: 200,
38
+ });
39
+ return true;
40
+ }
41
+
42
+ const ts = Date.parse(body.event_time);
43
+ this.$emit(body, {
44
+ id: `${body.campaign_id || body.email}-${ts}`,
45
+ summary: this.getSummary(body),
46
+ ts: ts,
47
+ });
48
+ },
49
+ };
@@ -0,0 +1,67 @@
1
+ import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
2
+ import selzy from "../../selzy.app.mjs";
3
+
4
+ export default {
5
+ key: "selzy-new-campaign",
6
+ name: "New Campaign Created",
7
+ description: "Emit new event when a new email campaign is created. Useful for monitoring campaign creation activity.",
8
+ version: "0.0.1",
9
+ type: "source",
10
+ dedupe: "unique",
11
+ props: {
12
+ selzy,
13
+ db: "$.service.db",
14
+ timer: {
15
+ type: "$.interface.timer",
16
+ default: {
17
+ intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
18
+ },
19
+ },
20
+ },
21
+ methods: {
22
+ _getLastId() {
23
+ return this.db.get("lastId") || 0;
24
+ },
25
+ _setLastId(lastId) {
26
+ this.db.set("lastId", lastId);
27
+ },
28
+ async emitEvent(maxResults = false) {
29
+ const lastId = this._getLastId();
30
+
31
+ const response = this.selzy.paginate({
32
+ fn: this.selzy.getCampaigns,
33
+ });
34
+
35
+ let responseArray = [];
36
+ for await (const item of response) {
37
+ responseArray.push(item);
38
+ }
39
+
40
+ responseArray = responseArray.filter((item) => item.id > lastId).sort((a, b) => b.id - a.id);
41
+
42
+ if (responseArray.length) {
43
+ if (maxResults && (responseArray.length > maxResults)) {
44
+ responseArray.length = maxResults;
45
+ }
46
+
47
+ this._setLastId(responseArray[0].id);
48
+ }
49
+
50
+ for (const item of responseArray.reverse()) {
51
+ this.$emit(item, {
52
+ id: item.id,
53
+ summary: `New campaign created: ${item.id}`,
54
+ ts: Date.now(),
55
+ });
56
+ }
57
+ },
58
+ },
59
+ hooks: {
60
+ async deploy() {
61
+ await this.emitEvent(25);
62
+ },
63
+ },
64
+ async run() {
65
+ await this.emitEvent();
66
+ },
67
+ };
@@ -0,0 +1,11 @@
1
+ export default {
2
+ "id": 326794048,
3
+ "start_time": "2025-06-10 18:12:00",
4
+ "status": "waits_schedule",
5
+ "message_id": 230193688,
6
+ "list_id": 1,
7
+ "subject": "Subject Name",
8
+ "sender_name": "Sender Name",
9
+ "sender_email": "sender@email.com.br",
10
+ "stats_url": "https://api.selzy.com/en/v5/campaigns/123456789"
11
+ }
@@ -0,0 +1,24 @@
1
+ import common from "../common/base.mjs";
2
+ import sampleEmit from "./test-event.mjs";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "selzy-new-campaign-status-instant",
7
+ name: "New Campaign Status (Instant)",
8
+ description: "Emit new event when the status of a campaign changes.",
9
+ version: "0.0.1",
10
+ type: "source",
11
+ dedupe: "unique",
12
+ methods: {
13
+ ...common.methods,
14
+ getEventType() {
15
+ return {
16
+ "events[campaign_status]": "*",
17
+ };
18
+ },
19
+ getSummary(body) {
20
+ return `Campaign status updated to ${body.status}`;
21
+ },
22
+ },
23
+ sampleEmit,
24
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "auth": "974d2fec2b89aeb00195ab4419371b09",
3
+ "login": "ID7208007",
4
+ "event_name": "campaign_status",
5
+ "event_time": "2025-05-16 19:55:56",
6
+ "campaign_id": 326794044,
7
+ "status": "canceled",
8
+ "contact_count": 0,
9
+ "period_messages": 0,
10
+ "prepaid_messages": 0,
11
+ "pay_sum": 0,
12
+ "currency": "USD"
13
+ }
@@ -0,0 +1,37 @@
1
+ import common from "../common/base.mjs";
2
+ import sampleEmit from "./test-event.mjs";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "selzy-new-subscriber-instant",
7
+ name: "New Subscriber (Instant)",
8
+ description: "Emit new event when a new contact subscribes to a specified list.",
9
+ version: "0.0.1",
10
+ type: "source",
11
+ dedupe: "unique",
12
+ props: {
13
+ ...common.props,
14
+ listId: {
15
+ propDefinition: [
16
+ common.props.selzy,
17
+ "listId",
18
+ ],
19
+ description: "Code of the list you want to monitor.",
20
+ optional: true,
21
+ },
22
+ },
23
+ methods: {
24
+ ...common.methods,
25
+ getEventType() {
26
+ return {
27
+ "events[subscribe]": this.listId
28
+ ? this.listId
29
+ : "*",
30
+ };
31
+ },
32
+ getSummary(body) {
33
+ return `New subscriber: ${body.email}`;
34
+ },
35
+ },
36
+ sampleEmit,
37
+ };
@@ -0,0 +1,10 @@
1
+ export default {
2
+ "auth": "21f6bf566f216300c5a6080ecfa89b75",
3
+ "login": "ID2070078",
4
+ "event_name": "subscribe",
5
+ "event_time": "2025-05-16 20:23:28",
6
+ "email": "subscriber@email.com",
7
+ "subscribed_list_ids": [
8
+ 3
9
+ ]
10
+ }