mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
feat(Microsoft Outlook Node): Add support for recurring event instances (#29802)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
8573197aef
commit
dab3653f80
|
|
@ -0,0 +1,28 @@
|
|||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
import nock from 'nock';
|
||||
|
||||
describe('Test MicrosoftOutlookV2, event => getAll', () => {
|
||||
nock('https://graph.microsoft.com/v1.0/me')
|
||||
.get(
|
||||
'/calendars/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=/events',
|
||||
)
|
||||
.query(true)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{
|
||||
id: 'AAMkADlhOTA0MTc5event1',
|
||||
subject: 'Single Event',
|
||||
bodyPreview: 'A one-time event',
|
||||
start: { dateTime: '2023-09-05T07:00:00.0000000', timeZone: 'UTC' },
|
||||
end: { dateTime: '2023-09-05T08:00:00.0000000', timeZone: 'UTC' },
|
||||
organizer: { emailAddress: { name: 'Test User', address: 'test@example.com' } },
|
||||
attendees: [],
|
||||
webLink: 'https://outlook.office365.com/owa/?itemid=event1',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
new NodeTestHarness().setupTests({
|
||||
workflowFiles: ['getAll.workflow.json'],
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"name": "Test getAll events",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "e524f588-b6a3-4849-8777-b32a8a755ae5",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [820, 360]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "event",
|
||||
"operation": "getAll",
|
||||
"fromAllCalendars": false,
|
||||
"calendarId": {
|
||||
"__rl": true,
|
||||
"value": "AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=",
|
||||
"mode": "list",
|
||||
"cachedResultName": "Calendar"
|
||||
},
|
||||
"includeRecurringInstances": false,
|
||||
"returnAll": false,
|
||||
"limit": 10,
|
||||
"output": "simple",
|
||||
"filters": {}
|
||||
},
|
||||
"id": "baff6798-0304-4255-bdb0-dd3f2659373b",
|
||||
"name": "Get Many Events",
|
||||
"type": "n8n-nodes-base.microsoftOutlook",
|
||||
"typeVersion": 2,
|
||||
"position": [1040, 360],
|
||||
"credentials": {
|
||||
"microsoftOutlookOAuth2Api": {
|
||||
"id": "iXJCki7i5Vz0bdks",
|
||||
"name": "Microsoft Outlook account 2"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Get Many Events": [
|
||||
{
|
||||
"json": {
|
||||
"id": "AAMkADlhOTA0MTc5event1",
|
||||
"subject": "Single Event",
|
||||
"bodyPreview": "A one-time event",
|
||||
"start": {
|
||||
"dateTime": "2023-09-05T07:00:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"end": {
|
||||
"dateTime": "2023-09-05T08:00:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"organizer": {
|
||||
"emailAddress": {
|
||||
"name": "Test User",
|
||||
"address": "test@example.com"
|
||||
}
|
||||
},
|
||||
"attendees": [],
|
||||
"webLink": "https://outlook.office365.com/owa/?itemid=event1"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Many Events",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "dceb08aa-5897-44d1-afbc-748d1e8a2627",
|
||||
"id": "2CYHzBXQw1nfPGtC",
|
||||
"meta": {
|
||||
"instanceId": "b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
import nock from 'nock';
|
||||
|
||||
describe('Test MicrosoftOutlookV2, event => getAll (calendarView)', () => {
|
||||
nock('https://graph.microsoft.com/v1.0/me')
|
||||
.get(
|
||||
'/calendars/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=/calendarView',
|
||||
)
|
||||
.query(true)
|
||||
.reply(200, {
|
||||
value: [
|
||||
{
|
||||
id: 'AAMkADlhOTA0MTc5event1',
|
||||
subject: 'Single Event',
|
||||
bodyPreview: 'A one-time event',
|
||||
start: { dateTime: '2023-09-05T07:00:00.0000000', timeZone: 'UTC' },
|
||||
end: { dateTime: '2023-09-05T08:00:00.0000000', timeZone: 'UTC' },
|
||||
organizer: { emailAddress: { name: 'Test User', address: 'test@example.com' } },
|
||||
attendees: [],
|
||||
webLink: 'https://outlook.office365.com/owa/?itemid=event1',
|
||||
},
|
||||
{
|
||||
id: 'AAMkADlhOTA0MTc5recurring1',
|
||||
subject: 'Weekly Standup',
|
||||
bodyPreview: 'Recurring weekly meeting - instance 1',
|
||||
start: { dateTime: '2023-09-04T09:00:00.0000000', timeZone: 'UTC' },
|
||||
end: { dateTime: '2023-09-04T09:30:00.0000000', timeZone: 'UTC' },
|
||||
organizer: { emailAddress: { name: 'Test User', address: 'test@example.com' } },
|
||||
attendees: [],
|
||||
webLink: 'https://outlook.office365.com/owa/?itemid=recurring1',
|
||||
},
|
||||
{
|
||||
id: 'AAMkADlhOTA0MTc5recurring2',
|
||||
subject: 'Weekly Standup',
|
||||
bodyPreview: 'Recurring weekly meeting - instance 2',
|
||||
start: { dateTime: '2023-09-11T09:00:00.0000000', timeZone: 'UTC' },
|
||||
end: { dateTime: '2023-09-11T09:30:00.0000000', timeZone: 'UTC' },
|
||||
organizer: { emailAddress: { name: 'Test User', address: 'test@example.com' } },
|
||||
attendees: [],
|
||||
webLink: 'https://outlook.office365.com/owa/?itemid=recurring2',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
new NodeTestHarness().setupTests({
|
||||
workflowFiles: ['getAllCalendarView.workflow.json'],
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
{
|
||||
"name": "Test getAll events with calendar view",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "e524f588-b6a3-4849-8777-b32a8a755ae5",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [820, 360]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "event",
|
||||
"operation": "getAll",
|
||||
"fromAllCalendars": false,
|
||||
"calendarId": {
|
||||
"__rl": true,
|
||||
"value": "AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=",
|
||||
"mode": "list",
|
||||
"cachedResultName": "Calendar"
|
||||
},
|
||||
"includeRecurringInstances": true,
|
||||
"startDateTime": "2023-09-01T00:00:00.000Z",
|
||||
"endDateTime": "2023-09-30T23:59:59.000Z",
|
||||
"returnAll": false,
|
||||
"limit": 10,
|
||||
"output": "simple"
|
||||
},
|
||||
"id": "calendar-view-node",
|
||||
"name": "Get Many Events Calendar View",
|
||||
"type": "n8n-nodes-base.microsoftOutlook",
|
||||
"typeVersion": 2,
|
||||
"position": [1040, 360],
|
||||
"credentials": {
|
||||
"microsoftOutlookOAuth2Api": {
|
||||
"id": "iXJCki7i5Vz0bdks",
|
||||
"name": "Microsoft Outlook account 2"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Get Many Events Calendar View": [
|
||||
{
|
||||
"json": {
|
||||
"id": "AAMkADlhOTA0MTc5event1",
|
||||
"subject": "Single Event",
|
||||
"bodyPreview": "A one-time event",
|
||||
"start": {
|
||||
"dateTime": "2023-09-05T07:00:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"end": {
|
||||
"dateTime": "2023-09-05T08:00:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"organizer": {
|
||||
"emailAddress": {
|
||||
"name": "Test User",
|
||||
"address": "test@example.com"
|
||||
}
|
||||
},
|
||||
"attendees": [],
|
||||
"webLink": "https://outlook.office365.com/owa/?itemid=event1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": "AAMkADlhOTA0MTc5recurring1",
|
||||
"subject": "Weekly Standup",
|
||||
"bodyPreview": "Recurring weekly meeting - instance 1",
|
||||
"start": {
|
||||
"dateTime": "2023-09-04T09:00:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"end": {
|
||||
"dateTime": "2023-09-04T09:30:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"organizer": {
|
||||
"emailAddress": {
|
||||
"name": "Test User",
|
||||
"address": "test@example.com"
|
||||
}
|
||||
},
|
||||
"attendees": [],
|
||||
"webLink": "https://outlook.office365.com/owa/?itemid=recurring1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": "AAMkADlhOTA0MTc5recurring2",
|
||||
"subject": "Weekly Standup",
|
||||
"bodyPreview": "Recurring weekly meeting - instance 2",
|
||||
"start": {
|
||||
"dateTime": "2023-09-11T09:00:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"end": {
|
||||
"dateTime": "2023-09-11T09:30:00.0000000",
|
||||
"timeZone": "UTC"
|
||||
},
|
||||
"organizer": {
|
||||
"emailAddress": {
|
||||
"name": "Test User",
|
||||
"address": "test@example.com"
|
||||
}
|
||||
},
|
||||
"attendees": [],
|
||||
"webLink": "https://outlook.office365.com/owa/?itemid=recurring2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Many Events Calendar View",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "dceb08aa-5897-44d1-afbc-748d1e8a2628",
|
||||
"id": "3CYHzBXQw1nfPGtD",
|
||||
"meta": {
|
||||
"instanceId": "b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
|
|
@ -21,6 +21,40 @@ export const properties: INodeProperties[] = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Include Recurring Event Instances',
|
||||
name: 'includeRecurringInstances',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether to expand recurring events into individual instances within the specified date range. When disabled, recurring events are returned as a single series master event.',
|
||||
},
|
||||
{
|
||||
displayName: 'Start Date',
|
||||
name: 'startDateTime',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
required: true,
|
||||
description: 'Start of the date range to retrieve event instances for',
|
||||
displayOptions: {
|
||||
show: {
|
||||
includeRecurringInstances: [true],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'End Date',
|
||||
name: 'endDateTime',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
required: true,
|
||||
description: 'End of the date range to retrieve event instances for',
|
||||
displayOptions: {
|
||||
show: {
|
||||
includeRecurringInstances: [true],
|
||||
},
|
||||
},
|
||||
},
|
||||
...returnAllOrLimit,
|
||||
{
|
||||
displayName: 'Output',
|
||||
|
|
@ -61,6 +95,11 @@ export const properties: INodeProperties[] = [
|
|||
type: 'collection',
|
||||
placeholder: 'Add Filter',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
includeRecurringInstances: [false],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Filter Query',
|
||||
|
|
@ -88,8 +127,11 @@ export async function execute(this: IExecuteFunctions, index: number) {
|
|||
const qs = {} as IDataObject;
|
||||
|
||||
const returnAll = this.getNodeParameter('returnAll', index);
|
||||
const filters = this.getNodeParameter('filters', index, {});
|
||||
const output = this.getNodeParameter('output', index) as string;
|
||||
const includeRecurringInstances = this.getNodeParameter(
|
||||
'includeRecurringInstances',
|
||||
index,
|
||||
) as boolean;
|
||||
|
||||
if (output === 'fields') {
|
||||
const fields = this.getNodeParameter('fields', index) as string[];
|
||||
|
|
@ -100,6 +142,12 @@ export async function execute(this: IExecuteFunctions, index: number) {
|
|||
qs.$select = 'id,subject,bodyPreview,start,end,organizer,attendees,webLink';
|
||||
}
|
||||
|
||||
if (includeRecurringInstances) {
|
||||
qs.startDateTime = this.getNodeParameter('startDateTime', index) as string;
|
||||
qs.endDateTime = this.getNodeParameter('endDateTime', index) as string;
|
||||
} else {
|
||||
const filters = this.getNodeParameter('filters', index, {});
|
||||
|
||||
if (Object.keys(filters).length) {
|
||||
const filterString: string[] = [];
|
||||
|
||||
|
|
@ -111,6 +159,7 @@ export async function execute(this: IExecuteFunctions, index: number) {
|
|||
qs.$filter = filterString.join(' and ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const calendars: string[] = [];
|
||||
|
||||
|
|
@ -133,7 +182,9 @@ export async function execute(this: IExecuteFunctions, index: number) {
|
|||
const limit = this.getNodeParameter('limit', index, 0);
|
||||
|
||||
for (const calendarId of calendars) {
|
||||
const endpoint = `/calendars/${calendarId}/events`;
|
||||
const endpoint = includeRecurringInstances
|
||||
? `/calendars/${calendarId}/calendarView`
|
||||
: `/calendars/${calendarId}/events`;
|
||||
|
||||
if (returnAll) {
|
||||
const response = await microsoftApiRequestAllItems.call(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user