Skip to main content
Glama

mcp-google-sheets

send-email-action.ts6.21 kB
import { ApFile, createAction, Property } from '@activepieces/pieces-framework'; import mime from 'mime-types'; import MailComposer from 'nodemailer/lib/mail-composer'; import Mail, { Attachment } from 'nodemailer/lib/mailer'; import { gmailAuth } from '../../'; import { google } from 'googleapis'; import { OAuth2Client } from 'googleapis-common'; export const gmailSendEmailAction = createAction({ auth: gmailAuth, name: 'send_email', description: 'Send an email through a Gmail account', displayName: 'Send Email', props: { receiver: Property.Array({ displayName: 'Receiver Email (To)', description: undefined, required: true, }), cc: Property.Array({ displayName: 'CC Email', description: undefined, required: false, }), bcc: Property.Array({ displayName: 'BCC Email', description: undefined, required: false, }), subject: Property.ShortText({ displayName: 'Subject', description: undefined, required: true, }), body_type: Property.StaticDropdown({ displayName: 'Body Type', required: true, defaultValue: 'plain_text', options: { disabled: false, options: [ { label: 'plain text', value: 'plain_text', }, { label: 'html', value: 'html', }, ], }, }), body: Property.ShortText({ displayName: 'Body', description: 'Body for the email you want to send', required: true, }), reply_to: Property.Array({ displayName: 'Reply-To Email', description: 'Email address to set as the "Reply-To" header', required: false, }), sender_name: Property.ShortText({ displayName: 'Sender Name', required: false, }), from: Property.ShortText({ displayName: 'Sender Email', description: "The address must be listed in your GMail account's settings", required: false, }), attachments: Property.Array({ displayName: 'Attachments', required: false, properties: { file: Property.File({ displayName: 'File', description: 'File to attach to the email you want to send.', required: true, }), name: Property.ShortText({ displayName: 'Attachment Name', description: 'In case you want to change the name of the attachment.', required: false, }), }, }), in_reply_to: Property.ShortText({ displayName: 'In reply to', description: 'Reply to this Message-ID', required: false, }), draft: Property.Checkbox({ displayName: 'Create draft', description: 'Create draft without sending the actual email', required: true, defaultValue: false, }), }, async run(context) { const authClient = new OAuth2Client(); authClient.setCredentials(context.auth); const gmail = google.gmail({ version: 'v1', auth: authClient }); const subjectBase64 = Buffer.from(context.propsValue['subject']).toString( 'base64' ); const attachments = context.propsValue.attachments as { file: ApFile; name: string | undefined; }[]; const replyTo = context.propsValue['reply_to']?.filter( (email) => email !== '' ); const receiver = context.propsValue['receiver']?.filter( (email) => email !== '' ); const cc = context.propsValue['cc']?.filter((email) => email !== ''); const bcc = context.propsValue['bcc']?.filter((email) => email !== ''); const mailOptions: Mail.Options = { to: receiver.join(', '), // Join all email addresses with a comma cc: cc ? cc.join(', ') : undefined, bcc: bcc ? bcc.join(', ') : undefined, subject: `=?UTF-8?B?${subjectBase64}?=`, replyTo: replyTo ? replyTo.join(', ') : '', text: context.propsValue.body_type === 'plain_text' ? context.propsValue['body'] : undefined, html: context.propsValue.body_type === 'html' ? context.propsValue['body'] : undefined, attachments: [], }; let threadId = undefined; if (context.propsValue.in_reply_to) { mailOptions.headers = [ { key: 'References', value: context.propsValue.in_reply_to, }, { key: 'In-Reply-To', value: context.propsValue.in_reply_to, }, ]; const messages = await gmail.users.messages.list({ userId: 'me', q: `Rfc822msgid:${context.propsValue.in_reply_to}`, }); threadId = messages.data.messages?.[0].threadId; } const senderEmail = context.propsValue.from || (await google.oauth2({ version: 'v2', auth: authClient }).userinfo.get()) .data.email; if (senderEmail) { mailOptions.from = context.propsValue.sender_name ? `${context.propsValue['sender_name']} <${senderEmail}>` : senderEmail; } if (attachments && attachments.length > 0) { const attachmentOption: Attachment[] = attachments.map( ({ file, name }) => { const lookupResult = mime.lookup( file.extension ? file.extension : '' ); return { filename: name ?? file.filename, content: file?.base64, contentType: lookupResult ? lookupResult : undefined, encoding: 'base64', }; } ); mailOptions.attachments = attachmentOption; } const mail: any = new MailComposer(mailOptions).compile(); mail.keepBcc = true; const mailBody = await mail.build(); const encodedPayload = Buffer.from(mailBody) .toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_'); if (context.propsValue.draft) { return await gmail.users.drafts.create({ userId: 'me', requestBody: { message: { threadId, raw: encodedPayload } }, }); } else { return await gmail.users.messages.send({ userId: 'me', requestBody: { threadId, raw: encodedPayload, }, }); } }, });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server