From f34c327bf9301b6543314dc31e36a7dee837128a Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Fri, 7 Mar 2025 12:44:20 -0300 Subject: [PATCH 1/7] [FEATURE] SendGrid - Attachment props #15819 Actions - Send Email Single Recipient - Send Email Multiple Recipients --- .../add-email-to-global-suppression.mjs | 2 +- .../add-or-update-contact/add-or-update-contact.mjs | 2 +- components/sendgrid/actions/common/common.mjs | 7 ++++++- .../create-contact-list/create-contact-list.mjs | 2 +- .../sendgrid/actions/create-send/create-send.mjs | 2 +- .../actions/delete-blocks/delete-blocks.mjs | 2 +- .../actions/delete-bounces/delete-bounces.mjs | 2 +- .../actions/delete-contacts/delete-contacts.mjs | 2 +- .../delete-global-suppression.mjs | 2 +- .../sendgrid/actions/delete-list/delete-list.mjs | 2 +- .../sendgrid/actions/get-a-block/get-a-block.mjs | 2 +- .../get-a-global-suppression.mjs | 2 +- .../actions/get-all-bounces/get-all-bounces.mjs | 2 +- .../actions/get-contact-lists/get-contact-lists.mjs | 2 +- .../sendgrid/actions/list-blocks/list-blocks.mjs | 2 +- .../list-global-suppressions.mjs | 2 +- .../remove-contact-from-list.mjs | 2 +- .../actions/search-contacts/search-contacts.mjs | 2 +- .../send-email-multiple-recipients.mjs | 13 ++++++++++++- .../send-email-single-recipient.mjs | 13 ++++++++++++- .../actions/validate-email/validate-email.mjs | 2 +- components/sendgrid/package.json | 3 ++- components/sendgrid/sendgrid.app.mjs | 2 +- components/sendgrid/sources/events/events.mjs | 2 +- .../sendgrid/sources/new-contact/new-contact.mjs | 2 +- 25 files changed, 53 insertions(+), 25 deletions(-) diff --git a/components/sendgrid/actions/add-email-to-global-suppression/add-email-to-global-suppression.mjs b/components/sendgrid/actions/add-email-to-global-suppression/add-email-to-global-suppression.mjs index 70d9071ab09c3..5bddb087a12b6 100644 --- a/components/sendgrid/actions/add-email-to-global-suppression/add-email-to-global-suppression.mjs +++ b/components/sendgrid/actions/add-email-to-global-suppression/add-email-to-global-suppression.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-add-email-to-global-suppression", name: "Add Email to Global Suppression", description: "Allows you to add one or more email addresses to the global suppressions group. [See the docs here](https://sendgrid.api-docs.io/v3.0/suppressions-global-suppressions/add-recipient-addresses-to-the-global-suppression-group)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/add-or-update-contact/add-or-update-contact.mjs b/components/sendgrid/actions/add-or-update-contact/add-or-update-contact.mjs index 6050fdfdcad74..7ec355ed9dbb7 100644 --- a/components/sendgrid/actions/add-or-update-contact/add-or-update-contact.mjs +++ b/components/sendgrid/actions/add-or-update-contact/add-or-update-contact.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-add-or-update-contact", name: "Add or Update Contact", description: "Adds or updates a contact. [See the docs here](https://docs.sendgrid.com/api-reference/contacts/add-or-update-a-contact)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/common/common.mjs b/components/sendgrid/actions/common/common.mjs index 6ee8f411baf84..f31a9f4fdc146 100644 --- a/components/sendgrid/actions/common/common.mjs +++ b/components/sendgrid/actions/common/common.mjs @@ -171,6 +171,11 @@ export default { } return asmConfig; }, - + checkTmp(filename) { + if (!filename.startsWith("/tmp")) { + return `/tmp/${filename}`; + } + return filename; + }, }, }; diff --git a/components/sendgrid/actions/create-contact-list/create-contact-list.mjs b/components/sendgrid/actions/create-contact-list/create-contact-list.mjs index 4a9492e4955cb..f4b0208a73645 100644 --- a/components/sendgrid/actions/create-contact-list/create-contact-list.mjs +++ b/components/sendgrid/actions/create-contact-list/create-contact-list.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-create-contact-list", name: "Create Contact List", description: "Allows you to create a new contact list. [See the docs here](https://docs.sendgrid.com/api-reference/lists/create-list)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/create-send/create-send.mjs b/components/sendgrid/actions/create-send/create-send.mjs index e12d28cea8f64..0d85f3dfc29b9 100644 --- a/components/sendgrid/actions/create-send/create-send.mjs +++ b/components/sendgrid/actions/create-send/create-send.mjs @@ -7,7 +7,7 @@ export default { key: "sendgrid-create-send", name: "Create Send", description: "Create a single send. [See the docs here](https://www.twilio.com/docs/sendgrid/api-reference/single-sends/create-single-send)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/delete-blocks/delete-blocks.mjs b/components/sendgrid/actions/delete-blocks/delete-blocks.mjs index bc1134e950786..98c1caee1e30c 100644 --- a/components/sendgrid/actions/delete-blocks/delete-blocks.mjs +++ b/components/sendgrid/actions/delete-blocks/delete-blocks.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-delete-blocks", name: "Delete Blocks", description: "Allows you to delete all email addresses on your blocks list. [See the docs here](https://docs.sendgrid.com/api-reference/blocks-api/delete-blocks)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/delete-bounces/delete-bounces.mjs b/components/sendgrid/actions/delete-bounces/delete-bounces.mjs index d04c0d91d6631..bcaecd67c8ed6 100644 --- a/components/sendgrid/actions/delete-bounces/delete-bounces.mjs +++ b/components/sendgrid/actions/delete-bounces/delete-bounces.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-delete-bounces", name: "Delete Bounces", description: "Allows you to delete all emails on your bounces list. [See the docs here](https://docs.sendgrid.com/api-reference/bounces-api/delete-bounces)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/delete-contacts/delete-contacts.mjs b/components/sendgrid/actions/delete-contacts/delete-contacts.mjs index 630f73000c3fc..26fc9db4a4968 100644 --- a/components/sendgrid/actions/delete-contacts/delete-contacts.mjs +++ b/components/sendgrid/actions/delete-contacts/delete-contacts.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-delete-contacts", name: "Delete Contacts", description: "Allows you to delete one or more contacts. [See the docs here](https://docs.sendgrid.com/api-reference/contacts/delete-contacts)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/delete-global-suppression/delete-global-suppression.mjs b/components/sendgrid/actions/delete-global-suppression/delete-global-suppression.mjs index a854cec3c5056..4c85fdfe68be7 100644 --- a/components/sendgrid/actions/delete-global-suppression/delete-global-suppression.mjs +++ b/components/sendgrid/actions/delete-global-suppression/delete-global-suppression.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-delete-global-suppression", name: "Delete Global Suppression", description: "Allows you to remove an email address from the global suppressions group. [See the docs here](https://docs.sendgrid.com/api-reference/suppressions-global-suppressions/delete-a-global-suppression)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/delete-list/delete-list.mjs b/components/sendgrid/actions/delete-list/delete-list.mjs index fcbf401a01dd1..803b796f828fb 100644 --- a/components/sendgrid/actions/delete-list/delete-list.mjs +++ b/components/sendgrid/actions/delete-list/delete-list.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-delete-list", name: "Delete List", description: "Allows you to delete a specific contact list. [See the docs here](https://docs.sendgrid.com/api-reference/lists/delete-a-list)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/get-a-block/get-a-block.mjs b/components/sendgrid/actions/get-a-block/get-a-block.mjs index 923276deada11..c6d88f59c2614 100644 --- a/components/sendgrid/actions/get-a-block/get-a-block.mjs +++ b/components/sendgrid/actions/get-a-block/get-a-block.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-get-a-block", name: "Get a Block", description: "Gets a specific block. [See the docs here](https://docs.sendgrid.com/api-reference/blocks-api/retrieve-a-specific-block)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/get-a-global-suppression/get-a-global-suppression.mjs b/components/sendgrid/actions/get-a-global-suppression/get-a-global-suppression.mjs index 775c795c759a9..407d4710f4cd0 100644 --- a/components/sendgrid/actions/get-a-global-suppression/get-a-global-suppression.mjs +++ b/components/sendgrid/actions/get-a-global-suppression/get-a-global-suppression.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-get-a-global-suppression", name: "Get A Global Suppression", description: "Gets a global suppression. [See the docs here](https://docs.sendgrid.com/api-reference/suppressions-global-suppressions/retrieve-a-global-suppression)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/get-all-bounces/get-all-bounces.mjs b/components/sendgrid/actions/get-all-bounces/get-all-bounces.mjs index 5bd9a6cf4224d..f4d6aa01806f0 100644 --- a/components/sendgrid/actions/get-all-bounces/get-all-bounces.mjs +++ b/components/sendgrid/actions/get-all-bounces/get-all-bounces.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-get-all-bounces", name: "Get All Bounces", description: "Allows you to get all of your bounces. [See the docs here](https://docs.sendgrid.com/api-reference/bounces-api/retrieve-all-bounces)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/get-contact-lists/get-contact-lists.mjs b/components/sendgrid/actions/get-contact-lists/get-contact-lists.mjs index fe1c4d38fb4fb..893efa599c9bf 100644 --- a/components/sendgrid/actions/get-contact-lists/get-contact-lists.mjs +++ b/components/sendgrid/actions/get-contact-lists/get-contact-lists.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-get-contact-lists", name: "Get Contact Lists", description: "Allows you to get details of your contact lists. [See the docs here](https://docs.sendgrid.com/api-reference/lists/get-all-lists)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/list-blocks/list-blocks.mjs b/components/sendgrid/actions/list-blocks/list-blocks.mjs index d4607dc9e483a..47ecaed0844f2 100644 --- a/components/sendgrid/actions/list-blocks/list-blocks.mjs +++ b/components/sendgrid/actions/list-blocks/list-blocks.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-list-blocks", name: "List Blocks", description: "Allows you to list all email addresses that are currently on your blocks list. [See the docs here](https://docs.sendgrid.com/api-reference/blocks-api/retrieve-all-blocks)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/list-global-suppressions/list-global-suppressions.mjs b/components/sendgrid/actions/list-global-suppressions/list-global-suppressions.mjs index 8aa2b55933258..25040a63afc5d 100644 --- a/components/sendgrid/actions/list-global-suppressions/list-global-suppressions.mjs +++ b/components/sendgrid/actions/list-global-suppressions/list-global-suppressions.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-list-global-suppressions", name: "List Global Suppressions", description: "Allows you to get a list of all email address that are globally suppressed. [See the docs here](https://docs.sendgrid.com/api-reference/suppressions-global-suppressions/retrieve-all-global-suppressions)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/remove-contact-from-list/remove-contact-from-list.mjs b/components/sendgrid/actions/remove-contact-from-list/remove-contact-from-list.mjs index 52621eabb57a8..a6e8f88966479 100644 --- a/components/sendgrid/actions/remove-contact-from-list/remove-contact-from-list.mjs +++ b/components/sendgrid/actions/remove-contact-from-list/remove-contact-from-list.mjs @@ -5,7 +5,7 @@ export default { key: "sendgrid-remove-contact-from-list", name: "Remove Contact From List", description: "Allows you to remove contacts from a given list. [See the docs here](https://docs.sendgrid.com/api-reference/lists/remove-contacts-from-a-list)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/search-contacts/search-contacts.mjs b/components/sendgrid/actions/search-contacts/search-contacts.mjs index b0feca6388420..1e3fed3957ef9 100644 --- a/components/sendgrid/actions/search-contacts/search-contacts.mjs +++ b/components/sendgrid/actions/search-contacts/search-contacts.mjs @@ -7,7 +7,7 @@ export default { key: "sendgrid-search-contacts", name: "Search Contacts", description: "Searches contacts with a SGQL query. [See the docs here](https://docs.sendgrid.com/api-reference/contacts/search-contacts)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs index a2a1f23ea035b..97ba1c79d9def 100644 --- a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs +++ b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs @@ -1,3 +1,4 @@ +import fs from "fs"; import validate from "validate.js"; import common from "../common/common.mjs"; @@ -6,7 +7,7 @@ export default { key: "sendgrid-send-email-multiple-recipients", name: "Send Email Multiple Recipients", description: "This action sends a personalized e-mail to multiple specified recipients. [See the docs here](https://docs.sendgrid.com/api-reference/mail-send/mail-send)", - version: "0.0.5", + version: "0.0.6", type: "action", props: { ...common.props, @@ -186,6 +187,16 @@ export default { }, }; attachments = this.getArrayObject(this.attachments); + attachments.map((attachment) => { + if (attachment.filepath) { + const filepath = this.checkTmp(attachment.filepath); + attachment.content = fs.readFileSync(filepath, { + encoding: "base64", + }); + } + delete attachment.filepath; + return attachment; + }); } if (this.categories) { constraints.categories = { diff --git a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs index 1514ce68d1b8d..3f5cd22b8a8f5 100644 --- a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs +++ b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs @@ -1,3 +1,4 @@ +import fs from "fs"; import validate from "validate.js"; import common from "../common/common.mjs"; @@ -6,7 +7,7 @@ export default { key: "sendgrid-send-email-single-recipient", name: "Send Email Single Recipient", description: "This action sends a personalized e-mail to the specified recipient. [See the docs here](https://docs.sendgrid.com/api-reference/mail-send/mail-send)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { ...common.props, @@ -211,6 +212,16 @@ export default { }, }; attachments = this.getArrayObject(this.attachments); + attachments.map((attachment) => { + if (attachment.filepath) { + const filepath = this.checkTmp(attachment.filepath); + attachment.content = fs.readFileSync(filepath, { + encoding: "base64", + }); + } + delete attachment.filepath; + return attachment; + }); } if (this.categories) { constraints.categories = { diff --git a/components/sendgrid/actions/validate-email/validate-email.mjs b/components/sendgrid/actions/validate-email/validate-email.mjs index 4d1fd7b07248c..36ed8a975356d 100644 --- a/components/sendgrid/actions/validate-email/validate-email.mjs +++ b/components/sendgrid/actions/validate-email/validate-email.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-validate-email", name: "Validate Email", description: "Validates an email address. This action requires a Sendgrid's Pro or Premier plan. [See the docs here](https://docs.sendgrid.com/api-reference/e-mail-address-validation/validate-an-email)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { ...common.props, diff --git a/components/sendgrid/package.json b/components/sendgrid/package.json index d09b9a5814181..eb437fa7eb4d1 100644 --- a/components/sendgrid/package.json +++ b/components/sendgrid/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/sendgrid", - "version": "0.4.0", + "version": "0.4.1", "description": "Pipedream Sendgrid Components", "main": "sendgrid.app.js", "keywords": [ @@ -14,6 +14,7 @@ "@sendgrid/client": "^7.6.2", "@sendgrid/eventwebhook": "^7.4.5", "async-retry": "^1.3.1", + "fs": "^0.0.1-security", "lodash": "^4.17.20", "uuid": "^8.3.2", "validate.js": "^0.13.1" diff --git a/components/sendgrid/sendgrid.app.mjs b/components/sendgrid/sendgrid.app.mjs index 49fef6ab87c7b..c7220c746fb89 100644 --- a/components/sendgrid/sendgrid.app.mjs +++ b/components/sendgrid/sendgrid.app.mjs @@ -216,7 +216,7 @@ export default { attachments: { type: "string", label: "Attachments", - description: "An array of objects where you can specify any attachments you want to include. The fields `content` and `filename` are required. `content` must be base64 encoded. Alternatively, provide a string that will `JSON.parse` to an array of attachments objects. Example: `[{content:\"aGV5\",type:\"text/plain\",filename:\"sample.txt\"}]`", + description: "An array of objects where you can specify any attachments you want to include. The fields `content` and `filename` are required. `content` must be base64 encoded. Alternatively, provide a string that will `JSON.parse` to an array of attachments objects. Example: `[{content:\"aGV5\",filepath:\"/tmp/file.txt\",type:\"text/plain\",filename:\"sample.txt\"}]` `You must provide either content in base64 or path to the /temp file`", optional: true, }, headers: { diff --git a/components/sendgrid/sources/events/events.mjs b/components/sendgrid/sources/events/events.mjs index 149604cee4344..ba24afc90ba0f 100644 --- a/components/sendgrid/sources/events/events.mjs +++ b/components/sendgrid/sources/events/events.mjs @@ -7,7 +7,7 @@ export default { key: "sendgrid-events", name: "New Events (Instant)", description: "Emit new event when any of the specified SendGrid events is received", - version: "0.0.6", + version: "0.0.7", type: "source", dedupe: "unique", props: { diff --git a/components/sendgrid/sources/new-contact/new-contact.mjs b/components/sendgrid/sources/new-contact/new-contact.mjs index ec0a897278805..20eeeee9fe5fc 100644 --- a/components/sendgrid/sources/new-contact/new-contact.mjs +++ b/components/sendgrid/sources/new-contact/new-contact.mjs @@ -6,7 +6,7 @@ export default { key: "sendgrid-new-contact", name: "New Contact", description: "Emit new event when a new contact is created", - version: "0.0.7", + version: "0.0.8", type: "source", dedupe: "unique", hooks: { From 6eeefa114ea218416ae437dd8fbf5672bd3453dc Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Fri, 7 Mar 2025 12:45:58 -0300 Subject: [PATCH 2/7] pnpm update --- pnpm-lock.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72803b66e9347..7ce539b9306bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10079,8 +10079,7 @@ importers: components/qwilr: {} - components/rabbitmq: - specifiers: {} + components/rabbitmq: {} components/radar: {} @@ -11133,6 +11132,9 @@ importers: async-retry: specifier: ^1.3.1 version: 1.3.3 + fs: + specifier: ^0.0.1-security + version: 0.0.1-security lodash: specifier: ^4.17.20 version: 4.17.21 @@ -11274,8 +11276,7 @@ importers: specifier: ^3.0.0 version: 3.0.3 - components/servicetitan: - specifiers: {} + components/servicetitan: {} components/serwersms_pl: {} From 8a3598fba401af1d0176b65c7a81080ad486cc0e Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 11 Mar 2025 18:04:32 -0300 Subject: [PATCH 3/7] some adjusts --- .../send-email-multiple-recipients.mjs | 62 ++++++++++++------- .../send-email-single-recipient.mjs | 62 ++++++++++++------- components/sendgrid/sendgrid.app.mjs | 9 +-- 3 files changed, 81 insertions(+), 52 deletions(-) diff --git a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs index 97ba1c79d9def..cc0c2d89b75d1 100644 --- a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs +++ b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs @@ -74,12 +74,6 @@ export default { ], optional: true, }, - attachments: { - propDefinition: [ - common.props.sendgrid, - "attachments", - ], - }, headers: { propDefinition: [ common.props.sendgrid, @@ -140,6 +134,33 @@ export default { "trackingSettings", ], }, + numberOfAttachments: { + propDefinition: [ + common.props.sendgrid, + "numberOfAttachments", + ], + optional: true, + }, + }, + async additionalProps() { + const props = {}; + if (this.numberOfAttachments) { + for (let i = 1; i <= this.numberOfAttachments; i++) { + props[`attachmentsName${i}`] = { + type: "string", + label: `Attachment File Name ${i}`, + description: "The name of the file.", + optional: true, + }; + props[`attachmentsPath${i}`] = { + type: "string", + label: `Attachment File Path ${i}`, + description: "The path to your file in /tmp dir. [See the documentation](https://pipedream.com/docs/code/nodejs/working-with-files/#writing-a-file-to-tmp) for how to work with tmp dir.", + optional: true, + }; + } + } + return props; }, async run({ $ }) { const personalizations = this.personalizations || []; @@ -178,26 +199,19 @@ export default { email: true, }; } - let attachments = this.convertEmptyStringToUndefined(this.attachments); - if (this.attachments) { - constraints.attachments = { - arrayValidator: { - value: this.attachments, - key: "attachments", - }, - }; - attachments = this.getArrayObject(this.attachments); - attachments.map((attachment) => { - if (attachment.filepath) { - const filepath = this.checkTmp(attachment.filepath); - attachment.content = fs.readFileSync(filepath, { - encoding: "base64", - }); - } - delete attachment.filepath; - return attachment; + const attachments = []; + for (let i = 1; i <= this.numberOfAttachments; i++) { + const filepath = this.checkTmp(this["attachmentsPath" + i]); + const content = fs.readFileSync(filepath, { + encoding: "base64", + }); + attachments.push({ + content, + type: "text/plain", + filename: this[`attachmentsName${i}`], }); } + if (this.categories) { constraints.categories = { type: "array", diff --git a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs index 3f5cd22b8a8f5..2d79da6a5704b 100644 --- a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs +++ b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs @@ -97,12 +97,6 @@ export default { ], optional: true, }, - attachments: { - propDefinition: [ - common.props.sendgrid, - "attachments", - ], - }, headers: { propDefinition: [ common.props.sendgrid, @@ -163,6 +157,33 @@ export default { "trackingSettings", ], }, + numberOfAttachments: { + propDefinition: [ + common.props.sendgrid, + "numberOfAttachments", + ], + optional: true, + }, + }, + async additionalProps() { + const props = {}; + if (this.numberOfAttachments) { + for (let i = 1; i <= this.numberOfAttachments; i++) { + props[`attachmentsName${i}`] = { + type: "string", + label: `Attachment File Name ${i}`, + description: "The name of the file.", + optional: true, + }; + props[`attachmentsPath${i}`] = { + type: "string", + label: `Attachment File Path ${i}`, + description: "The path to your file in /tmp dir. [See the documentation](https://pipedream.com/docs/code/nodejs/working-with-files/#writing-a-file-to-tmp) for how to work with tmp dir.", + optional: true, + }; + } + } + return props; }, async run({ $ }) { //Performs validation on parameters. @@ -203,26 +224,19 @@ export default { }, }; } - let attachments = this.convertEmptyStringToUndefined(this.attachments); - if (this.attachments) { - constraints.attachments = { - arrayValidator: { - value: this.attachments, - key: "attachments", - }, - }; - attachments = this.getArrayObject(this.attachments); - attachments.map((attachment) => { - if (attachment.filepath) { - const filepath = this.checkTmp(attachment.filepath); - attachment.content = fs.readFileSync(filepath, { - encoding: "base64", - }); - } - delete attachment.filepath; - return attachment; + const attachments = []; + for (let i = 1; i <= this.numberOfAttachments; i++) { + const filepath = this.checkTmp(this["attachmentsPath" + i]); + const content = fs.readFileSync(filepath, { + encoding: "base64", + }); + attachments.push({ + content, + type: "text/plain", + filename: this[`attachmentsName${i}`], }); } + if (this.categories) { constraints.categories = { type: "array", diff --git a/components/sendgrid/sendgrid.app.mjs b/components/sendgrid/sendgrid.app.mjs index c7220c746fb89..4641f7a3db14c 100644 --- a/components/sendgrid/sendgrid.app.mjs +++ b/components/sendgrid/sendgrid.app.mjs @@ -213,10 +213,11 @@ export default { label: "Content", description: "Content of the email in `text/html`", }, - attachments: { - type: "string", - label: "Attachments", - description: "An array of objects where you can specify any attachments you want to include. The fields `content` and `filename` are required. `content` must be base64 encoded. Alternatively, provide a string that will `JSON.parse` to an array of attachments objects. Example: `[{content:\"aGV5\",filepath:\"/tmp/file.txt\",type:\"text/plain\",filename:\"sample.txt\"}]` `You must provide either content in base64 or path to the /temp file`", + numberOfAttachments: { + type: "integer", + label: "Number Of Attachments", + description: "The number of attachments to be sent with the email.", + reloadProps: true, optional: true, }, headers: { From 9ba89cb9745e938dc646b77e42f7d23c00868718 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 12 Mar 2025 13:15:09 -0300 Subject: [PATCH 4/7] some adjusts --- .../send-email-multiple-recipients.mjs | 30 ++++++++++++------- .../send-email-single-recipient.mjs | 8 +++-- components/sendgrid/package.json | 1 + components/sendgrid/sendgrid.app.mjs | 2 +- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs index cc0c2d89b75d1..fd28e41812062 100644 --- a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs +++ b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs @@ -1,4 +1,6 @@ +import { ConfigurationError } from "@pipedream/platform"; import fs from "fs"; +import mime from "mime"; import validate from "validate.js"; import common from "../common/common.mjs"; @@ -163,17 +165,22 @@ export default { return props; }, async run({ $ }) { + if (!this.personalizations && !this.toEmails) { + throw new ConfigurationError("Please input either Personalization or Recipient Emails."); + } const personalizations = this.personalizations || []; if (personalizations.length == 0) { - for (const toEmail of this.toEmails) { - const personalization = { - to: [ - { - email: toEmail, - }, - ], - }; - personalizations.push(personalization); + if (this.convertEmptyStringToUndefined(this.toEmails)) { + for (const toEmail of this.toEmails) { + const personalization = { + to: [ + { + email: toEmail, + }, + ], + }; + personalizations.push(personalization); + } } } if (this.dynamicTemplateData) { @@ -205,9 +212,10 @@ export default { const content = fs.readFileSync(filepath, { encoding: "base64", }); + const type = mime.getType(filepath); attachments.push({ content, - type: "text/plain", + type, filename: this[`attachmentsName${i}`], }); } @@ -217,7 +225,7 @@ export default { type: "array", }; } - this.sendAt = this.convertEmptyStringToUndefined(this.sendAt); + this.sendAt = this.convertEmptyStringToUndefined(Date.parse(this.sendAt)); if (this.sendAt != null) { constraints.sendAt = this.getIntegerGtZeroConstraint(); } diff --git a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs index 2d79da6a5704b..f3bc22ba1e88a 100644 --- a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs +++ b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs @@ -1,4 +1,5 @@ import fs from "fs"; +import mime from "mime"; import validate from "validate.js"; import common from "../common/common.mjs"; @@ -7,7 +8,7 @@ export default { key: "sendgrid-send-email-single-recipient", name: "Send Email Single Recipient", description: "This action sends a personalized e-mail to the specified recipient. [See the docs here](https://docs.sendgrid.com/api-reference/mail-send/mail-send)", - version: "0.0.8", + version: "0.0.1", type: "action", props: { ...common.props, @@ -230,9 +231,10 @@ export default { const content = fs.readFileSync(filepath, { encoding: "base64", }); + const type = mime.getType(filepath); attachments.push({ content, - type: "text/plain", + type, filename: this[`attachmentsName${i}`], }); } @@ -247,7 +249,7 @@ export default { email: true, }; } - this.sendAt = this.convertEmptyStringToUndefined(this.sendAt); + this.sendAt = this.convertEmptyStringToUndefined(Date.parse(this.sendAt)); if (this.sendAt != null) { constraints.sendAt = this.getIntegerGtZeroConstraint(); } diff --git a/components/sendgrid/package.json b/components/sendgrid/package.json index eb437fa7eb4d1..bcf938ed25b69 100644 --- a/components/sendgrid/package.json +++ b/components/sendgrid/package.json @@ -16,6 +16,7 @@ "async-retry": "^1.3.1", "fs": "^0.0.1-security", "lodash": "^4.17.20", + "mime": "^4.0.6", "uuid": "^8.3.2", "validate.js": "^0.13.1" }, diff --git a/components/sendgrid/sendgrid.app.mjs b/components/sendgrid/sendgrid.app.mjs index 4641f7a3db14c..9b48ce9142591 100644 --- a/components/sendgrid/sendgrid.app.mjs +++ b/components/sendgrid/sendgrid.app.mjs @@ -241,7 +241,7 @@ export default { sendAt: { type: "integer", label: "Send At", - description: "A unix timestamp allowing you to specify when you want your email to be delivered. This may be overridden by the `send_at` parameter set at the personalizations level. Delivery cannot be scheduled more than 72 hours in advance. If you have the flexibility, it's better to schedule mail for off-peak times. Most emails are scheduled and sent at the top of the hour or half hour. Scheduling email to avoid peak times — for example, scheduling at 10:53 — can result in lower deferral rates due to the reduced traffic during off-peak times.", + description: "An ISO 8601 formatted date-time (YYYY-MM-DDTHH:MM:SSZ) allowing you to specify when you want your email to be delivered. This may be overridden by the `send_at` parameter set at the personalizations level. Delivery cannot be scheduled more than 72 hours in advance. If you have the flexibility, it's better to schedule mail for off-peak times. Most emails are scheduled and sent at the top of the hour or half hour. Scheduling email to avoid peak times — for example, scheduling at 10:53 — can result in lower deferral rates due to the reduced traffic during off-peak times.", optional: true, }, asm: { From 2c9a0cb403310348eec30390a037fad9edea85ac Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 12 Mar 2025 13:16:45 -0300 Subject: [PATCH 5/7] pnpm update --- pnpm-lock.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ce539b9306bf..5a5fd25c0af2a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11138,6 +11138,9 @@ importers: lodash: specifier: ^4.17.20 version: 4.17.21 + mime: + specifier: ^4.0.6 + version: 4.0.6 uuid: specifier: ^8.3.2 version: 8.3.2 From ee4eae101765e553272106f959d600ed382a716c Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 13 Mar 2025 12:15:33 -0300 Subject: [PATCH 6/7] some adjusts --- components/sendgrid/actions/common/common.mjs | 3 +++ .../send-email-multiple-recipients.mjs | 2 +- .../send-email-single-recipient.mjs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/components/sendgrid/actions/common/common.mjs b/components/sendgrid/actions/common/common.mjs index f31a9f4fdc146..c115f30194015 100644 --- a/components/sendgrid/actions/common/common.mjs +++ b/components/sendgrid/actions/common/common.mjs @@ -93,6 +93,9 @@ export default { * @param {object} value the value to check for returning `undefined`. */ convertEmptyStringToUndefined(value) { + if (Array.isArray(value) && value.length === 0) { + return undefined; + } if (value === "" || value === null) { return undefined; } diff --git a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs index fd28e41812062..abd77ce522085 100644 --- a/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs +++ b/components/sendgrid/actions/send-email-multiple-recipients/send-email-multiple-recipients.mjs @@ -226,7 +226,7 @@ export default { }; } this.sendAt = this.convertEmptyStringToUndefined(Date.parse(this.sendAt)); - if (this.sendAt != null) { + if (this.sendAt) { constraints.sendAt = this.getIntegerGtZeroConstraint(); } if (this.asm || this.asmGroupsToDisplay) { diff --git a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs index f3bc22ba1e88a..9cba50ecb0400 100644 --- a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs +++ b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs @@ -250,7 +250,7 @@ export default { }; } this.sendAt = this.convertEmptyStringToUndefined(Date.parse(this.sendAt)); - if (this.sendAt != null) { + if (this.sendAt) { constraints.sendAt = this.getIntegerGtZeroConstraint(); } //Executes validation From a91fb2d5a09bf6050bcce0dbcfe6be48ec032e94 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 13 Mar 2025 12:17:26 -0300 Subject: [PATCH 7/7] Update components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../send-email-single-recipient/send-email-single-recipient.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs index 9cba50ecb0400..5299dfde6627d 100644 --- a/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs +++ b/components/sendgrid/actions/send-email-single-recipient/send-email-single-recipient.mjs @@ -8,7 +8,7 @@ export default { key: "sendgrid-send-email-single-recipient", name: "Send Email Single Recipient", description: "This action sends a personalized e-mail to the specified recipient. [See the docs here](https://docs.sendgrid.com/api-reference/mail-send/mail-send)", - version: "0.0.1", + version: "0.0.8", type: "action", props: { ...common.props,