add Google tasks API

This commit is contained in:
shraddha shaligram
2020-06-15 15:47:44 -07:00
parent 2ef5c8c836
commit 136596f465
9 changed files with 1429 additions and 481 deletions

View File

@@ -1,6 +1,4 @@
import {
IExecuteFunctions,
} from 'n8n-core';
import { IExecuteFunctions } from 'n8n-core';
import {
IDataObject,
@@ -8,22 +6,14 @@ import {
INodeTypeDescription,
INodeType,
ILoadOptionsFunctions,
INodePropertyOptions,
INodePropertyOptions
} from 'n8n-workflow';
import {
googleApiRequest,
googleApiRequestAllItems,
} from './GenericFunctions';
import { googleApiRequest, googleApiRequestAllItems } from './GenericFunctions';
import {
eventOperations,
eventFields,
} from './EventDescription';
import { eventOperations, eventFields } from './EventDescription';
import {
IEvent,
} from './EventInterface';
import { IEvent } from './EventInterface';
import * as moment from 'moment-timezone';
@@ -38,15 +28,15 @@ export class GoogleCalendar implements INodeType {
description: 'Consume Google Calendar API.',
defaults: {
name: 'Google Calendar',
color: '#3E87E4',
color: '#3E87E4'
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'googleCalendarOAuth2Api',
required: true,
},
required: true
}
],
properties: [
{
@@ -56,70 +46,85 @@ export class GoogleCalendar implements INodeType {
options: [
{
name: 'Event',
value: 'event',
},
value: 'event'
}
],
default: 'event',
description: 'The resource to operate on.',
description: 'The resource to operate on.'
},
...eventOperations,
...eventFields,
],
...eventFields
]
};
methods = {
loadOptions: {
// Get all the calendars to display them to user so that he can
// select them easily
async getCalendars(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
async getCalendars(
this: ILoadOptionsFunctions
): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const calendars = await googleApiRequestAllItems.call(this, 'items', 'GET', '/calendar/v3/users/me/calendarList');
const calendars = await googleApiRequestAllItems.call(
this,
'items',
'GET',
'/calendar/v3/users/me/calendarList'
);
for (const calendar of calendars) {
const calendarName = calendar.summary;
const calendarId = calendar.id;
returnData.push({
name: calendarName,
value: calendarId,
value: calendarId
});
}
return returnData;
},
// Get all the colors to display them to user so that he can
// select them easily
async getColors(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
async getColors(
this: ILoadOptionsFunctions
): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const { calendar } = await googleApiRequest.call(this, 'GET', '/calendar/v3/colors');
for (const key of Object.keys(calendar)) {
const { calendar } = await googleApiRequest.call(
this,
'GET',
'/calendar/v3/colors'
);
for (const key of Object.keys(calendar)) {
const colorName = calendar[key].background;
const colorId = key;
returnData.push({
name: `${colorName} - ${colorId}`,
value: colorId,
value: colorId
});
}
return returnData;
},
// Get all the timezones to display them to user so that he can
// select them easily
async getTimezones(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
async getTimezones(
this: ILoadOptionsFunctions
): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
for (const timezone of moment.tz.names()) {
const timezoneName = timezone;
const timezoneId = timezone;
returnData.push({
name: timezoneName,
value: timezoneId,
value: timezoneId
});
}
return returnData;
},
},
}
}
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: IDataObject[] = [];
const length = items.length as unknown as number;
const length = (items.length as unknown) as number;
const qs: IDataObject = {};
let responseData;
const resource = this.getNodeParameter('resource', 0) as string;
@@ -131,8 +136,14 @@ export class GoogleCalendar implements INodeType {
const calendarId = this.getNodeParameter('calendar', i) as string;
const start = this.getNodeParameter('start', i) as string;
const end = this.getNodeParameter('end', i) as string;
const useDefaultReminders = this.getNodeParameter('useDefaultReminders', i) as boolean;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const useDefaultReminders = this.getNodeParameter(
'useDefaultReminders',
i
) as boolean;
const additionalFields = this.getNodeParameter(
'additionalFields',
i
) as IDataObject;
if (additionalFields.maxAttendees) {
qs.maxAttendees = additionalFields.maxAttendees as number;
}
@@ -145,17 +156,19 @@ export class GoogleCalendar implements INodeType {
const body: IEvent = {
start: {
dateTime: start,
timeZone: additionalFields.timeZone || this.getTimezone(),
timeZone: additionalFields.timeZone || this.getTimezone()
},
end: {
dateTime: end,
timeZone: additionalFields.timeZone || this.getTimezone(),
timeZone: additionalFields.timeZone || this.getTimezone()
}
};
if (additionalFields.attendees) {
body.attendees = (additionalFields.attendees as string[]).map(attendee => {
return { email: attendee };
});
body.attendees = (additionalFields.attendees as string[]).map(
attendee => {
return { email: attendee };
}
);
}
if (additionalFields.color) {
body.colorId = additionalFields.color as string;
@@ -188,9 +201,12 @@ export class GoogleCalendar implements INodeType {
body.visibility = additionalFields.visibility as string;
}
if (!useDefaultReminders) {
const reminders = (this.getNodeParameter('remindersUi', i) as IDataObject).remindersValues as IDataObject[];
const reminders = (this.getNodeParameter(
'remindersUi',
i
) as IDataObject).remindersValues as IDataObject[];
body.reminders = {
useDefault: false,
useDefault: false
};
if (reminders) {
body.reminders.overrides = reminders;
@@ -198,32 +214,54 @@ export class GoogleCalendar implements INodeType {
}
if (additionalFields.allday) {
body.start = {
date: moment(start).utc().format('YYYY-MM-DD'),
date: moment(start)
.utc()
.format('YYYY-MM-DD')
};
body.end = {
date: moment(end).utc().format('YYYY-MM-DD'),
date: moment(end)
.utc()
.format('YYYY-MM-DD')
};
}
//exampel: RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=10;UNTIL=20110701T170000Z
//https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-rule.html
body.recurrence = [];
if (additionalFields.repeatHowManyTimes
&& additionalFields.repeatUntil) {
throw new Error(`You can set either 'Repeat How Many Times' or 'Repeat Until' but not both`);
if (
additionalFields.repeatHowManyTimes &&
additionalFields.repeatUntil
) {
throw new Error(
`You can set either 'Repeat How Many Times' or 'Repeat Until' but not both`
);
}
if (additionalFields.repeatFrecuency) {
body.recurrence?.push(`FREQ=${(additionalFields.repeatFrecuency as string).toUpperCase()};`);
body.recurrence?.push(
`FREQ=${(additionalFields.repeatFrecuency as string).toUpperCase()};`
);
}
if (additionalFields.repeatHowManyTimes) {
body.recurrence?.push(`COUNT=${additionalFields.repeatHowManyTimes};`);
body.recurrence?.push(
`COUNT=${additionalFields.repeatHowManyTimes};`
);
}
if (additionalFields.repeatUntil) {
body.recurrence?.push(`UNTIL=${moment(additionalFields.repeatUntil as string).utc().format('YYYYMMDDTHHmmss')}Z`);
body.recurrence?.push(
`UNTIL=${moment(additionalFields.repeatUntil as string)
.utc()
.format('YYYYMMDDTHHmmss')}Z`
);
}
if (body.recurrence.length !== 0) {
body.recurrence = [`RRULE:${body.recurrence.join('')}`];
}
responseData = await googleApiRequest.call(this, 'POST', `/calendar/v3/calendars/${calendarId}/events`, body, qs);
responseData = await googleApiRequest.call(
this,
'POST',
`/calendar/v3/calendars/${calendarId}/events`,
body,
qs
);
}
//https://developers.google.com/calendar/v3/reference/events/delete
if (operation === 'delete') {
@@ -233,8 +271,13 @@ export class GoogleCalendar implements INodeType {
if (options.sendUpdates) {
qs.sendUpdates = options.sendUpdates as number;
}
responseData = await googleApiRequest.call(this, 'DELETE', `/calendar/v3/calendars/${calendarId}/events/${eventId}`, {});
responseData = { success: true };
responseData = await googleApiRequest.call(
this,
'DELETE',
`/calendar/v3/calendars/${calendarId}/events/${eventId}`,
{}
);
responseData = { success: true };
}
//https://developers.google.com/calendar/v3/reference/events/get
if (operation === 'get') {
@@ -247,7 +290,13 @@ export class GoogleCalendar implements INodeType {
if (options.timeZone) {
qs.timeZone = options.timeZone as string;
}
responseData = await googleApiRequest.call(this, 'GET', `/calendar/v3/calendars/${calendarId}/events/${eventId}`, {}, qs);
responseData = await googleApiRequest.call(
this,
'GET',
`/calendar/v3/calendars/${calendarId}/events/${eventId}`,
{},
qs
);
}
//https://developers.google.com/calendar/v3/reference/events/list
if (operation === 'getAll') {
@@ -288,10 +337,23 @@ export class GoogleCalendar implements INodeType {
qs.updatedMin = options.updatedMin as string;
}
if (returnAll) {
responseData = await googleApiRequestAllItems.call(this, 'items', 'GET', `/calendar/v3/calendars/${calendarId}/events`, {}, qs);
responseData = await googleApiRequestAllItems.call(
this,
'items',
'GET',
`/calendar/v3/calendars/${calendarId}/events`,
{},
qs
);
} else {
qs.maxResults = this.getNodeParameter('limit', i) as number;
responseData = await googleApiRequest.call(this, 'GET', `/calendar/v3/calendars/${calendarId}/events`, {}, qs);
responseData = await googleApiRequest.call(
this,
'GET',
`/calendar/v3/calendars/${calendarId}/events`,
{},
qs
);
responseData = responseData.items;
}
}
@@ -299,8 +361,14 @@ export class GoogleCalendar implements INodeType {
if (operation === 'update') {
const calendarId = this.getNodeParameter('calendar', i) as string;
const eventId = this.getNodeParameter('eventId', i) as string;
const useDefaultReminders = this.getNodeParameter('useDefaultReminders', i) as boolean;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
const useDefaultReminders = this.getNodeParameter(
'useDefaultReminders',
i
) as boolean;
const updateFields = this.getNodeParameter(
'updateFields',
i
) as IDataObject;
if (updateFields.maxAttendees) {
qs.maxAttendees = updateFields.maxAttendees as number;
}
@@ -314,19 +382,21 @@ export class GoogleCalendar implements INodeType {
if (updateFields.start) {
body.start = {
dateTime: updateFields.start,
timeZone: updateFields.timeZone || this.getTimezone(),
timeZone: updateFields.timeZone || this.getTimezone()
};
}
if (updateFields.end) {
body.end = {
dateTime: updateFields.end,
timeZone: updateFields.timeZone || this.getTimezone(),
timeZone: updateFields.timeZone || this.getTimezone()
};
}
if (updateFields.attendees) {
body.attendees = (updateFields.attendees as string[]).map(attendee => {
return { email: attendee };
});
body.attendees = (updateFields.attendees as string[]).map(
attendee => {
return { email: attendee };
}
);
}
if (updateFields.color) {
body.colorId = updateFields.color as string;
@@ -359,46 +429,64 @@ export class GoogleCalendar implements INodeType {
body.visibility = updateFields.visibility as string;
}
if (!useDefaultReminders) {
const reminders = (this.getNodeParameter('remindersUi', i) as IDataObject).remindersValues as IDataObject[];
const reminders = (this.getNodeParameter(
'remindersUi',
i
) as IDataObject).remindersValues as IDataObject[];
body.reminders = {
useDefault: false,
useDefault: false
};
if (reminders) {
body.reminders.overrides = reminders;
}
}
if (updateFields.allday
&& updateFields.start
&& updateFields.end) {
if (updateFields.allday && updateFields.start && updateFields.end) {
body.start = {
date: moment(updateFields.start as string).utc().format('YYYY-MM-DD'),
date: moment(updateFields.start as string)
.utc()
.format('YYYY-MM-DD')
};
body.end = {
date: moment(updateFields.end as string).utc().format('YYYY-MM-DD'),
date: moment(updateFields.end as string)
.utc()
.format('YYYY-MM-DD')
};
}
//exampel: RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=10;UNTIL=20110701T170000Z
//https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-rule.html
body.recurrence = [];
if (updateFields.repeatHowManyTimes
&& updateFields.repeatUntil) {
throw new Error(`You can set either 'Repeat How Many Times' or 'Repeat Until' but not both`);
if (updateFields.repeatHowManyTimes && updateFields.repeatUntil) {
throw new Error(
`You can set either 'Repeat How Many Times' or 'Repeat Until' but not both`
);
}
if (updateFields.repeatFrecuency) {
body.recurrence?.push(`FREQ=${(updateFields.repeatFrecuency as string).toUpperCase()};`);
body.recurrence?.push(
`FREQ=${(updateFields.repeatFrecuency as string).toUpperCase()};`
);
}
if (updateFields.repeatHowManyTimes) {
body.recurrence?.push(`COUNT=${updateFields.repeatHowManyTimes};`);
}
if (updateFields.repeatUntil) {
body.recurrence?.push(`UNTIL=${moment(updateFields.repeatUntil as string).utc().format('YYYYMMDDTHHmmss')}Z`);
body.recurrence?.push(
`UNTIL=${moment(updateFields.repeatUntil as string)
.utc()
.format('YYYYMMDDTHHmmss')}Z`
);
}
if (body.recurrence.length !== 0) {
body.recurrence = [`RRULE:${body.recurrence.join('')}`];
} else {
delete body.recurrence;
}
responseData = await googleApiRequest.call(this, 'PATCH', `/calendar/v3/calendars/${calendarId}/events/${eventId}`, body, qs);
responseData = await googleApiRequest.call(
this,
'PATCH',
`/calendar/v3/calendars/${calendarId}/events/${eventId}`,
body,
qs
);
}
}
}