-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Onedrive Trigger Node (#8742)
Co-authored-by: Giulio Andreini <andreini@netseven.it> Co-authored-by: Marcus <marcus@n8n.io>
- Loading branch information
1 parent
4f0b52c
commit ff8dd4e
Showing
6 changed files
with
571 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDriveTrigger.node.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"node": "n8n-nodes-base.microsoftOneDriveTrigger", | ||
"nodeVersion": "1.0", | ||
"codexVersion": "1.0", | ||
"categories": ["Data & Storage"], | ||
"resources": { | ||
"credentialDocumentation": [ | ||
{ | ||
"url": "https://docs.n8n.io/credentials/microsoft" | ||
} | ||
], | ||
"primaryDocumentation": [ | ||
{ | ||
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.microsoftonedrivetrigger/" | ||
} | ||
], | ||
"generic": [ | ||
{ | ||
"label": "Hey founders! Your business doesn't need you to operate", | ||
"icon": " 🖥️", | ||
"url": "https://n8n.io/blog/your-business-doesnt-need-you-to-operate/" | ||
} | ||
] | ||
} | ||
} |
173 changes: 173 additions & 0 deletions
173
packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDriveTrigger.node.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
import type { | ||
IPollFunctions, | ||
IDataObject, | ||
INodeExecutionData, | ||
INodeType, | ||
INodeTypeDescription, | ||
} from 'n8n-workflow'; | ||
|
||
import { DateTime } from 'luxon'; | ||
import { triggerDescription } from './TriggerDescription'; | ||
import { getPath, microsoftApiRequest, microsoftApiRequestAllItemsDelta } from './GenericFunctions'; | ||
|
||
export class MicrosoftOneDriveTrigger implements INodeType { | ||
description: INodeTypeDescription = { | ||
displayName: 'Microsoft OneDrive Trigger', | ||
name: 'microsoftOneDriveTrigger', | ||
icon: 'file:oneDrive.svg', | ||
group: ['trigger'], | ||
version: 1, | ||
description: 'Trigger for Microsoft OneDrive API.', | ||
subtitle: '={{($parameter["event"])}}', | ||
defaults: { | ||
name: 'Microsoft OneDrive Trigger', | ||
}, | ||
credentials: [ | ||
{ | ||
name: 'microsoftOneDriveOAuth2Api', | ||
required: true, | ||
}, | ||
], | ||
polling: true, | ||
inputs: [], | ||
outputs: ['main'], | ||
properties: [...triggerDescription], | ||
}; | ||
|
||
methods = { | ||
loadOptions: {}, | ||
}; | ||
|
||
async poll(this: IPollFunctions): Promise<INodeExecutionData[][] | null> { | ||
const workflowData = this.getWorkflowStaticData('node'); | ||
let responseData: IDataObject[]; | ||
|
||
const lastLink: string = | ||
(workflowData.LastLink as string) || | ||
'https://graph.microsoft.com/v1.0/me/drive/root/delta?token=latest'; | ||
|
||
const now = DateTime.now().toUTC(); | ||
const start = DateTime.fromISO(workflowData.lastTimeChecked as string) || now; | ||
const end = now; | ||
const event = this.getNodeParameter('event', 'fileCreated') as string; | ||
const watch = this.getNodeParameter('watch', 'anyFile') as string; | ||
const watchFolder = (this.getNodeParameter('watchFolder', false) as boolean) || false; | ||
const folderChild = (this.getNodeParameter('options.folderChild', false) as boolean) || false; | ||
|
||
let eventType = 'created'; | ||
let eventResource = 'file'; | ||
if (event.includes('Updated')) { | ||
eventType = 'updated'; | ||
} | ||
if (event.includes('folder')) { | ||
eventResource = 'folder'; | ||
} | ||
try { | ||
if (this.getMode() === 'manual') { | ||
responseData = ( | ||
await microsoftApiRequest.call( | ||
this, | ||
'GET', | ||
'', | ||
{}, | ||
{}, | ||
'https://graph.microsoft.com/v1.0/me/drive/root/delta', | ||
) | ||
).value as IDataObject[]; | ||
} else { | ||
const response: IDataObject = (await microsoftApiRequestAllItemsDelta.call( | ||
this, | ||
lastLink, | ||
start, | ||
eventType, | ||
)) as IDataObject; | ||
responseData = response.returnData as IDataObject[]; | ||
workflowData.LastLink = response.deltaLink; | ||
} | ||
|
||
workflowData.lastTimeChecked = end.toISO(); | ||
if (watch === 'selectedFile') { | ||
const fileId = ( | ||
this.getNodeParameter('fileId', '', { | ||
extractValue: true, | ||
}) as string | ||
).replace('%21', '!'); | ||
if (fileId) { | ||
responseData = responseData.filter((item: IDataObject) => item.id === fileId); | ||
} | ||
} | ||
|
||
if ( | ||
!folderChild && | ||
(watch === 'oneSelectedFolder' || watch === 'selectedFolder' || watchFolder) | ||
) { | ||
const folderId = ( | ||
this.getNodeParameter('folderId', '', { | ||
extractValue: true, | ||
}) as string | ||
).replace('%21', '!'); | ||
if (folderId) { | ||
if (watch === 'oneSelectedFolder') { | ||
responseData = responseData.filter((item: IDataObject) => item.id === folderId); | ||
} else { | ||
responseData = responseData.filter( | ||
(item: IDataObject) => (item.parentReference as IDataObject).id === folderId, | ||
); | ||
} | ||
} | ||
} | ||
if (folderChild && (watch === 'selectedFolder' || watchFolder)) { | ||
const folderId = ( | ||
this.getNodeParameter('folderId', '', { | ||
extractValue: true, | ||
}) as string | ||
).replace('%21', '!'); | ||
const folderPath = await getPath.call(this, folderId); | ||
responseData = responseData.filter((item: IDataObject) => | ||
((item.parentReference as IDataObject).path as string).startsWith(folderPath), | ||
); | ||
} | ||
responseData = responseData.filter((item: IDataObject) => item[eventResource]); | ||
if (!responseData?.length) { | ||
return null; | ||
} | ||
|
||
const simplify = this.getNodeParameter('simple') as boolean; | ||
if (simplify) { | ||
responseData = responseData.map((x) => ({ | ||
id: x.id, | ||
createdDateTime: (x.fileSystemInfo as IDataObject)?.createdDateTime, | ||
lastModifiedDateTime: (x.fileSystemInfo as IDataObject)?.lastModifiedDateTime, | ||
name: x.name, | ||
webUrl: x.webUrl, | ||
size: x.size, | ||
path: (x.parentReference as IDataObject)?.path || '', | ||
mimeType: (x.file as IDataObject)?.mimeType || '', | ||
})); | ||
} | ||
|
||
if (this.getMode() === 'manual') { | ||
return [this.helpers.returnJsonArray(responseData[0])]; | ||
} else { | ||
return [this.helpers.returnJsonArray(responseData)]; | ||
} | ||
} catch (error) { | ||
if (this.getMode() === 'manual' || !workflowData.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}'`, | ||
{ | ||
node: node.name, | ||
workflowId: workflow.id, | ||
error, | ||
}, | ||
); | ||
throw error; | ||
} | ||
|
||
return null; | ||
} | ||
} |
Oops, something went wrong.