mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
feat(Microsoft Outlook Node): Add location and attendees fields to calendar events (#29844)
Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Michael Kret <88898367+michael-radency@users.noreply.github.com>
This commit is contained in:
parent
7635131bd3
commit
2e21c5fcf8
|
|
@ -6,6 +6,12 @@ describe('Test MicrosoftOutlookV2, contact => event', () => {
|
|||
.post(
|
||||
'/calendars/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=/events',
|
||||
{
|
||||
attendees: [
|
||||
{
|
||||
emailAddress: { address: 'samantha@contoso.com', name: 'Samantha Booth' },
|
||||
type: 'required',
|
||||
},
|
||||
],
|
||||
body: { content: 'event description', contentType: 'html' },
|
||||
bodyPreview: 'preview',
|
||||
categories: ['Yellow category', 'Orange category'],
|
||||
|
|
@ -16,6 +22,7 @@ describe('Test MicrosoftOutlookV2, contact => event', () => {
|
|||
isCancelled: false,
|
||||
isDraft: false,
|
||||
isOnlineMeeting: true,
|
||||
location: { displayName: "Harry's Bar" },
|
||||
sensitivity: 'personal',
|
||||
showAs: 'busy',
|
||||
start: { dateTime: '2023-09-05T07:26:47.000Z', timeZone: 'UTC' },
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@
|
|||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
820,
|
||||
360
|
||||
]
|
||||
"position": [820, 360]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
|
|
@ -26,10 +23,16 @@
|
|||
"startDateTime": "2023-09-05T07:26:47.000Z",
|
||||
"endDateTime": "2023-09-06T07:56:47.000Z",
|
||||
"additionalFields": {
|
||||
"categories": [
|
||||
"Yellow category",
|
||||
"Orange category"
|
||||
],
|
||||
"attendees": {
|
||||
"values": [
|
||||
{
|
||||
"email": "samantha@contoso.com",
|
||||
"name": "Samantha Booth",
|
||||
"type": "required"
|
||||
}
|
||||
]
|
||||
},
|
||||
"categories": ["Yellow category", "Orange category"],
|
||||
"body": "event description",
|
||||
"bodyPreview": "preview",
|
||||
"hideAttendees": true,
|
||||
|
|
@ -38,6 +41,7 @@
|
|||
"isCancelled": false,
|
||||
"isDraft": false,
|
||||
"isOnlineMeeting": true,
|
||||
"location": "Harry's Bar",
|
||||
"sensitivity": "personal",
|
||||
"showAs": "busy",
|
||||
"type": "occurrence"
|
||||
|
|
@ -47,10 +51,7 @@
|
|||
"name": "Microsoft Outlook",
|
||||
"type": "n8n-nodes-base.microsoftOutlook",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1040,
|
||||
360
|
||||
],
|
||||
"position": [1040, 360],
|
||||
"credentials": {
|
||||
"microsoftOutlookOAuth2Api": {
|
||||
"id": "iXJCki7i5Vz0bdks",
|
||||
|
|
@ -69,10 +70,7 @@
|
|||
"createdDateTime": "2023-09-04T10:12:47.1985121Z",
|
||||
"lastModifiedDateTime": "2023-09-04T10:12:48.2173253Z",
|
||||
"changeKey": "WX+A3vy5K0qqTyPHso1JgAABVtwgEQ==",
|
||||
"categories": [
|
||||
"Yellow category",
|
||||
"Orange category"
|
||||
],
|
||||
"categories": ["Yellow category", "Orange category"],
|
||||
"transactionId": null,
|
||||
"originalStartTimeZone": "UTC",
|
||||
"originalEndTimeZone": "UTC",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ import { NodeOperationError } from 'n8n-workflow';
|
|||
|
||||
import { updateDisplayOptions } from '@utils/utilities';
|
||||
|
||||
import { calendarRLC } from '../../descriptions';
|
||||
import { calendarRLC, eventAttendeesField, eventLocationField } from '../../descriptions';
|
||||
import { prepareEventFields } from '../../helpers/utils';
|
||||
import { microsoftApiRequest } from '../../transport';
|
||||
|
||||
export const properties: INodeProperties[] = [
|
||||
|
|
@ -38,6 +39,7 @@ export const properties: INodeProperties[] = [
|
|||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
options: [
|
||||
eventAttendeesField,
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-multi-options
|
||||
displayName: 'Categories',
|
||||
|
|
@ -117,6 +119,7 @@ export const properties: INodeProperties[] = [
|
|||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
eventLocationField,
|
||||
{
|
||||
displayName: 'Sensitivity',
|
||||
name: 'sensitivity',
|
||||
|
|
@ -251,6 +254,8 @@ export async function execute(this: IExecuteFunctions, index: number) {
|
|||
};
|
||||
}
|
||||
|
||||
additionalFields = prepareEventFields(additionalFields);
|
||||
|
||||
let startDateTime = this.getNodeParameter('startDateTime', index) as string;
|
||||
let endDateTime = this.getNodeParameter('endDateTime', index) as string;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import type { IDataObject, IExecuteFunctions, INodeProperties } from 'n8n-workfl
|
|||
|
||||
import { updateDisplayOptions } from '@utils/utilities';
|
||||
|
||||
import { calendarRLC, eventRLC } from '../../descriptions';
|
||||
import { decodeOutlookId } from '../../helpers/utils';
|
||||
import { calendarRLC, eventAttendeesField, eventLocationField, eventRLC } from '../../descriptions';
|
||||
import { decodeOutlookId, prepareEventFields } from '../../helpers/utils';
|
||||
import { microsoftApiRequest } from '../../transport';
|
||||
|
||||
export const properties: INodeProperties[] = [
|
||||
|
|
@ -17,6 +17,10 @@ export const properties: INodeProperties[] = [
|
|||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
...eventAttendeesField,
|
||||
description: 'Setting attendees on update replaces the entire attendee list',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-multi-options
|
||||
displayName: 'Categories',
|
||||
|
|
@ -102,6 +106,7 @@ export const properties: INodeProperties[] = [
|
|||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
eventLocationField,
|
||||
{
|
||||
displayName: 'Sensitivity',
|
||||
name: 'sensitivity',
|
||||
|
|
@ -210,7 +215,7 @@ const displayOptions = {
|
|||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(this: IExecuteFunctions, index: number) {
|
||||
const additionalFields = this.getNodeParameter('additionalFields', index);
|
||||
let additionalFields = this.getNodeParameter('additionalFields', index);
|
||||
|
||||
const eventId = decodeOutlookId(
|
||||
this.getNodeParameter('eventId', index, undefined, {
|
||||
|
|
@ -232,6 +237,8 @@ export async function execute(this: IExecuteFunctions, index: number) {
|
|||
};
|
||||
}
|
||||
|
||||
additionalFields = prepareEventFields(additionalFields);
|
||||
|
||||
let startDateTime = additionalFields.start as string;
|
||||
let endDateTime = additionalFields.end as string;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,65 @@
|
|||
import type { INodeProperties } from 'n8n-workflow';
|
||||
import type { INodeProperties, INodePropertyCollection } from 'n8n-workflow';
|
||||
|
||||
const attendeeValues: INodePropertyCollection = {
|
||||
displayName: 'Attendee',
|
||||
name: 'values',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Email',
|
||||
name: 'email',
|
||||
type: 'string',
|
||||
placeholder: 'name@email.com',
|
||||
required: true,
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
default: 'required',
|
||||
options: [
|
||||
{
|
||||
name: 'Optional',
|
||||
value: 'optional',
|
||||
},
|
||||
{
|
||||
name: 'Required',
|
||||
value: 'required',
|
||||
},
|
||||
{
|
||||
name: 'Resource',
|
||||
value: 'resource',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const eventAttendeesField: INodeProperties = {
|
||||
displayName: 'Attendees',
|
||||
name: 'attendees',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
default: {},
|
||||
placeholder: 'Add Attendee',
|
||||
options: [attendeeValues],
|
||||
};
|
||||
|
||||
export const eventLocationField: INodeProperties = {
|
||||
displayName: 'Location',
|
||||
name: 'location',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The location of the event (e.g. a meeting room name, address, or meeting link)',
|
||||
};
|
||||
|
||||
export const returnAllOrLimit: INodeProperties[] = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -229,6 +229,27 @@ export function prepareContactFields(fields: IDataObject) {
|
|||
return returnData;
|
||||
}
|
||||
|
||||
export function prepareEventFields(fields: IDataObject): IDataObject {
|
||||
const result = { ...fields };
|
||||
|
||||
if (result.location) {
|
||||
result.location = { displayName: result.location };
|
||||
}
|
||||
|
||||
if (result.attendees) {
|
||||
const attendeeEntries = ((result.attendees as IDataObject).values as IDataObject[]) ?? [];
|
||||
result.attendees = attendeeEntries.map((entry) => ({
|
||||
emailAddress: {
|
||||
address: entry.email,
|
||||
...(entry.name ? { name: entry.name } : {}),
|
||||
},
|
||||
type: entry.type,
|
||||
}));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function prepareFilterString(filters: IDataObject) {
|
||||
const selectedFilters = filters.filters as IDataObject;
|
||||
const filterString: string[] = [];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user