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

208 lines
5.3 KiB
TypeScript
Raw Normal View History

2020-03-05 15:25:18 -08:00
import {
IExecuteFunctions,
} from 'n8n-core';
2019-06-23 03:35:23 -07:00
import {
IDataObject,
INodeTypeDescription,
INodeExecutionData,
INodeType,
2020-03-05 15:25:18 -08:00
ILoadOptionsFunctions,
INodePropertyOptions,
2019-06-23 03:35:23 -07:00
} from 'n8n-workflow';
2020-03-05 15:25:18 -08:00
import {
channelOperations,
channelFields,
} from './ChannelDescription';
import {
messageOperations,
messageFields,
} from './MessageDescription';
import {
conversationOperations,
conversationFields,
} from './ConversationDescription';
import {
slackApiRequest,
salckApiRequestAllItems,
} from './GenericFunctions';
import {
IAttachment,
} from './MessageInterface';
2019-06-23 03:35:23 -07:00
export class Slack implements INodeType {
description: INodeTypeDescription = {
displayName: 'Slack',
name: 'slack',
icon: 'file:slack.png',
group: ['output'],
version: 1,
2019-07-26 04:13:01 -07:00
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
2019-06-23 03:35:23 -07:00
description: 'Sends data to Slack',
defaults: {
name: 'Slack',
color: '#BB2244',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'slackApi',
required: true,
displayOptions: {
show: {
2020-03-05 15:25:18 -08:00
authentication: [
'accessToken',
],
},
},
},
{
2020-03-05 15:25:18 -08:00
name: 'slackOAuth2Api',
2019-06-23 03:35:23 -07:00
required: true,
displayOptions: {
show: {
2020-03-05 15:25:18 -08:00
authentication: [
'oauth2',
],
2019-06-23 03:35:23 -07:00
},
},
2020-03-05 15:25:18 -08:00
}
],
properties: [
2019-06-23 03:35:23 -07:00
{
2020-03-05 15:25:18 -08:00
displayName: 'Authentication',
name: 'authentication',
type: 'options',
2019-06-23 03:35:23 -07:00
options: [
{
2020-03-05 15:25:18 -08:00
name: 'Access Token',
value: 'accessToken',
2019-06-23 03:35:23 -07:00
},
{
2020-03-05 15:25:18 -08:00
name: 'OAuth2',
value: 'oauth2',
2019-06-23 03:35:23 -07:00
},
],
2020-03-05 15:25:18 -08:00
default: 'accessToken',
description: 'The resource to operate on.',
2019-06-23 03:35:23 -07:00
},
{
2020-03-05 15:25:18 -08:00
displayName: 'Resource',
name: 'resource',
type: 'options',
2019-06-23 03:35:23 -07:00
options: [
{
2020-03-05 15:25:18 -08:00
name: 'Channel',
value: 'channel',
2019-06-23 03:35:23 -07:00
},
{
2020-03-05 15:25:18 -08:00
name: 'Message',
value: 'message',
2019-06-23 03:35:23 -07:00
},
],
2020-03-05 15:25:18 -08:00
default: 'message',
description: 'The resource to operate on.',
2019-06-23 03:35:23 -07:00
},
2020-03-05 15:25:18 -08:00
...channelOperations,
...channelFields,
...messageOperations,
...messageFields,
2019-06-23 03:35:23 -07:00
],
};
2020-03-05 15:25:18 -08:00
methods = {
loadOptions: {
// Get all the users to display them to user so that he can
// select them easily
async getUsers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const users = await salckApiRequestAllItems.call(this, 'members', 'GET', '/users.list');
for (const user of users) {
const userName = user.name;
const userId = user.id;
returnData.push({
name: userName,
value: userId,
});
}
console.log(users)
return returnData;
},
}
};
2019-06-23 03:35:23 -07:00
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: IDataObject[] = [];
2020-03-05 15:25:18 -08:00
const length = items.length as unknown as number;
2019-06-23 03:35:23 -07:00
let qs: IDataObject;
2020-03-05 15:25:18 -08:00
let responseData;
for (let i = 0; i < length; i++) {
2019-06-23 03:35:23 -07:00
qs = {};
2020-03-05 15:25:18 -08:00
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
if (resource === 'channel') {
2020-03-05 15:25:18 -08:00
//https://api.slack.com/methods/conversations.create
if (operation === 'create') {
2020-03-05 15:25:18 -08:00
const channel = this.getNodeParameter('channel', i) as string;
const body: IDataObject = {
name: channel,
};
responseData = await slackApiRequest.call(this, 'POST', '/channels.create', body, qs);
}
if (operation === 'invite') {
const channel = this.getNodeParameter('channel', i) as string;
const user = this.getNodeParameter('username', i) as string;
const body: IDataObject = {
channel,
user,
};
responseData = await slackApiRequest.call(this, 'POST', '/channels.invite', body, qs);
2019-06-23 03:35:23 -07:00
}
2020-03-05 15:25:18 -08:00
}
if (resource === 'message') {
if (operation === 'post') {
2020-03-05 15:25:18 -08:00
const channel = this.getNodeParameter('channel', i) as string;
const text = this.getNodeParameter('text', i) as string;
const attachments = this.getNodeParameter('attachments', i, []) as unknown as IAttachment[];
const as_user = this.getNodeParameter('as_user', i) as boolean;
const body: IDataObject = {
channel: channel,
text,
as_user,
};
if (as_user === false) {
body.username = this.getNodeParameter('username', i) as string;
2019-06-23 03:35:23 -07:00
}
// The node does save the fields data differently than the API
// expects so fix the data befre we send the request
for (const attachment of attachments) {
if (attachment.fields !== undefined) {
if (attachment.fields.item !== undefined) {
// Move the field-content up
// @ts-ignore
attachment.fields = attachment.fields.item;
} else {
// If it does not have any items set remove it
delete attachment.fields;
}
}
}
body['attachments'] = attachments;
2019-06-23 03:35:23 -07:00
// Add all the other options to the request
const otherOptions = this.getNodeParameter('otherOptions', i) as IDataObject;
Object.assign(body, otherOptions);
2020-03-05 15:25:18 -08:00
responseData = await slackApiRequest.call(this, 'POST', '/chat.postMessage', body, qs);
}
2019-06-23 03:35:23 -07:00
}
2020-03-05 15:25:18 -08:00
if (Array.isArray(responseData)) {
returnData.push.apply(returnData, responseData as IDataObject[]);
} else {
returnData.push(responseData as IDataObject);
2019-06-23 03:35:23 -07:00
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}