n8n/packages/nodes-base/nodes/Trello/Trello.node.ts

1435 lines
31 KiB
TypeScript
Raw Normal View History

2019-07-12 08:54:15 -07:00
import {
IExecuteFunctions,
} from 'n8n-core';
import {
IDataObject,
INodeTypeDescription,
INodeExecutionData,
INodeType,
} from 'n8n-workflow';
import {
apiRequest,
} from './GenericFunctions';
export class Trello implements INodeType {
description: INodeTypeDescription = {
displayName: 'Trello',
name: 'trello',
icon: 'file:trello.png',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Create, change and delete boards and cards',
defaults: {
name: 'Trello',
color: '#026aa7',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'trelloApi',
required: true,
}
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'Board',
value: 'board',
},
{
name: 'Card',
value: 'card',
},
{
name: 'List',
value: 'list',
},
],
default: 'card',
description: 'The resource to operate on.',
},
// ----------------------------------
// board
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'board',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new board',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a board',
},
{
name: 'Get',
value: 'get',
description: 'Get the data of a board',
},
{
name: 'Update',
value: 'update',
description: 'Update a board',
},
],
default: 'create',
description: 'The operation to perform.',
},
// ----------------------------------
// board:create
// ----------------------------------
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
placeholder: 'My board',
required: true,
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'board',
],
},
},
description: 'The name of the board',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'board',
],
},
},
description: 'The description of the board',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'board',
],
},
},
default: {},
options: [
{
displayName: 'Aging',
name: 'prefs_cardAging',
type: 'options',
options: [
{
name: 'Pirate',
value: 'pirate',
},
{
name: 'Regular',
value: 'regular',
},
],
default: 'regular',
description: 'Determines the type of card aging that should take place on the board if card aging is enabled.',
},
{
displayName: 'Background',
name: 'prefs_background',
type: 'string',
default: 'blue',
description: 'The id of a custom background or one of: blue, orange, green, red, purple, pink, lime, sky, grey.',
},
{
displayName: 'Comments',
name: 'prefs_comments',
type: 'options',
options: [
{
name: 'Disabled',
value: 'disabled',
},
{
name: 'Members',
value: 'members',
},
{
name: 'Observers',
value: 'observers',
},
{
name: 'Organization',
value: 'org',
},
{
name: 'Public',
value: 'public',
},
],
default: 'members',
description: 'Who can comment on cards on this board.',
},
{
displayName: 'Covers',
name: 'prefs_cardCovers',
type: 'boolean',
default: true,
description: 'Determines whether card covers are enabled.',
},
{
displayName: 'Invitations',
name: 'prefs_invitations',
type: 'options',
options: [
{
name: 'Admins',
value: 'admins',
},
{
name: 'Members',
value: 'members',
},
],
default: 'members',
description: 'Determines what types of members can invite users to join.',
},
{
displayName: 'Keep From Source',
name: 'keepFromSource',
type: 'string',
default: 'none',
description: 'To keep cards from the original board pass in the value cards.',
},
{
displayName: 'Labels',
name: 'defaultLabels',
type: 'boolean',
default: true,
description: 'Determines whether to use the default set of labels.',
},
{
displayName: 'Lists',
name: 'defaultLists',
type: 'boolean',
default: true,
description: 'Determines whether to add the default set of lists to a board(To Do, Doing, Done).It is ignored if idBoardSource is provided.',
},
{
displayName: 'Organization ID',
name: 'idOrganization',
type: 'string',
default: '',
description: 'The id or name of the team the board should belong to.',
},
{
displayName: 'Permission Level',
name: 'prefs_permissionLevel',
type: 'options',
options: [
{
name: 'Organization',
value: 'org',
},
{
name: 'Private',
value: 'private',
},
{
name: 'Public',
value: 'public',
},
],
default: 'private',
description: 'The permissions level of the board.',
},
{
displayName: 'Power Ups',
name: 'powerUps',
type: 'options',
options: [
{
name: 'All',
value: 'all',
},
{
name: 'Calendar',
value: 'calendar',
},
{
name: 'Card Aging',
value: 'cardAging',
},
{
name: 'Recap',
value: 'recap',
},
{
name: 'Voting',
value: 'voting',
},
],
default: 'all',
description: 'The Power-Ups that should be enabled on the new board.',
},
{
displayName: 'Self Join',
name: 'prefs_selfJoin',
type: 'boolean',
default: true,
description: 'Determines whether users can join the boards themselves or whether they have to be invited.',
},
{
displayName: 'Source IDs',
name: 'idBoardSource',
type: 'string',
default: '',
description: 'The id of a board to copy into the new board.',
},
{
displayName: 'Voting',
name: 'prefs_voting',
type: 'options',
options: [
{
name: 'Disabled',
value: 'disabled',
},
{
name: 'Members',
value: 'members',
},
{
name: 'Observers',
value: 'observers',
},
{
name: 'Organization',
value: 'org',
},
{
name: 'Public',
value: 'public',
},
],
default: 'disabled',
description: 'Who can vote on this board.',
},
],
},
// ----------------------------------
// board:delete
// ----------------------------------
{
displayName: 'Board ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'delete',
],
resource: [
'board',
],
},
},
description: 'The ID of the board to delete.',
},
// ----------------------------------
// board:get
// ----------------------------------
{
displayName: 'Board ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'get',
],
resource: [
'board',
],
},
},
description: 'The ID of the board to get.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'get',
],
resource: [
'board',
],
},
},
default: {},
options: [
{
displayName: 'Fields',
name: 'fields',
type: 'string',
default: 'all',
description: 'Fields to return. Either "all" or a comma-separated list:<br />closed, dateLastActivity, dateLastView, desc, descData,<br />idOrganization, invitations, invited, labelNames, memberships,<br />name, pinned, powerUps, prefs, shortLink, shortUrl,<br />starred, subscribed, url',
},
{
displayName: 'Plugin Data',
name: 'pluginData',
type: 'boolean',
default: false,
description: 'Whether to include pluginData on the card with the response.',
},
],
},
// ----------------------------------
// board:update
// ----------------------------------
{
displayName: 'Board ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'update',
],
resource: [
'board',
],
},
},
description: 'The ID of the board to update.',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'update',
],
resource: [
'board',
],
},
},
default: {},
options: [
{
displayName: 'Closed',
name: 'closed',
type: 'boolean',
default: false,
description: 'Whether the board is closed.',
},
{
displayName: 'Description',
name: 'desc',
type: 'string',
default: '',
description: 'New description of the board',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'New name of the board',
},
{
displayName: 'Organization ID',
name: 'idOrganization',
type: 'string',
default: '',
description: 'The id of the team the board should be moved to.',
},
{
displayName: 'Subscribed',
name: 'subscribed',
type: 'boolean',
default: false,
description: 'Whether the acting user is subscribed to the board.',
},
],
},
// ----------------------------------
// card
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'card',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new card',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a card',
},
{
name: 'Get',
value: 'get',
description: 'Get the data of a card',
},
{
name: 'Update',
value: 'update',
description: 'Update a card',
},
],
default: 'create',
description: 'The operation to perform.',
},
// ----------------------------------
// card:create
// ----------------------------------
{
displayName: 'List ID',
name: 'listId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'card',
],
},
},
description: 'The id of the list to create card in',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
placeholder: 'My card',
required: true,
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'card',
],
},
},
description: 'The name of the card',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'card',
],
},
},
description: 'The description of the card',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'card',
],
},
},
default: {},
options: [
{
displayName: 'Due Date',
name: 'due',
type: 'dateTime',
default: '',
description: 'A due date for the card.',
},
{
displayName: 'Due Complete',
name: 'dueComplete',
type: 'boolean',
default: false,
description: 'If the card is completed.',
},
{
displayName: 'Position',
name: 'pos',
type: 'string',
default: 'bottom',
description: 'The position of the new card. top, bottom, or a positive float.',
},
{
displayName: 'Member IDs',
name: 'idMembers',
type: 'string',
default: '',
description: 'Comma-separated list of member IDs to add to the card.',
},
{
displayName: 'Label IDs',
name: 'idLabels',
type: 'string',
default: '',
description: 'Comma-separated list of label IDs to add to the card.',
},
{
displayName: 'URL Source',
name: 'urlSource',
type: 'string',
default: '',
description: 'A source URL to attach to card.',
},
{
displayName: 'Source ID',
name: 'idCardSource',
type: 'string',
default: '',
description: 'The ID of a card to copy into the new card.',
},
{
displayName: 'Keep from source',
name: 'keepFromSource',
type: 'string',
default: 'all',
description: 'If using idCardSource you can specify which properties to copy over. all or comma-separated list of: attachments, checklists, comments, due, labels, members, stickers',
},
],
},
// ----------------------------------
// card:delete
// ----------------------------------
{
displayName: 'Card ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'delete',
],
resource: [
'card',
],
},
},
description: 'The ID of the card to delete.',
},
// ----------------------------------
// card:get
// ----------------------------------
{
displayName: 'Card ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'get',
],
resource: [
'card',
],
},
},
description: 'The ID of the card to get.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'get',
],
resource: [
'card',
],
},
},
default: {},
options: [
{
displayName: 'Fields',
name: 'fields',
type: 'string',
default: 'all',
description: 'Fields to return. Either "all" or a comma-separated list:<br />badges, checkItemStates, closed, dateLastActivity, desc,<br />descData, due, email, idBoard, idChecklists, idLabels, idList,<br />idMembers, idShort, idAttachmentCover, manualCoverAttachment<br />, labels, name, pos, shortUrl, url',
},
{
displayName: 'Board',
name: 'board',
type: 'boolean',
default: false,
description: 'Whether to return the board object the card is on.',
},
{
displayName: 'Board Fields',
name: 'board_fields',
type: 'string',
default: 'all',
description: 'Fields to return. Either "all" or a comma-separated list:<br />name, desc, descData, closed, idOrganization, pinned, url, prefs',
},
{
displayName: 'Custom Field Items',
name: 'customFieldItems',
type: 'boolean',
default: false,
description: 'Whether to include the customFieldItems.',
},
{
displayName: 'Members',
name: 'members',
type: 'boolean',
default: false,
description: 'Whether to return member objects for members on the card.',
},
{
displayName: 'Member Fields',
name: 'member_fields',
type: 'string',
default: 'all',
description: 'Fields to return. Either "all" or a comma-separated list:<br />avatarHash, fullName, initials, username',
},
{
displayName: 'Plugin Data',
name: 'pluginData',
type: 'boolean',
default: false,
description: 'Whether to include pluginData on the card with the response.',
},
{
displayName: 'Stickers',
name: 'stickers',
type: 'boolean',
default: false,
description: 'Whether to include sticker models with the response.',
},
{
displayName: 'Sticker Fields',
name: 'sticker_fields',
type: 'string',
default: 'all',
description: 'Fields to return. Either "all" or a comma-separated list of sticker fields.',
},
],
},
// ----------------------------------
// card:update
// ----------------------------------
{
displayName: 'Card ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'update',
],
resource: [
'card',
],
},
},
description: 'The ID of the card to update.',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'update',
],
resource: [
'card',
],
},
},
default: {},
options: [
{
displayName: 'Attachment Cover',
name: 'idAttachmentCover',
type: 'string',
default: '',
description: 'The ID of the image attachment the card should use as its cover, or null for none.',
},
{
displayName: 'Board ID',
name: 'idBoard',
type: 'string',
default: '',
description: 'The ID of the board the card should be on.',
},
{
displayName: 'Closed',
name: 'closed',
type: 'boolean',
default: false,
description: 'Whether the board is closed.',
},
{
displayName: 'Description',
name: 'desc',
type: 'string',
default: '',
description: 'New description of the board.',
},
{
displayName: 'Due Date',
name: 'due',
type: 'dateTime',
default: '',
description: 'A due date for the card.',
},
{
displayName: 'Due Complete',
name: 'dueComplete',
type: 'boolean',
default: false,
description: 'If the card is completed.',
},
{
displayName: 'Label IDs',
name: 'idLabels',
type: 'string',
default: '',
description: 'Comma-separated list of label IDs to set on card.',
},
{
displayName: 'List ID',
name: 'idList',
type: 'string',
default: '',
description: 'The ID of the list the card should be in.',
},
{
displayName: 'Member IDs',
name: 'idMembers',
type: 'string',
default: '',
description: 'Comma-separated list of member IDs to set on card.',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'New name of the board',
},
{
displayName: 'Position',
name: 'pos',
type: 'string',
default: 'bottom',
description: 'The position of the card. top, bottom, or a positive float.',
},
{
displayName: 'Subscribed',
name: 'subscribed',
type: 'boolean',
default: false,
description: 'Whether the acting user is subscribed to the board.',
},
],
},
// ----------------------------------
// list
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'list',
],
},
},
options: [
{
name: 'Archive',
value: 'archive',
description: 'Archive/Unarchive a list',
},
{
name: 'Create',
value: 'create',
description: 'Create a new list',
},
{
name: 'Get',
value: 'get',
description: 'Get the data of a list',
},
{
name: 'Update',
value: 'update',
description: 'Update a list',
},
],
default: 'create',
description: 'The operation to perform.',
},
// ----------------------------------
// list:archive
// ----------------------------------
{
displayName: 'List ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'archive',
],
resource: [
'list',
],
},
},
description: 'The ID of the list to archive or unarchive.',
},
{
displayName: 'Archive',
name: 'archive',
type: 'boolean',
default: false,
displayOptions: {
show: {
operation: [
'archive',
],
resource: [
'list',
],
},
},
description: 'If the list should be archived or unarchived.',
},
// ----------------------------------
// list:create
// ----------------------------------
{
displayName: 'Board ID',
name: 'idBoard',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'list',
],
},
},
description: 'The ID of the board the list should be created in',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
placeholder: 'My list',
required: true,
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'list',
],
},
},
description: 'The name of the list',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'create',
],
resource: [
'list',
],
},
},
default: {},
options: [
{
displayName: 'List Source',
name: 'idListSource',
type: 'string',
default: '',
description: 'ID of the list to copy into the new list.',
},
{
displayName: 'Position',
name: 'pos',
type: 'string',
default: 'bottom',
description: 'The position of the new list. top, bottom, or a positive float.',
},
],
},
// ----------------------------------
// list:get
// ----------------------------------
{
displayName: 'List ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'get',
],
resource: [
'list',
],
},
},
description: 'The ID of the list to get.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'get',
],
resource: [
'list',
],
},
},
default: {},
options: [
{
displayName: 'Fields',
name: 'fields',
type: 'string',
default: 'all',
description: 'Fields to return. Either "all" or a comma-separated list of fields.',
},
],
},
// ----------------------------------
// list:update
// ----------------------------------
{
displayName: 'List ID',
name: 'id',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'update',
],
resource: [
'list',
],
},
},
description: 'The ID of the list to update.',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: [
'update',
],
resource: [
'list',
],
},
},
default: {},
options: [
{
displayName: 'Board ID',
name: 'idBoard',
type: 'string',
default: '',
description: 'ID of a board the list should be moved to.',
},
{
displayName: 'Closed',
name: 'closed',
type: 'boolean',
default: false,
description: 'Whether the list is closed.',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'New name of the list',
},
{
displayName: 'Position',
name: 'pos',
type: 'string',
default: 'bottom',
description: 'The position of the list. top, bottom, or a positive float.',
},
{
displayName: 'Subscribed',
name: 'subscribed',
type: 'boolean',
default: false,
description: 'Whether the acting user is subscribed to the list.',
},
],
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: IDataObject[] = [];
const operation = this.getNodeParameter('operation', 0) as string;
const resource = this.getNodeParameter('resource', 0) as string;
// For Post
let body: IDataObject;
// For Query string
let qs: IDataObject;
let requestMethod: string;
let endpoint: string;
for (let i = 0; i < items.length; i++) {
requestMethod = 'GET';
endpoint = '';
body = {};
qs = {};
if (resource === 'board') {
if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
endpoint = 'boards';
qs.name = this.getNodeParameter('name', i) as string;
qs.desc = this.getNodeParameter('description', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(qs, additionalFields);
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const id = this.getNodeParameter('id', i) as string;
endpoint = `boards/${id}`;
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const id = this.getNodeParameter('id', i) as string;
endpoint = `boards/${id}`;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(qs, additionalFields);
} else if (operation === 'update') {
// ----------------------------------
// update
// ----------------------------------
requestMethod = 'PUT';
const id = this.getNodeParameter('id', i) as string;
endpoint = `boards/${id}`;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
Object.assign(qs, updateFields);
} else {
throw new Error(`The operation "${operation}" is not known!`);
}
} else if (resource === 'card') {
if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
endpoint = 'cards';
qs.idList = this.getNodeParameter('listId', i) as string;
qs.name = this.getNodeParameter('name', i) as string;
qs.desc = this.getNodeParameter('description', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(qs, additionalFields);
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const id = this.getNodeParameter('id', i) as string;
endpoint = `cards/${id}`;
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const id = this.getNodeParameter('id', i) as string;
endpoint = `cards/${id}`;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(qs, additionalFields);
} else if (operation === 'update') {
// ----------------------------------
// update
// ----------------------------------
requestMethod = 'PUT';
const id = this.getNodeParameter('id', i) as string;
endpoint = `cards/${id}`;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
Object.assign(qs, updateFields);
} else {
throw new Error(`The operation "${operation}" is not known!`);
}
} else if (resource === 'list') {
if (operation === 'archive') {
// ----------------------------------
// archive
// ----------------------------------
requestMethod = 'PUT';
const id = this.getNodeParameter('id', i) as string;
qs.value = this.getNodeParameter('archive', i) as boolean;
endpoint = `lists/${id}/closed`;
} else if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
endpoint = 'lists';
qs.idBoard = this.getNodeParameter('idBoard', i) as string;
qs.name = this.getNodeParameter('name', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(qs, additionalFields);
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const id = this.getNodeParameter('id', i) as string;
endpoint = `lists/${id}`;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
Object.assign(qs, additionalFields);
} else if (operation === 'update') {
// ----------------------------------
// update
// ----------------------------------
requestMethod = 'PUT';
const id = this.getNodeParameter('id', i) as string;
endpoint = `lists/${id}`;
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
Object.assign(qs, updateFields);
} else {
throw new Error(`The operation "${operation}" is not known!`);
}
} else {
throw new Error(`The resource "${resource}" is not known!`);
}
const responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs);
returnData.push(responseData as IDataObject);
}
return [this.helpers.returnJsonArray(returnData)];
}
}