mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
fix(Gmail Trigger Node): Fetching duplicate emails (#9424)
This commit is contained in:
parent
c1eef60ccd
commit
3761537880
|
@ -23,7 +23,7 @@ export class GmailTrigger implements INodeType {
|
||||||
name: 'gmailTrigger',
|
name: 'gmailTrigger',
|
||||||
icon: 'file:gmail.svg',
|
icon: 'file:gmail.svg',
|
||||||
group: ['trigger'],
|
group: ['trigger'],
|
||||||
version: 1,
|
version: [1, 1.1],
|
||||||
description:
|
description:
|
||||||
'Fetches emails from Gmail and starts the workflow on specified polling intervals.',
|
'Fetches emails from Gmail and starts the workflow on specified polling intervals.',
|
||||||
subtitle: '={{"Gmail Trigger"}}',
|
subtitle: '={{"Gmail Trigger"}}',
|
||||||
|
@ -226,11 +226,24 @@ export class GmailTrigger implements INodeType {
|
||||||
};
|
};
|
||||||
|
|
||||||
async poll(this: IPollFunctions): Promise<INodeExecutionData[][] | null> {
|
async poll(this: IPollFunctions): Promise<INodeExecutionData[][] | null> {
|
||||||
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;
|
let responseData;
|
||||||
|
|
||||||
const now = Math.floor(DateTime.now().toSeconds()).toString();
|
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 endDate = +now;
|
||||||
|
|
||||||
const options = this.getNodeParameter('options', {}) as IDataObject;
|
const options = this.getNodeParameter('options', {}) as IDataObject;
|
||||||
|
@ -257,7 +270,7 @@ export class GmailTrigger implements INodeType {
|
||||||
responseData = responseData.messages;
|
responseData = responseData.messages;
|
||||||
|
|
||||||
if (!responseData?.length) {
|
if (!responseData?.length) {
|
||||||
webhookData.lastTimeChecked = endDate;
|
nodeStaticData.lastTimeChecked = endDate;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,11 +310,10 @@ export class GmailTrigger implements INodeType {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.getMode() === 'manual' || !webhookData.lastTimeChecked) {
|
if (this.getMode() === 'manual' || !nodeStaticData.lastTimeChecked) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
const workflow = this.getWorkflow();
|
const workflow = this.getWorkflow();
|
||||||
const node = this.getNode();
|
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`There was a problem in '${node.name}' node in workflow '${workflow.id}': '${error.description}'`,
|
`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) {
|
if (!responseData?.length) {
|
||||||
webhookData.lastTimeChecked = endDate;
|
nodeStaticData.lastTimeChecked = endDate;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getEmailDateAsSeconds = (email: IDataObject) => {
|
const emailsWithInvalidDate = new Set<string>();
|
||||||
const { internalDate, date } = email;
|
|
||||||
return internalDate
|
const getEmailDateAsSeconds = (email: IDataObject): number => {
|
||||||
? +(internalDate as string) / 1000
|
let date;
|
||||||
: +DateTime.fromJSDate(new Date(date as string)).toSeconds();
|
|
||||||
|
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 }) => {
|
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.concat((json as IDataObject).id as string)
|
||||||
: duplicates;
|
: duplicates;
|
||||||
},
|
},
|
||||||
[] as string[],
|
Array.from(emailsWithInvalidDate),
|
||||||
);
|
);
|
||||||
|
|
||||||
const possibleDuplicates = (webhookData.possibleDuplicates as string[]) || [];
|
const possibleDuplicates = (nodeStaticData.possibleDuplicates as string[]) || [];
|
||||||
if (possibleDuplicates.length) {
|
if (possibleDuplicates.length) {
|
||||||
responseData = (responseData as IDataObject[]).filter(({ json }) => {
|
responseData = (responseData as IDataObject[]).filter(({ json }) => {
|
||||||
const { id } = json as IDataObject;
|
const { id } = json as IDataObject;
|
||||||
|
@ -347,8 +375,8 @@ export class GmailTrigger implements INodeType {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
webhookData.possibleDuplicates = nextPollPossibleDuplicates;
|
nodeStaticData.possibleDuplicates = nextPollPossibleDuplicates;
|
||||||
webhookData.lastTimeChecked = lastEmailDate || endDate;
|
nodeStaticData.lastTimeChecked = lastEmailDate || endDate;
|
||||||
|
|
||||||
if (Array.isArray(responseData) && responseData.length) {
|
if (Array.isArray(responseData) && responseData.length) {
|
||||||
return [responseData as INodeExecutionData[]];
|
return [responseData as INodeExecutionData[]];
|
||||||
|
|
Loading…
Reference in a new issue