🐛 Fixing issue with Gmail subject enconding (#1121)

Reported by community user huuich (https://community.n8n.io/t/gmail-integration-partly-created/693/12?u=jan)

An attempt to fix the problem using basic JS functions (escape / unescape
/ encoding / decoding) did not work, so I decided to use MailComposer
as suggested by Jan on Jira Issue PROD-575
This commit is contained in:
Omar Ajoue 2020-11-02 18:47:47 -03:00 committed by GitHub
parent 13e71b06ad
commit 3650d3b3bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 54 deletions

View file

@ -23,6 +23,8 @@ import {
IEmail, IEmail,
} from './Gmail.node'; } from './Gmail.node';
const MailComposer = require("nodemailer/lib/mail-composer");
export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string,
endpoint: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any endpoint: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
let options: OptionsWithUri = { let options: OptionsWithUri = {
@ -126,62 +128,40 @@ export async function parseRawEmail(this: IExecuteFunctions, messageData: any, d
// for more info on MIME, https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2010/aa494197(v%3Dexchg.140) // for more info on MIME, https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2010/aa494197(v%3Dexchg.140)
//------------------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------------------
export function encodeEmail(email: IEmail) { export async function encodeEmail(email: IEmail) {
let mimeEmail = ''; let mailBody: Buffer;
if (email.attachments !== undefined && email.attachments !== []) { const mailOptions = {
const attachments = email.attachments.map((attachment) => { to: email.to,
return [ cc : email.cc,
"--XXXXboundary text\n", bcc: email.bcc,
"Content-Type:", attachment.type, ";\n", replyTo: email.inReplyTo,
"Content-Transfer-Encoding: Base64\n", references: email.reference,
"Content-Disposition: attachment;\n", subject: email.subject,
"\tfilename=\"", attachment.name, "\"\n\n", text: email.body,
} as IDataObject;
attachment.content, "\n\n", if (email.attachments !== undefined && Array.isArray(email.attachments) && email.attachments.length > 0) {
const attachments = email.attachments.map((attachment) => ({
filename: attachment.name,
content: attachment.content,
contentType: attachment.type,
encoding : 'base64',
}));
"--XXXXboundary text\n\n", mailOptions.attachments = attachments;
].join('');
});
mimeEmail = [
"To: ", email.to, "\n",
"Cc: ", email.cc, "\n",
"Bcc: ", email.bcc, "\n",
"In-Reply-To: ", email.inReplyTo, "\n",
"References: ", email.reference, "\n",
"Subject: ", email.subject, "\n",
"MIME-Version: 1.0\n",
"Content-Type: multipart/mixed;\n",
"\tboundary=\"XXXXboundary text\"\n\n",
"This is a multipart message in MIME format.\n\n",
"--XXXXboundary text\n",
"Content-Type: text/plain\n\n",
email.body, "\n\n",
attachments.join(''),
"--XXXXboundary text--",
].join('');
} else {
mimeEmail = [
"Content-Type: text/plain; charset=\"UTF-8\"\n",
"MIME-Version: 1.0\n",
"Content-Transfer-Encoding: 7bit\n",
"To: ", email.to, "\n",
"Cc: ", email.cc, "\n",
"Bcc: ", email.bcc, "\n",
"In-Reply-To: ", email.inReplyTo, "\n",
"References: ", email.reference, "\n",
"Subject: ", email.subject, "\n\n",
email.body,
].join('');
} }
return Buffer.from(mimeEmail).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
const mail = new MailComposer(mailOptions);
mailBody = await new Promise((resolve) => {
mail.compile().build(async (err: string, result: Buffer) => {
resolve(result);
});
});
return mailBody.toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
} }
export async function googleApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any export async function googleApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any

View file

@ -329,7 +329,7 @@ export class Gmail implements INodeType {
method = 'POST'; method = 'POST';
body = { body = {
raw: encodeEmail(email), raw: await encodeEmail(email),
}; };
responseData = await googleApiRequest.call(this, method, endpoint, body, qs); responseData = await googleApiRequest.call(this, method, endpoint, body, qs);
@ -427,7 +427,7 @@ export class Gmail implements INodeType {
email.reference = id; email.reference = id;
body = { body = {
raw: encodeEmail(email), raw: await encodeEmail(email),
threadId: this.getNodeParameter('threadId', i) as string, threadId: this.getNodeParameter('threadId', i) as string,
}; };
@ -625,7 +625,7 @@ export class Gmail implements INodeType {
body = { body = {
message: { message: {
raw: encodeEmail(email), raw: await encodeEmail(email),
}, },
}; };