From 3746ed35de52d610c1de94eb931b783cc64ace03 Mon Sep 17 00:00:00 2001 From: Byron Sommardahl Date: Thu, 1 Sep 2022 08:46:51 -0500 Subject: [PATCH 1/4] Adding actions to send emails via SMTP2GO (Fixes #3966) --- components/smtp2go/actions/common.ts | 130 ++++++++++++++++++ .../send-single-email-with-template.ts | 40 ++++++ .../send-single-email/send-single-email.ts | 51 +++++++ components/smtp2go/app/smtp2go.app.ts | 13 -- components/smtp2go/package.json | 4 +- components/smtp2go/smtp2go.app.ts | 52 +++++++ 6 files changed, 275 insertions(+), 15 deletions(-) create mode 100644 components/smtp2go/actions/common.ts create mode 100644 components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts create mode 100644 components/smtp2go/actions/send-single-email/send-single-email.ts delete mode 100644 components/smtp2go/app/smtp2go.app.ts create mode 100644 components/smtp2go/smtp2go.app.ts diff --git a/components/smtp2go/actions/common.ts b/components/smtp2go/actions/common.ts new file mode 100644 index 0000000000000..48eb548b02749 --- /dev/null +++ b/components/smtp2go/actions/common.ts @@ -0,0 +1,130 @@ +import smtp2go from "../smtp2go.app"; + +export default { + props: { + smtp2go, + fromEmail: { + type: "string", + label: "\"From\" email address", + description: + "The sender email address. To include a name, use the format 'Full Name <sender@domain.com>' for the address.", + }, + toEmail: { + type: "string", + label: "Recipient email address(es)", + description: + "Recipient email address. Multiple addresses are comma separated. Max 50.", + }, + ccEmail: { + type: "string", + label: "CC email address(es)", + description: + "Cc recipient email address. Multiple addresses are comma separated. Max 50.", + optional: true, + }, + bccEmail: { + type: "string", + label: "BCC email address(es)", + description: + "Bcc recipient email address. Multiple addresses are comma separated. Max 50.", + optional: true, + }, + replyTo: { + type: "string", + label: "\"Reply To\" email address", + description: + "Reply To override email address. Defaults to the Reply To set in the sender signature.", + optional: true, + }, + customHeaders: { + type: "string[]", + label: "Custom Headers", + description: `List of custom headers to include. + \\ + Each attachment should be a string with the parameters separated by a pipe character \`|\`, in the format: \`header|value\`. Alternatively, you can pass a string representing an object. Both parameters are required: + \\ + \\ + \`header\` - the header key name, i.e. \`some-header\` + \\ + \`value\` - the string value of the header, i.e. \`the-value\` + \\ + \\ + Example with pipe-separated parameters: \`some-custom-header|the-value\` + \\ + Example with JSON-stringified object: \`{"header":"some-custom-header","value":"the-value"}\` + `, + optional: true, + }, + attachments: { + type: "string[]", + label: "Attachments", + description: `List of attachments to include. + \\ + Each attachment should be a string with the parameters separated by a pipe character \`|\`, in the format: \`Name|Content|ContentType\`. Alternatively, you can pass a string representing an object. All three parameters are required: + \\ + \\ + \`filename\` - the filename with extension, i.e. \`readme.txt\` + \\ + \`fileblob\` - the base64-encoded string with the binary data for the file, i.e. \`dGVzdCBjb250ZW50\` + \\ + \`mimetype\` - the MIME content type, i.e. \`text/plain\` + \\ + \\ + Example with pipe-separated parameters: \`readme.txt|dGVzdCBjb250ZW50|text/plain\` + \\ + Example with JSON-stringified object: \`{"filename":"readme.txt","fileblob":"dGVzdCBjb250ZW50","mimetype":"text/plain"}\` + `, + optional: true, + }, + ignoreFailures: { + type: "boolean", + label: "Ignore Failures", + description: "Should this action ignore failures to send an email?", + optional: true + } + }, + methods: { + getActionRequestCommonData() { + return { + from: this.fromEmail, + to: this.toEmail, + cc: this.ccEmail, + bcc: this.bccEmail, + reply_to: this.replyTo, + custom_headers: [...this.getHeaderData(this.customHeaders), ...this.getReplyToHeaders(this.replyTo)], + attachments: this.getAttachmentData(this.attachments) + }; + }, + getAttachmentData(attachments: any[]) { + return attachments?.map((str) => { + let params = str.split("|"); + return params.length === 3 + ? { + filename: params[0], + fileblob: params[1], + mimetype: params[2], + } + : JSON.parse(str); + }); + }, + getReplyToHeaders(replyToEmail: string) { + return reply_to ? [ + { + header: "Reply-To", + value: reply_to + } + ] : []; + }, + getCustomHeaderData(headers: any[]) { + return headers?.map((str) => { + let params = str.split("|"); + return params.length === 2 + ? { + header: params[0], + value: params[1] + } + : JSON.parse(str); + }); + }, + }, +}; diff --git a/components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts b/components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts new file mode 100644 index 0000000000000..745556194b18c --- /dev/null +++ b/components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts @@ -0,0 +1,40 @@ +import common from "../common.mjs"; + +export default { + ...common, + key: "smtp2go-send-single-email", + name: "Send Single Email with Template", + description: "Send a single email with SMTP2GO using a pre-defined template and data object [(See docs here)](https://apidoc.smtp2go.com/documentation/#/POST%20/email/send)", + version: "0.1.0", + type: "action", + props: { + subject: { + type: "string", + label: "Subject", + description: "Email subject.", + }, + templateId: { + type: "string", + label: "Template ID", + description: "The ID of the pre-defined template in SMTP2GO.", + }, + templateModel: { + type: "object", + label: "Template Model", + description: + "The model to be applied to the specified template to generate the email body and subject.", + }, + // The above props are intentionally placed first + ...common.props, + }, + async run({ $ }) { + const data = { + ...this.getActionRequestCommonData(), + template_id: this.templateId, + template_data: this.templateModel + }; + const response = await this.smtp2go.sendSingleEmailWithTemplate($, data, this.ignoreFailures); + $.export("$summary", "Sent email successfully"); + return response; + }, +}; diff --git a/components/smtp2go/actions/send-single-email/send-single-email.ts b/components/smtp2go/actions/send-single-email/send-single-email.ts new file mode 100644 index 0000000000000..19364740b6d83 --- /dev/null +++ b/components/smtp2go/actions/send-single-email/send-single-email.ts @@ -0,0 +1,51 @@ +import common from "../common.mjs"; + +export default { + ...common, + key: "smtp2go-send-single-email", + name: "Send Single Email", + description: "Send a single email with SMTP2GO [(See docs here)](https://apidoc.smtp2go.com/documentation/#/POST%20/email/send)", + version: "0.1.0", + type: "action", + props: { + subject: { + type: "string", + label: "Subject", + description: "Email subject.", + }, + htmlBody: { + type: "string", + label: "HTML Body", + description: + `HTML email message. + \\ + **Required** if no \`Text Body\` is specified.`, + optional: true, + }, + textBody: { + type: "string", + label: "Text Body", + description: + `Plain text email message. + \\ + **Required** if no \`HTML Body\` is specified.`, + optional: true, + }, + // The above props are intentionally placed first + ...common.props, + }, + async run({ $ }) { + const data = { + ...this.getActionRequestCommonData(), + subject: this.subject, + html_body: this.htmlBody, + text_body: this.textBody + }; + if(!data.html_body && !data.text_body){ + throw new Error("You must have EITHER a text body or an html body. Neither were provided."); + } + const response = await this.smtp2go.sendSingleEmail($, data, this.ignoreFailures); + $.export("$summary", "Sent email successfully"); + return response; + }, +}; diff --git a/components/smtp2go/app/smtp2go.app.ts b/components/smtp2go/app/smtp2go.app.ts deleted file mode 100644 index 57ea73fb3b567..0000000000000 --- a/components/smtp2go/app/smtp2go.app.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineApp } from "@pipedream/types"; - -export default defineApp({ - type: "app", - app: "smtp2go", - propDefinitions: {}, - methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); - }, - }, -}); \ No newline at end of file diff --git a/components/smtp2go/package.json b/components/smtp2go/package.json index 5a431815a1b26..d3e69f83e419a 100644 --- a/components/smtp2go/package.json +++ b/components/smtp2go/package.json @@ -1,8 +1,8 @@ { "name": "@pipedream/smtp2go", "version": "0.0.1", - "description": "Pipedream SMTP2GO Components", - "main": "dist/app/smtp2go.app.mjs", + "description": "Pipedream SMTP2GO Components", + "main": "dist/smtp2go.app.ts", "keywords": [ "pipedream", "smtp2go" diff --git a/components/smtp2go/smtp2go.app.ts b/components/smtp2go/smtp2go.app.ts new file mode 100644 index 0000000000000..76ae8a5eff259 --- /dev/null +++ b/components/smtp2go/smtp2go.app.ts @@ -0,0 +1,52 @@ +import { axios } from "@pipedream/platform"; + +export default { + type: "app", + app: "smtp2go", + methods: { + _apikey() { + return this.$auth.api_key; + }, + getHeaders() { + return { + "Content-Type": "application/json", + }; + }, + async sharedRequest($, params) { + const { + endpoint, + method, + data, + } = params; + + return axios($, { + url: `https://api.smtp2go.com/v3/${endpoint}`, + method, + headers: this.getHeaders(), + data: { ...data, api_key: this._apikey }, + }); + }, + async sharedActionRequest($, endpoint: string, data: any) { + return this.sharedRequest($, { + endpoint, + method: "POST", + data, + }); + }, + verifiedSent(result){ + if(result.data.failed>0){ + throw new Error(`Mail sender responded with the following error(s): ${string.join(result.data.failures, ",")}`); + } + }, + async sendSingleEmail($, data: { sender: string, to: string[], cc: string[], bcc: string[], subject: string, text_body: string, html_body: string, attachments: any[], custom_headers: any[] }, ignoreFailures: boolean) { + const result = this.sharedActionRequest($, "email/send", data); + if(ignoreFailures) return result; + return this.verifiedSent(result); + }, + async sendSingleEmailWithTemplate($, data: { sender: string, to: string[], cc: string[], bcc: string[], subject: string, template_id: string, template_data: any, attachments: any[], custom_headers: any[] }, ignoreFailures: boolean) { + const result = this.sharedActionRequest($, "email/send", data); + if(ignoreFailures) return result; + return this.verifiedSent(result); + } + }, +}; From 4695bc12136a1bd5c44820c4b432755b1af22832 Mon Sep 17 00:00:00 2001 From: Byron Sommardahl Date: Thu, 1 Sep 2022 14:30:47 -0500 Subject: [PATCH 2/4] Adding a new line. :) --- components/smtp2go/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/smtp2go/package.json b/components/smtp2go/package.json index d3e69f83e419a..1dcfebea2349a 100644 --- a/components/smtp2go/package.json +++ b/components/smtp2go/package.json @@ -14,4 +14,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} From aecaf8276afc0dd79ade9619d6d54e64159fa313 Mon Sep 17 00:00:00 2001 From: Lucas Caresia Date: Fri, 2 Sep 2022 13:54:09 -0300 Subject: [PATCH 3/4] Update send-single-email-with-template.ts --- .../send-single-email-with-template.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts b/components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts index 745556194b18c..4925546d94abd 100644 --- a/components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts +++ b/components/smtp2go/actions/send-single-email-with-template/send-single-email-with-template.ts @@ -34,7 +34,7 @@ export default { template_data: this.templateModel }; const response = await this.smtp2go.sendSingleEmailWithTemplate($, data, this.ignoreFailures); - $.export("$summary", "Sent email successfully"); + $.export("$summary", `Sent email successfully with email ID ${response.data.email_id}`); return response; }, }; From 97822a2a895a2550437db1d9a6ed2644bf1189f6 Mon Sep 17 00:00:00 2001 From: Lucas Caresia Date: Fri, 2 Sep 2022 13:54:47 -0300 Subject: [PATCH 4/4] Update send-single-email.ts --- .../smtp2go/actions/send-single-email/send-single-email.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/smtp2go/actions/send-single-email/send-single-email.ts b/components/smtp2go/actions/send-single-email/send-single-email.ts index 19364740b6d83..e4f777260ed85 100644 --- a/components/smtp2go/actions/send-single-email/send-single-email.ts +++ b/components/smtp2go/actions/send-single-email/send-single-email.ts @@ -45,7 +45,7 @@ export default { throw new Error("You must have EITHER a text body or an html body. Neither were provided."); } const response = await this.smtp2go.sendSingleEmail($, data, this.ignoreFailures); - $.export("$summary", "Sent email successfully"); + $.export("$summary", `Sent email successfully with email ID ${response.data.email_id}`); return response; }, };