mirror of
https://github.com/n8n-io/n8n.git
synced 2026-06-03 18:27:09 +02:00
155 lines
3.7 KiB
TypeScript
155 lines
3.7 KiB
TypeScript
import uniq from 'lodash/uniq';
|
|
import { NodeOperationError, type IDataObject, type IExecuteFunctions } from 'n8n-workflow';
|
|
|
|
import type { IEmail } from '@utils/sendAndWait/interfaces';
|
|
|
|
import {
|
|
encodeEmail,
|
|
googleApiRequest,
|
|
prepareEmailAttachments,
|
|
prepareEmailBody,
|
|
prepareEmailsInput,
|
|
} from '../GenericFunctions';
|
|
import type { GmailMessage, GmailMessageMetadata, GmailUserProfile } from '../types';
|
|
|
|
export async function replyToEmail(
|
|
this: IExecuteFunctions,
|
|
gmailId: string,
|
|
options: IDataObject,
|
|
itemIndex: number,
|
|
nodeVersion: number,
|
|
) {
|
|
if (options.replyToSenderOnly && options.replyToRecipientsOnly) {
|
|
throw new NodeOperationError(
|
|
this.getNode(),
|
|
'Both "Reply to Sender Only" and "Reply to Recipient Only" cannot be enabled at the same time. Please select only one option.',
|
|
{ itemIndex },
|
|
);
|
|
}
|
|
|
|
let qs: IDataObject = {};
|
|
|
|
let cc = '';
|
|
let bcc = '';
|
|
|
|
if (options.ccList) {
|
|
cc = prepareEmailsInput.call(this, options.ccList as string, 'CC', itemIndex);
|
|
}
|
|
|
|
if (options.bccList) {
|
|
bcc = prepareEmailsInput.call(this, options.bccList as string, 'BCC', itemIndex);
|
|
}
|
|
let attachments: IDataObject[] = [];
|
|
if (options.attachmentsUi) {
|
|
attachments = await prepareEmailAttachments.call(
|
|
this,
|
|
options.attachmentsUi as IDataObject,
|
|
itemIndex,
|
|
);
|
|
if (attachments.length) {
|
|
qs = {
|
|
userId: 'me',
|
|
uploadType: 'media',
|
|
};
|
|
}
|
|
}
|
|
|
|
const endpoint = `/gmail/v1/users/me/messages/${gmailId}`;
|
|
|
|
qs.format = 'metadata';
|
|
const { payload, threadId } = (await googleApiRequest.call(
|
|
this,
|
|
'GET',
|
|
endpoint,
|
|
{},
|
|
qs,
|
|
)) as GmailMessageMetadata;
|
|
|
|
const subject =
|
|
payload.headers.filter(
|
|
(data: { [key: string]: string }) => data.name.toLowerCase() === 'subject',
|
|
)[0]?.value || '';
|
|
|
|
const messageIdGlobal =
|
|
payload.headers.filter(
|
|
(data: { [key: string]: string }) => data.name.toLowerCase() === 'message-id',
|
|
)[0]?.value || '';
|
|
|
|
const { emailAddress } = (await googleApiRequest.call(
|
|
this,
|
|
'GET',
|
|
'/gmail/v1/users/me/profile',
|
|
)) as GmailUserProfile;
|
|
|
|
const to: string[] = [];
|
|
const replyToSenderOnly =
|
|
options.replyToSenderOnly === undefined ? false : (options.replyToSenderOnly as boolean);
|
|
const replyToRecipientsOnly =
|
|
options.replyToRecipientsOnly === undefined
|
|
? false
|
|
: (options.replyToRecipientsOnly as boolean);
|
|
|
|
const prepareEmailString = (email: string) => {
|
|
if (email.includes(emailAddress)) return;
|
|
if (email.includes('<') && email.includes('>')) {
|
|
to.push(email);
|
|
} else {
|
|
to.push(`<${email}>`);
|
|
}
|
|
};
|
|
|
|
let replyToHeaderName = 'from';
|
|
if (nodeVersion >= 2.2 && payload.headers.some((h) => h.name.toLowerCase() === 'reply-to')) {
|
|
replyToHeaderName = 'reply-to';
|
|
}
|
|
|
|
for (const header of payload.headers) {
|
|
const headerName = (header.name || '').toLowerCase();
|
|
if (headerName === replyToHeaderName && !replyToRecipientsOnly) {
|
|
const replyToEmail = header.value;
|
|
if (replyToEmail.includes('<') && replyToEmail.includes('>')) {
|
|
to.push(replyToEmail);
|
|
} else {
|
|
to.push(`<${replyToEmail}>`);
|
|
}
|
|
}
|
|
|
|
if (headerName === 'to' && !replyToSenderOnly) {
|
|
const toEmails = header.value;
|
|
toEmails.split(',').forEach(prepareEmailString);
|
|
}
|
|
}
|
|
|
|
let from = '';
|
|
if (options.senderName) {
|
|
from = `${options.senderName as string} <${emailAddress}>`;
|
|
}
|
|
|
|
const toString = uniq(to).join(', ');
|
|
|
|
const email: IEmail = {
|
|
from,
|
|
to: toString,
|
|
cc,
|
|
bcc,
|
|
subject,
|
|
attachments,
|
|
inReplyTo: messageIdGlobal,
|
|
reference: messageIdGlobal,
|
|
...prepareEmailBody.call(this, itemIndex),
|
|
};
|
|
|
|
const body = {
|
|
raw: await encodeEmail(email),
|
|
threadId,
|
|
};
|
|
|
|
return (await googleApiRequest.call(
|
|
this,
|
|
'POST',
|
|
'/gmail/v1/users/me/messages/send',
|
|
body,
|
|
qs,
|
|
)) as GmailMessage;
|
|
}
|