diff --git a/packages/nodes-base/nodes/Google/Gmail/GmailTrigger.node.ts b/packages/nodes-base/nodes/Google/Gmail/GmailTrigger.node.ts index ac6855d58a16c..526c0466be12c 100644 --- a/packages/nodes-base/nodes/Google/Gmail/GmailTrigger.node.ts +++ b/packages/nodes-base/nodes/Google/Gmail/GmailTrigger.node.ts @@ -23,7 +23,7 @@ export class GmailTrigger implements INodeType { name: 'gmailTrigger', icon: 'file:gmail.svg', group: ['trigger'], - version: 1, + version: [1, 1.1], description: 'Fetches emails from Gmail and starts the workflow on specified polling intervals.', subtitle: '={{"Gmail Trigger"}}', @@ -226,11 +226,24 @@ export class GmailTrigger implements INodeType { }; async poll(this: IPollFunctions): Promise { - const webhookData = this.getWorkflowStaticData('node'); + const workflowStaticData = this.getWorkflowStaticData('node'); + const node = this.getNode(); + + let nodeStaticData = workflowStaticData; + if (node.typeVersion > 1) { + const nodeName = node.name; + if (workflowStaticData[nodeName] === undefined) { + workflowStaticData[nodeName] = {} as IDataObject; + nodeStaticData = workflowStaticData[nodeName] as IDataObject; + } else { + nodeStaticData = workflowStaticData[nodeName] as IDataObject; + } + } + let responseData; const now = Math.floor(DateTime.now().toSeconds()).toString(); - const startDate = (webhookData.lastTimeChecked as string) || +now; + const startDate = (nodeStaticData.lastTimeChecked as string) || +now; const endDate = +now; const options = this.getNodeParameter('options', {}) as IDataObject; @@ -257,7 +270,7 @@ export class GmailTrigger implements INodeType { responseData = responseData.messages; if (!responseData?.length) { - webhookData.lastTimeChecked = endDate; + nodeStaticData.lastTimeChecked = endDate; return null; } @@ -297,11 +310,10 @@ export class GmailTrigger implements INodeType { ); } } catch (error) { - if (this.getMode() === 'manual' || !webhookData.lastTimeChecked) { + if (this.getMode() === 'manual' || !nodeStaticData.lastTimeChecked) { throw error; } const workflow = this.getWorkflow(); - const node = this.getNode(); this.logger.error( `There was a problem in '${node.name}' node in workflow '${workflow.id}': '${error.description}'`, { @@ -313,15 +325,31 @@ export class GmailTrigger implements INodeType { } if (!responseData?.length) { - webhookData.lastTimeChecked = endDate; + nodeStaticData.lastTimeChecked = endDate; return null; } - const getEmailDateAsSeconds = (email: IDataObject) => { - const { internalDate, date } = email; - return internalDate - ? +(internalDate as string) / 1000 - : +DateTime.fromJSDate(new Date(date as string)).toSeconds(); + const emailsWithInvalidDate = new Set(); + + const getEmailDateAsSeconds = (email: IDataObject): number => { + let date; + + if (email.internalDate) { + date = +(email.internalDate as string) / 1000; + } else if (email.date) { + date = +DateTime.fromJSDate(new Date(email.date as string)).toSeconds(); + } else { + date = +DateTime.fromJSDate( + new Date((email?.headers as IDataObject)?.date as string), + ).toSeconds(); + } + + if (!date || isNaN(date)) { + emailsWithInvalidDate.add(email.id as string); + return +startDate; + } + + return date; }; const lastEmailDate = (responseData as IDataObject[]).reduce((lastDate, { json }) => { @@ -336,10 +364,10 @@ export class GmailTrigger implements INodeType { ? duplicates.concat((json as IDataObject).id as string) : duplicates; }, - [] as string[], + Array.from(emailsWithInvalidDate), ); - const possibleDuplicates = (webhookData.possibleDuplicates as string[]) || []; + const possibleDuplicates = (nodeStaticData.possibleDuplicates as string[]) || []; if (possibleDuplicates.length) { responseData = (responseData as IDataObject[]).filter(({ json }) => { const { id } = json as IDataObject; @@ -347,8 +375,8 @@ export class GmailTrigger implements INodeType { }); } - webhookData.possibleDuplicates = nextPollPossibleDuplicates; - webhookData.lastTimeChecked = lastEmailDate || endDate; + nodeStaticData.possibleDuplicates = nextPollPossibleDuplicates; + nodeStaticData.lastTimeChecked = lastEmailDate || endDate; if (Array.isArray(responseData) && responseData.length) { return [responseData as INodeExecutionData[]];