Skip to content

Commit 3761537

Browse files
fix(Gmail Trigger Node): Fetching duplicate emails (#9424)
1 parent c1eef60 commit 3761537

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

packages/nodes-base/nodes/Google/Gmail/GmailTrigger.node.ts

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class GmailTrigger implements INodeType {
2323
name: 'gmailTrigger',
2424
icon: 'file:gmail.svg',
2525
group: ['trigger'],
26-
version: 1,
26+
version: [1, 1.1],
2727
description:
2828
'Fetches emails from Gmail and starts the workflow on specified polling intervals.',
2929
subtitle: '={{"Gmail Trigger"}}',
@@ -226,11 +226,24 @@ export class GmailTrigger implements INodeType {
226226
};
227227

228228
async poll(this: IPollFunctions): Promise<INodeExecutionData[][] | null> {
229-
const webhookData = this.getWorkflowStaticData('node');
229+
const workflowStaticData = this.getWorkflowStaticData('node');
230+
const node = this.getNode();
231+
232+
let nodeStaticData = workflowStaticData;
233+
if (node.typeVersion > 1) {
234+
const nodeName = node.name;
235+
if (workflowStaticData[nodeName] === undefined) {
236+
workflowStaticData[nodeName] = {} as IDataObject;
237+
nodeStaticData = workflowStaticData[nodeName] as IDataObject;
238+
} else {
239+
nodeStaticData = workflowStaticData[nodeName] as IDataObject;
240+
}
241+
}
242+
230243
let responseData;
231244

232245
const now = Math.floor(DateTime.now().toSeconds()).toString();
233-
const startDate = (webhookData.lastTimeChecked as string) || +now;
246+
const startDate = (nodeStaticData.lastTimeChecked as string) || +now;
234247
const endDate = +now;
235248

236249
const options = this.getNodeParameter('options', {}) as IDataObject;
@@ -257,7 +270,7 @@ export class GmailTrigger implements INodeType {
257270
responseData = responseData.messages;
258271

259272
if (!responseData?.length) {
260-
webhookData.lastTimeChecked = endDate;
273+
nodeStaticData.lastTimeChecked = endDate;
261274
return null;
262275
}
263276

@@ -297,11 +310,10 @@ export class GmailTrigger implements INodeType {
297310
);
298311
}
299312
} catch (error) {
300-
if (this.getMode() === 'manual' || !webhookData.lastTimeChecked) {
313+
if (this.getMode() === 'manual' || !nodeStaticData.lastTimeChecked) {
301314
throw error;
302315
}
303316
const workflow = this.getWorkflow();
304-
const node = this.getNode();
305317
this.logger.error(
306318
`There was a problem in '${node.name}' node in workflow '${workflow.id}': '${error.description}'`,
307319
{
@@ -313,15 +325,31 @@ export class GmailTrigger implements INodeType {
313325
}
314326

315327
if (!responseData?.length) {
316-
webhookData.lastTimeChecked = endDate;
328+
nodeStaticData.lastTimeChecked = endDate;
317329
return null;
318330
}
319331

320-
const getEmailDateAsSeconds = (email: IDataObject) => {
321-
const { internalDate, date } = email;
322-
return internalDate
323-
? +(internalDate as string) / 1000
324-
: +DateTime.fromJSDate(new Date(date as string)).toSeconds();
332+
const emailsWithInvalidDate = new Set<string>();
333+
334+
const getEmailDateAsSeconds = (email: IDataObject): number => {
335+
let date;
336+
337+
if (email.internalDate) {
338+
date = +(email.internalDate as string) / 1000;
339+
} else if (email.date) {
340+
date = +DateTime.fromJSDate(new Date(email.date as string)).toSeconds();
341+
} else {
342+
date = +DateTime.fromJSDate(
343+
new Date((email?.headers as IDataObject)?.date as string),
344+
).toSeconds();
345+
}
346+
347+
if (!date || isNaN(date)) {
348+
emailsWithInvalidDate.add(email.id as string);
349+
return +startDate;
350+
}
351+
352+
return date;
325353
};
326354

327355
const lastEmailDate = (responseData as IDataObject[]).reduce((lastDate, { json }) => {
@@ -336,19 +364,19 @@ export class GmailTrigger implements INodeType {
336364
? duplicates.concat((json as IDataObject).id as string)
337365
: duplicates;
338366
},
339-
[] as string[],
367+
Array.from(emailsWithInvalidDate),
340368
);
341369

342-
const possibleDuplicates = (webhookData.possibleDuplicates as string[]) || [];
370+
const possibleDuplicates = (nodeStaticData.possibleDuplicates as string[]) || [];
343371
if (possibleDuplicates.length) {
344372
responseData = (responseData as IDataObject[]).filter(({ json }) => {
345373
const { id } = json as IDataObject;
346374
return !possibleDuplicates.includes(id as string);
347375
});
348376
}
349377

350-
webhookData.possibleDuplicates = nextPollPossibleDuplicates;
351-
webhookData.lastTimeChecked = lastEmailDate || endDate;
378+
nodeStaticData.possibleDuplicates = nextPollPossibleDuplicates;
379+
nodeStaticData.lastTimeChecked = lastEmailDate || endDate;
352380

353381
if (Array.isArray(responseData) && responseData.length) {
354382
return [responseData as INodeExecutionData[]];

0 commit comments

Comments
 (0)