diff --git a/packages/nodes-base/credentials/TodoistApi.credentials.ts b/packages/nodes-base/credentials/TodoistApi.credentials.ts new file mode 100644 index 0000000000..cec053e40e --- /dev/null +++ b/packages/nodes-base/credentials/TodoistApi.credentials.ts @@ -0,0 +1,18 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + + +export class TodoistApi implements ICredentialType { + name = 'todoistApi'; + displayName = 'Todoist API'; + properties = [ + { + displayName: 'API Key', + name: 'apiKey', + type: 'string' as NodePropertyTypes, + default: '', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Todoist/GenericFunctions.ts b/packages/nodes-base/nodes/Todoist/GenericFunctions.ts new file mode 100644 index 0000000000..f98b54f1c7 --- /dev/null +++ b/packages/nodes-base/nodes/Todoist/GenericFunctions.ts @@ -0,0 +1,101 @@ +import { OptionsWithUri } from 'request'; + +import { + IExecuteFunctions, + IHookFunctions, + ILoadOptionsFunctions, + IExecuteSingleFunctions +} from 'n8n-core'; + +import * as _ from 'lodash'; +import { IDataObject } from 'n8n-workflow'; + +export async function mandrillApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, resource: string, method: string, action: string, body: any = {}, headers?: object): Promise { // tslint:disable-line:no-any + const credentials = this.getCredentials('mandrillApi'); + + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + const data = Object.assign({}, body, { key: credentials.apiKey }); + + const endpoint = 'mandrillapp.com/api/1.0'; + + const options: OptionsWithUri = { + headers, + method, + uri: `https://${endpoint}${resource}${action}.json`, + body: data, + json: true + }; + + + try { + return await this.helpers.request!(options); + } catch (error) { + console.error(error); + + const errorMessage = error.response.body.message || error.response.body.Message; + if (error.name === 'Invalid_Key') { + throw new Error('The provided API key is not a valid Mandrill API key'); + } else if (error.name === 'ValidationError') { + throw new Error('The parameters passed to the API call are invalid or not provided when required'); + } else if (error.name === 'GeneralError') { + throw new Error('An unexpected error occurred processing the request. Mandrill developers will be notified.'); + } + + if (errorMessage !== undefined) { + throw errorMessage; + } + throw error.response.body; + } +} + +export function getToEmailArray(toEmail: string): any { // tslint:disable-line:no-any + let toEmailArray; + if (toEmail.split(',').length > 0) { + const array = toEmail.split(','); + toEmailArray = _.map(array, (email) => { + return { + email, + type: 'to' + }; + }); + } else { + toEmailArray = [{ + email: toEmail, + type: 'to' + }]; + } + return toEmailArray; +} + +export function getGoogleAnalyticsDomainsArray(s: string): string[] { + let array: string[] = []; + if (s.split(',').length > 0) { + array = s.split(','); + } else { + array = [s]; + } + return array; +} + +export function getTags(s: string): any[] { // tslint:disable-line:no-any + let array = []; + if (s.split(',').length > 0) { + array = s.split(','); + } else { + array = [s]; + } + return array; +} + +export function validateJSON(json: string | undefined): any { // tslint:disable-line:no-any + let result; + try { + result = JSON.parse(json!); + } catch (exception) { + result = []; + } + return result; +} diff --git a/packages/nodes-base/nodes/Todoist/Todoist.node.ts b/packages/nodes-base/nodes/Todoist/Todoist.node.ts new file mode 100644 index 0000000000..b2f6b7dd22 --- /dev/null +++ b/packages/nodes-base/nodes/Todoist/Todoist.node.ts @@ -0,0 +1,90 @@ +import { + IExecuteSingleFunctions, +} from 'n8n-core'; +import { + IDataObject, + INodeTypeDescription, + INodeExecutionData, + INodeType, + ILoadOptionsFunctions, + INodePropertyOptions, +} from 'n8n-workflow'; +import { + mandrillApiRequest, + getToEmailArray, + getGoogleAnalyticsDomainsArray, + getTags, + validateJSON +} from './GenericFunctions'; + +export class Todoist implements INodeType { + + //https://mandrillapp.com/api/docs/messages.JSON.html#method=send-template + + description: INodeTypeDescription = { + displayName: 'Todoist', + name: 'todoist', + icon: 'file:todoist.png', + group: ['output'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Consume Todoist API', + defaults: { + name: 'Todoist', + color: '#c02428', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'todoistApi', + required: true, + } + ], + //multiOptions + properties: [ + { + displayName: 'Testing', + name: 'testing', + placeholder: 'blabla', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + options: [ + { + name: 'label', + displayName: 'label', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'options', + default: '', + options: [ + { + name: 'Message', + value: 'message', + description: 'Send a message.', + }, + ], + }, + { + displayName: 'Content', + name: 'content', + type: 'string', + default: '', + }, + ], + }, + ], + }, + ], + }; + + async executeSingle(this: IExecuteSingleFunctions): Promise { + + + } +} diff --git a/packages/nodes-base/nodes/Todoist/todoist.png b/packages/nodes-base/nodes/Todoist/todoist.png new file mode 100644 index 0000000000..44691b2e49 Binary files /dev/null and b/packages/nodes-base/nodes/Todoist/todoist.png differ diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 2b6ddeca77..6af0a99a5c 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -56,7 +56,8 @@ "dist/credentials/TrelloApi.credentials.js", "dist/credentials/TwilioApi.credentials.js", "dist/credentials/TypeformApi.credentials.js", - "dist/credentials/MandrillApi.credentials.js" + "dist/credentials/MandrillApi.credentials.js", + "dist/credentials/TodoistApi.credentials.js" ], "nodes": [ "dist/nodes/ActiveCampaign/ActiveCampaign.node.js", @@ -122,7 +123,8 @@ "dist/nodes/WriteBinaryFile.node.js", "dist/nodes/Webhook.node.js", "dist/nodes/Xml.node.js", - "dist/nodes/Mandrill/Mandrill.node.js" + "dist/nodes/Mandrill/Mandrill.node.js", + "dist/nodes/Todoist/Todoist.node.js" ] }, "devDependencies": {