import { ConfigurationError } from "@pipedream/platform";
import fs from "fs";
import mime from "mime";
import validate from "validate.js";
import common from "../common/common.mjs";
export default {
...common,
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.6",
type: "action",
props: {
...common.props,
personalizations: {
type: "string",
label: "Personalizations",
description: "An array of messages and their metadata. Each object within personalizations can be thought of as an envelope - it defines who should receive an individual message and how that message should be handled. See our [Personalizations documentation](https://sendgrid.com/docs/for-developers/sending-email/personalizations/) for details. maxItems: 1000. Example: `[{to:[{email:\"email@email.com\",name:\"Example\"}],subject:\"Mail Personalization Sample\"}]`",
optional: true,
},
toEmails: {
type: "string[]",
label: "Recipient Emails",
description: "The intended recipients' email addresses. Will be ignored if `personalizations` prop is used.",
optional: true,
},
fromEmail: {
propDefinition: [
common.props.sendgrid,
"fromEmail",
],
},
fromName: {
propDefinition: [
common.props.sendgrid,
"fromName",
],
},
dynamicTemplateData: {
type: "object",
label: "Dynamic Template Data",
description: "Dynamic template data is available using Handlebars syntax in Dynamic Transactional Templates. This field should be used in combination with a Dynamic Transactional Template, which can be identified by a template_id starting with d-. This field is a collection of key/value pairs following the pattern `\"variable_name\":\"value to insert\"`",
optional: true,
},
templateId: {
propDefinition: [
common.props.sendgrid,
"templateId",
],
optional: true,
},
replyToEmail: {
propDefinition: [
common.props.sendgrid,
"replyToEmail",
],
},
replyToName: {
propDefinition: [
common.props.sendgrid,
"replyToName",
],
},
subject: {
propDefinition: [
common.props.sendgrid,
"subject",
],
description: "The global or `message level` subject of your email. This may be overridden by subject lines set -in personalizations.",
},
content: {
propDefinition: [
common.props.sendgrid,
"content",
],
optional: true,
},
headers: {
propDefinition: [
common.props.sendgrid,
"headers",
],
},
categories: {
propDefinition: [
common.props.sendgrid,
"categories",
],
},
customArgs: {
propDefinition: [
common.props.sendgrid,
"customArgs",
],
},
sendAt: {
propDefinition: [
common.props.sendgrid,
"sendAt",
],
},
asm: {
propDefinition: [
common.props.sendgrid,
"asm",
],
},
asmGroupId: {
propDefinition: [
common.props.sendgrid,
"asmGroupId",
],
},
asmGroupsToDisplay: {
propDefinition: [
common.props.sendgrid,
"asmGroupsToDisplay",
],
},
ipPoolName: {
propDefinition: [
common.props.sendgrid,
"ipPoolName",
],
},
mailSettings: {
propDefinition: [
common.props.sendgrid,
"mailSettings",
],
},
trackingSettings: {
propDefinition: [
common.props.sendgrid,
"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({ $ }) {
if (!this.personalizations && !this.toEmails) {
throw new ConfigurationError("Please input either Personalization or Recipient Emails.");
}
const personalizations = this.personalizations || [];
if (personalizations.length == 0) {
if (this.convertEmptyStringToUndefined(this.toEmails)) {
for (const toEmail of this.toEmails) {
const personalization = {
to: [
{
email: toEmail,
},
],
};
personalizations.push(personalization);
}
}
}
if (this.dynamicTemplateData) {
for (const personalization of personalizations) {
personalization.dynamic_template_data = this.dynamicTemplateData;
}
}
validate.validators.arrayValidator = this.validateArray;
validate.validators.asmValidator = this.validateAsm;
const constraints = {
personalizations: {
type: "array",
},
fromEmail: {
email: true,
},
};
if (this.replyToEmail) {
constraints.replyToEmail = {
email: true,
};
}
const attachments = [];
for (let i = 1; i <= this.numberOfAttachments; i++) {
const filepath = this.checkTmp(this["attachmentsPath" + i]);
const content = fs.readFileSync(filepath, {
encoding: "base64",
});
const type = mime.getType(filepath);
attachments.push({
content,
type,
filename: this[`attachmentsName${i}`],
});
}
if (this.categories) {
constraints.categories = {
type: "array",
};
}
this.sendAt = this.convertEmptyStringToUndefined(Date.parse(this.sendAt));
if (this.sendAt) {
constraints.sendAt = this.getIntegerGtZeroConstraint();
}
if (this.asm || this.asmGroupsToDisplay) {
constraints.asm = {
asmValidator: {
asm: this.asm,
asmGroupId: this.asmGroupId,
asmGroupsToDisplay: this.asmGroupsToDisplay,
},
};
}
const validationResult = validate(
{
personalizations: this.personalizations,
fromEmail: this.fromEmail,
replyToEmail: this.replyToEmail,
subject: this.subject,
attachments: this.attachments,
categories: this.categories,
sendAt: this.sendAt,
},
constraints,
);
this.checkValidationResults(validationResult);
const from = {
email: this.fromEmail,
};
if (this.fromName) {
from.name = this.fromName;
}
let replyTo = undefined;
if (this.replyToEmail) {
replyTo = {
email: this.replyToEmail,
};
if (this.replyToName) {
replyTo.name = this.replyToName;
}
}
const config = this.omitEmptyStringValues({
personalizations: this.getArrayObject(personalizations),
from,
reply_to: replyTo,
subject: this.subject,
content: this.content && [
{
type: "text/html",
value: this.content,
},
],
attachments,
headers: this.headers,
categories: this.categories,
custom_args: this.customArgs,
send_at: this.sendAt,
asm: this.getAsmConfig(),
ip_pool_name: this.ipPoolName,
mail_settings: this.mailSettings,
tracking_settings: this.trackingSettings,
template_id: this.templateId,
});
const resp = await this.sendgrid.sendEmail(config);
$.export("$summary", "Email successfully sent");
return resp;
},
};