diff --git a/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts b/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts
index cdca307de5..050bdfb641 100644
--- a/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts
+++ b/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts
@@ -8,13 +8,15 @@ const userScopes = [
'chat:write',
'files:read',
'files:write',
+ 'groups:read',
+ 'im:read',
+ 'mpim:read',
+ 'reactions:read',
+ 'reactions:write',
'stars:read',
'stars:write',
'users.profile:read',
'users.profile:write',
- 'groups:read',
- 'im:read',
- 'mpim:read',
];
export class SlackOAuth2Api implements ICredentialType {
diff --git a/packages/nodes-base/nodes/Slack/ChannelDescription.ts b/packages/nodes-base/nodes/Slack/ChannelDescription.ts
index 52437134e7..2dbf1059e8 100644
--- a/packages/nodes-base/nodes/Slack/ChannelDescription.ts
+++ b/packages/nodes-base/nodes/Slack/ChannelDescription.ts
@@ -1,4 +1,6 @@
-import { INodeProperties } from 'n8n-workflow';
+import {
+ INodeProperties,
+} from 'n8n-workflow';
export const channelOperations = [
{
@@ -63,6 +65,11 @@ export const channelOperations = [
value: 'leave',
description: 'Leaves a conversation.',
},
+ {
+ name: 'Member',
+ value: 'member',
+ description: 'List members of a conversation.',
+ },
{
name: 'Open',
value: 'open',
@@ -101,9 +108,9 @@ export const channelOperations = [
export const channelFields = [
-/* -------------------------------------------------------------------------- */
-/* channel:archive */
-/* -------------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------------- */
+ /* channel:archive */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -125,9 +132,10 @@ export const channelFields = [
required: true,
description: 'The name of the channel to archive.',
},
-/* -------------------------------------------------------------------------- */
-/* channel:close */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:close */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -149,9 +157,10 @@ export const channelFields = [
required: true,
description: 'The name of the channel to close.',
},
-/* -------------------------------------------------------------------------- */
-/* channel:create */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:create */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -197,9 +206,10 @@ export const channelFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* channel:invite */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:invite */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -242,9 +252,10 @@ export const channelFields = [
required: true,
description: 'The ID of the user to invite into channel.',
},
-/* -------------------------------------------------------------------------- */
-/* channel:get */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:get */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -288,9 +299,10 @@ export const channelFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* channel:kick */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:kick */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -332,9 +344,10 @@ export const channelFields = [
},
default: '',
},
-/* -------------------------------------------------------------------------- */
-/* channel:join */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:join */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -356,9 +369,10 @@ export const channelFields = [
},
required: true,
},
-/* -------------------------------------------------------------------------- */
-/* channel:getAll */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:getAll */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
@@ -451,9 +465,10 @@ export const channelFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* channel:history */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:history */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -557,9 +572,10 @@ export const channelFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* channel:leave */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:leave */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -581,9 +597,89 @@ export const channelFields = [
required: true,
description: 'The name of the channel to leave.',
},
-/* -------------------------------------------------------------------------- */
-/* channel:open */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:member */
+ /* -------------------------------------------------------------------------- */
+ {
+ displayName: 'Channel',
+ name: 'channelId',
+ type: 'options',
+ typeOptions: {
+ loadOptionsMethod: 'getChannels',
+ },
+ default: '',
+ displayOptions: {
+ show: {
+ operation: [
+ 'member',
+ ],
+ resource: [
+ 'channel',
+ ],
+ },
+ },
+ required: true,
+ },
+ {
+ displayName: 'Return All',
+ name: 'returnAll',
+ type: 'boolean',
+ displayOptions: {
+ show: {
+ resource: [
+ 'channel',
+ ],
+ operation: [
+ 'member',
+ ],
+ },
+ },
+ default: false,
+ description: 'If all results should be returned or only up to a given limit.',
+ },
+ {
+ displayName: 'Limit',
+ name: 'limit',
+ type: 'number',
+ default: 100,
+ placeholder: 'Limit',
+ displayOptions: {
+ show: {
+ operation: [
+ 'member',
+ ],
+ resource: [
+ 'channel',
+ ],
+ returnAll: [
+ false,
+ ],
+ },
+ },
+ required: false,
+ },
+ {
+ displayName: 'Resolve Data',
+ name: 'resolveData',
+ type: 'boolean',
+ default: false,
+ displayOptions: {
+ show: {
+ resource: [
+ 'channel',
+ ],
+ operation: [
+ 'member',
+ ],
+ },
+ },
+ description: 'By default the response only contain the ID to resource. If this
option gets activated it will resolve the data automatically.',
+ },
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:open */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Options',
name: 'options',
@@ -627,9 +723,10 @@ export const channelFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* channel:rename */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:rename */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -669,9 +766,10 @@ export const channelFields = [
required: true,
description: 'New name for conversation.',
},
-/* -------------------------------------------------------------------------- */
-/* channel:replies */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:replies */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -793,9 +891,10 @@ export const channelFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* channel:setPurpose */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:setPurpose */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -835,9 +934,10 @@ export const channelFields = [
required: true,
description: 'A new, specialer purpose',
},
-/* -------------------------------------------------------------------------- */
-/* channel:setTopic */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:setTopic */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
@@ -877,9 +977,10 @@ export const channelFields = [
required: true,
description: 'The new topic string. Does not support formatting or linkification.',
},
-/* -------------------------------------------------------------------------- */
-/* channel:unarchive */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* channel:unarchive */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
diff --git a/packages/nodes-base/nodes/Slack/FileDescription.ts b/packages/nodes-base/nodes/Slack/FileDescription.ts
index 1b78fc294b..e33b9e356e 100644
--- a/packages/nodes-base/nodes/Slack/FileDescription.ts
+++ b/packages/nodes-base/nodes/Slack/FileDescription.ts
@@ -36,9 +36,9 @@ export const fileOperations = [
export const fileFields = [
-/* -------------------------------------------------------------------------- */
-/* file:upload */
-/* -------------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------------- */
+ /* file:upload */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Binary Data',
name: 'binaryData',
@@ -159,9 +159,10 @@ export const fileFields = [
},
],
},
-/* ----------------------------------------------------------------------- */
-/* file:getAll */
-/* ----------------------------------------------------------------------- */
+
+ /* ----------------------------------------------------------------------- */
+ /* file:getAll */
+ /* ----------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
@@ -261,29 +262,29 @@ export const fileFields = [
value: 'all',
},
{
- name: 'Spaces',
- value: 'spaces',
- },
- {
- name: 'Snippets',
- value: 'snippets',
+ name: 'Google Docs',
+ value: 'gdocs',
},
{
name: 'Images',
value: 'images',
},
{
- name: 'Google Docs',
- value: 'gdocs',
+ name: 'Snippets',
+ value: 'snippets',
},
{
- name: 'Zips',
- value: 'zips',
+ name: 'Spaces',
+ value: 'spaces',
},
{
name: 'pdfs',
value: 'pdfs',
},
+ {
+ name: 'Zips',
+ value: 'zips',
+ },
],
default: ['all'],
description: 'Filter files by type',
@@ -300,9 +301,10 @@ export const fileFields = [
},
],
},
-/* ----------------------------------------------------------------------- */
-/* file:get */
-/* ----------------------------------------------------------------------- */
+
+ /* ----------------------------------------------------------------------- */
+ /* file:get */
+ /* ----------------------------------------------------------------------- */
{
displayName: 'File ID',
name: 'fileId',
diff --git a/packages/nodes-base/nodes/Slack/GenericFunctions.ts b/packages/nodes-base/nodes/Slack/GenericFunctions.ts
index e31a505892..43cc376b5c 100644
--- a/packages/nodes-base/nodes/Slack/GenericFunctions.ts
+++ b/packages/nodes-base/nodes/Slack/GenericFunctions.ts
@@ -76,7 +76,7 @@ export async function slackApiRequest(this: IExecuteFunctions | IExecuteSingleFu
}
}
-export async function slackApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string ,method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any
+export async function slackApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, propertyName: string, method: string, endpoint: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any
const returnData: IDataObject[] = [];
let responseData;
query.page = 1;
@@ -88,13 +88,13 @@ export async function slackApiRequestAllItems(this: IExecuteFunctions | ILoadOpt
returnData.push.apply(returnData, responseData[propertyName]);
} while (
(responseData.response_metadata !== undefined &&
- responseData.response_metadata.mext_cursor !== undefined &&
- responseData.response_metadata.next_cursor !== '' &&
- responseData.response_metadata.next_cursor !== null) ||
+ responseData.response_metadata.mext_cursor !== undefined &&
+ responseData.response_metadata.next_cursor !== '' &&
+ responseData.response_metadata.next_cursor !== null) ||
(responseData.paging !== undefined &&
- responseData.paging.pages !== undefined &&
- responseData.paging.page !== undefined &&
- responseData.paging.page < responseData.paging.pages
+ responseData.paging.pages !== undefined &&
+ responseData.paging.page !== undefined &&
+ responseData.paging.page < responseData.paging.pages
)
);
diff --git a/packages/nodes-base/nodes/Slack/MessageDescription.ts b/packages/nodes-base/nodes/Slack/MessageDescription.ts
index ad5ac67f1b..9953441afe 100644
--- a/packages/nodes-base/nodes/Slack/MessageDescription.ts
+++ b/packages/nodes-base/nodes/Slack/MessageDescription.ts
@@ -31,9 +31,9 @@ export const messageOperations = [
export const messageFields = [
-/* -------------------------------------------------------------------------- */
-/* message:post */
-/* -------------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------------- */
+ /* message:post */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channel',
@@ -382,6 +382,13 @@ export const messageFields = [
default: '',
description: 'URL to an image to use as the icon for this message.',
},
+ {
+ displayName: 'Link Names',
+ name: 'link_names',
+ type: 'boolean',
+ default: false,
+ description: 'Find and link channel names and usernames.',
+ },
{
displayName: 'Make Reply',
name: 'thread_ts',
@@ -389,20 +396,6 @@ export const messageFields = [
default: '',
description: 'Provide another message\'s ts value to make this message a reply.',
},
- {
- displayName: 'Unfurl Links',
- name: 'unfurl_links',
- type: 'boolean',
- default: false,
- description: 'Pass true to enable unfurling of primarily text-based content.',
- },
- {
- displayName: 'Unfurl Media',
- name: 'unfurl_media',
- type: 'boolean',
- default: true,
- description: 'Pass false to disable unfurling of media content.',
- },
{
displayName: 'Markdown',
name: 'mrkdwn',
@@ -418,17 +411,25 @@ export const messageFields = [
description: 'Used in conjunction with thread_ts and indicates whether reply should be made visible to everyone in the channel or conversation.',
},
{
- displayName: 'Link Names',
- name: 'link_names',
+ displayName: 'Unfurl Links',
+ name: 'unfurl_links',
type: 'boolean',
default: false,
- description: 'Find and link channel names and usernames.',
+ description: 'Pass true to enable unfurling of primarily text-based content.',
+ },
+ {
+ displayName: 'Unfurl Media',
+ name: 'unfurl_media',
+ type: 'boolean',
+ default: true,
+ description: 'Pass false to disable unfurling of media content.',
},
],
},
-/* ----------------------------------------------------------------------- */
-/* message:update */
-/* ----------------------------------------------------------------------- */
+
+ /* ----------------------------------------------------------------------- */
+ /* message:update */
+ /* ----------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
diff --git a/packages/nodes-base/nodes/Slack/MessageInterface.ts b/packages/nodes-base/nodes/Slack/MessageInterface.ts
index caff7c0765..463c2fa636 100644
--- a/packages/nodes-base/nodes/Slack/MessageInterface.ts
+++ b/packages/nodes-base/nodes/Slack/MessageInterface.ts
@@ -4,4 +4,3 @@ export interface IAttachment {
item?: object[];
};
}
-
diff --git a/packages/nodes-base/nodes/Slack/ReactionDescription.ts b/packages/nodes-base/nodes/Slack/ReactionDescription.ts
new file mode 100644
index 0000000000..0e41dc9282
--- /dev/null
+++ b/packages/nodes-base/nodes/Slack/ReactionDescription.ts
@@ -0,0 +1,101 @@
+import { INodeProperties } from 'n8n-workflow';
+
+export const reactionOperations = [
+ {
+ displayName: 'Operation',
+ name: 'operation',
+ type: 'options',
+ displayOptions: {
+ show: {
+ resource: [
+ 'reaction',
+ ],
+ },
+ },
+ options: [
+ {
+ name: 'Add',
+ value: 'add',
+ description: 'Adds a reaction to a message',
+ },
+ {
+ name: 'Get',
+ value: 'get',
+ description: 'Get the reactions of a message',
+ },
+ {
+ name: 'Remove',
+ value: 'remove',
+ description: 'Remove a reaction of a message',
+ },
+ ],
+ default: 'add',
+ description: 'The operation to perform.',
+ },
+] as INodeProperties[];
+
+export const reactionFields = [
+ {
+ displayName: 'Channel',
+ name: 'channelId',
+ type: 'options',
+ typeOptions: {
+ loadOptionsMethod: 'getChannels',
+ },
+ required: true,
+ default: '',
+ displayOptions: {
+ show: {
+ resource: [
+ 'reaction',
+ ],
+ operation: [
+ 'add',
+ 'get',
+ 'remove',
+ ],
+ },
+ },
+ description: 'Channel containing the message.',
+ },
+ {
+ displayName: 'Emoji',
+ name: 'name',
+ type: 'string',
+ required: true,
+ default: '',
+ displayOptions: {
+ show: {
+ resource: [
+ 'reaction',
+ ],
+ operation: [
+ 'add',
+ 'remove',
+ ],
+ },
+ },
+ description: 'Name of emoji.',
+ placeholder: '+1',
+ },
+ {
+ displayName: 'Timestamp',
+ name: 'timestamp',
+ type: 'string',
+ required: true,
+ default: '',
+ displayOptions: {
+ show: {
+ resource: [
+ 'reaction',
+ ],
+ operation: [
+ 'add',
+ 'get',
+ 'remove',
+ ],
+ },
+ },
+ description: `Timestamp of the message.`,
+ },
+] as INodeProperties[];
diff --git a/packages/nodes-base/nodes/Slack/Slack.node.ts b/packages/nodes-base/nodes/Slack/Slack.node.ts
index 24553d7f79..096b479192 100644
--- a/packages/nodes-base/nodes/Slack/Slack.node.ts
+++ b/packages/nodes-base/nodes/Slack/Slack.node.ts
@@ -32,6 +32,16 @@ import {
fileOperations,
} from './FileDescription';
+import {
+ reactionFields,
+ reactionOperations,
+} from './ReactionDescription';
+
+import {
+ userFields,
+ userOperations,
+} from './UserDescription';
+
import {
userProfileFields,
userProfileOperations,
@@ -46,6 +56,7 @@ import {
import {
IAttachment,
} from './MessageInterface';
+
import moment = require('moment');
interface Attachment {
@@ -163,10 +174,18 @@ export class Slack implements INodeType {
name: 'Message',
value: 'message',
},
+ {
+ name: 'Reaction',
+ value: 'reaction',
+ },
{
name: 'Star',
value: 'star',
},
+ {
+ name: 'User',
+ value: 'user',
+ },
{
name: 'User Profile',
value: 'userProfile',
@@ -184,6 +203,10 @@ export class Slack implements INodeType {
...starFields,
...fileOperations,
...fileFields,
+ ...reactionOperations,
+ ...reactionFields,
+ ...userOperations,
+ ...userFields,
...userProfileOperations,
...userProfileFields,
],
@@ -217,7 +240,7 @@ export class Slack implements INodeType {
// select them easily
async getChannels(this: ILoadOptionsFunctions): Promise {
const returnData: INodePropertyOptions[] = [];
- const qs = { types: 'public_channel,private_channel' };
+ const qs = { types: 'public_channel,private_channel', limit: 1000 };
const channels = await slackApiRequestAllItems.call(this, 'channels', 'GET', '/conversations.list', {}, qs);
for (const channel of channels) {
const channelName = channel.name;
@@ -265,7 +288,7 @@ export class Slack implements INodeType {
const operation = this.getNodeParameter('operation', 0) as string;
for (let i = 0; i < length; i++) {
- responseData = { error: 'Resource ' + resource + ' / operation ' + operation + ' not found!'};
+ responseData = { error: 'Resource ' + resource + ' / operation ' + operation + ' not found!' };
qs = {};
if (resource === 'channel') {
//https://api.slack.com/methods/conversations.archive
@@ -383,6 +406,29 @@ export class Slack implements INodeType {
};
responseData = await slackApiRequest.call(this, 'POST', '/conversations.leave', body, qs);
}
+ //https://api.slack.com/methods/conversations.members
+ if (operation === 'member') {
+ const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
+ const resolveData = this.getNodeParameter('resolveData', 0) as boolean;
+ qs.channel = this.getNodeParameter('channelId', i) as string;
+ if (returnAll) {
+ responseData = await slackApiRequestAllItems.call(this, 'members', 'GET', '/conversations.members', {}, qs);
+ responseData = responseData.map((member: string) => ({ member }));
+ } else {
+ qs.limit = this.getNodeParameter('limit', i) as number;
+ responseData = await slackApiRequest.call(this, 'GET', '/conversations.members', {}, qs);
+ responseData = responseData.members.map((member: string) => ({ member }));
+ }
+
+ if (resolveData) {
+ const data: IDataObject[] = [];
+ for (const { member } of responseData) {
+ const { user } = await slackApiRequest.call(this, 'GET', '/users.info', {}, { user: member });
+ data.push(user);
+ }
+ responseData = data;
+ }
+ }
//https://api.slack.com/methods/conversations.open
if (operation === 'open') {
const options = this.getNodeParameter('options', i) as IDataObject;
@@ -745,6 +791,36 @@ export class Slack implements INodeType {
responseData = await slackApiRequest.call(this, 'POST', '/chat.update', body, qs);
}
}
+ if (resource === 'reaction') {
+ const channel = this.getNodeParameter('channelId', i) as string;
+ const timestamp = this.getNodeParameter('timestamp', i) as string;
+ //https://api.slack.com/methods/reactions.add
+ if (operation === 'add') {
+ const name = this.getNodeParameter('name', i) as string;
+ const body: IDataObject = {
+ channel,
+ name,
+ timestamp,
+ };
+ responseData = await slackApiRequest.call(this, 'POST', '/reactions.add', body, qs);
+ }
+ //https://api.slack.com/methods/reactions.remove
+ if (operation === 'remove') {
+ const name = this.getNodeParameter('name', i) as string;
+ const body: IDataObject = {
+ channel,
+ name,
+ timestamp,
+ };
+ responseData = await slackApiRequest.call(this, 'POST', '/reactions.remove', body, qs);
+ }
+ //https://api.slack.com/methods/reactions.get
+ if (operation === 'get') {
+ qs.channel = channel;
+ qs.timestamp = timestamp;
+ responseData = await slackApiRequest.call(this, 'GET', '/reactions.get', {}, qs);
+ }
+ }
if (resource === 'star') {
//https://api.slack.com/methods/stars.add
if (operation === 'add') {
@@ -879,6 +955,19 @@ export class Slack implements INodeType {
responseData = responseData.file;
}
}
+ if (resource === 'user') {
+ //https://api.slack.com/methods/users.info
+ if (operation === 'info') {
+ qs.user = this.getNodeParameter('user', i) as string;
+ responseData = await slackApiRequest.call(this, 'GET', '/users.info', {}, qs);
+ responseData = responseData.user;
+ }
+ //https://api.slack.com/methods/users.getPresence
+ if (operation === 'getPresence') {
+ qs.user = this.getNodeParameter('user', i) as string;
+ responseData = await slackApiRequest.call(this, 'GET', '/users.getPresence', {}, qs);
+ }
+ }
if (resource === 'userProfile') {
//https://api.slack.com/methods/users.profile.set
if (operation === 'update') {
diff --git a/packages/nodes-base/nodes/Slack/StarDescription.ts b/packages/nodes-base/nodes/Slack/StarDescription.ts
index 0f77db7596..66d95c127c 100644
--- a/packages/nodes-base/nodes/Slack/StarDescription.ts
+++ b/packages/nodes-base/nodes/Slack/StarDescription.ts
@@ -36,9 +36,9 @@ export const starOperations = [
export const starFields = [
-/* -------------------------------------------------------------------------- */
-/* star:add */
-/* -------------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------------- */
+ /* star:add */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Options',
name: 'options',
@@ -67,13 +67,6 @@ export const starFields = [
default: '',
description: 'Channel to add star to, or channel where the message to add star to was posted (used with timestamp).',
},
- {
- displayName: 'File ID',
- name: 'fileId',
- type: 'string',
- default: '',
- description: 'File to add star to.',
- },
{
displayName: 'File Comment',
name: 'fileComment',
@@ -81,6 +74,13 @@ export const starFields = [
default: '',
description: 'File comment to add star to.',
},
+ {
+ displayName: 'File ID',
+ name: 'fileId',
+ type: 'string',
+ default: '',
+ description: 'File to add star to.',
+ },
{
displayName: 'Timestamp',
name: 'timestamp',
@@ -90,9 +90,10 @@ export const starFields = [
},
],
},
-/* ----------------------------------------------------------------------- */
-/* star:delete */
-/* ----------------------------------------------------------------------- */
+
+ /* ----------------------------------------------------------------------- */
+ /* star:delete */
+ /* ----------------------------------------------------------------------- */
{
displayName: 'Options',
name: 'options',
@@ -144,9 +145,10 @@ export const starFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* star:getAll */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* star:getAll */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
diff --git a/packages/nodes-base/nodes/Slack/UserDescription.ts b/packages/nodes-base/nodes/Slack/UserDescription.ts
new file mode 100644
index 0000000000..7505a3b8d7
--- /dev/null
+++ b/packages/nodes-base/nodes/Slack/UserDescription.ts
@@ -0,0 +1,85 @@
+import {
+ INodeProperties,
+} from 'n8n-workflow';
+
+export const userOperations = [
+ {
+ displayName: 'Operation',
+ name: 'operation',
+ type: 'options',
+ displayOptions: {
+ show: {
+ resource: [
+ 'user',
+ ],
+ },
+ },
+ options: [
+ {
+ name: 'Info',
+ value: 'info',
+ description: `Get information about a user`,
+ },
+ {
+ name: 'Get Presence',
+ value: 'getPresence',
+ description: `Get online status of a user`,
+ },
+ ],
+ default: 'info',
+ description: 'The operation to perform.',
+ },
+] as INodeProperties[];
+
+export const userFields = [
+
+ /* -------------------------------------------------------------------------- */
+ /* user:info */
+ /* -------------------------------------------------------------------------- */
+ {
+ displayName: 'User ID',
+ name: 'user',
+ type: 'string',
+ typeOptions: {
+ loadOptionsMethod: 'getUsers',
+ },
+ default: '',
+ displayOptions: {
+ show: {
+ operation: [
+ 'info',
+ ],
+ resource: [
+ 'user',
+ ],
+ },
+ },
+ required: true,
+ description: 'The ID of the user to get information about.',
+ },
+
+ /* -------------------------------------------------------------------------- */
+ /* user:getPresence */
+ /* -------------------------------------------------------------------------- */
+ {
+ displayName: 'User ID',
+ name: 'user',
+ type: 'string',
+ typeOptions: {
+ loadOptionsMethod: 'getUsers',
+ },
+ default: '',
+ displayOptions: {
+ show: {
+ operation: [
+ 'getPresence',
+ ],
+ resource: [
+ 'user',
+ ],
+ },
+ },
+ required: true,
+ description: 'The ID of the user to get the online status of.',
+ },
+] as INodeProperties[];
diff --git a/packages/nodes-base/nodes/Slack/UserProfileDescription.ts b/packages/nodes-base/nodes/Slack/UserProfileDescription.ts
index a3475ee993..9bf9d103ef 100644
--- a/packages/nodes-base/nodes/Slack/UserProfileDescription.ts
+++ b/packages/nodes-base/nodes/Slack/UserProfileDescription.ts
@@ -34,9 +34,9 @@ export const userProfileOperations = [
export const userProfileFields = [
-/* -------------------------------------------------------------------------- */
-/* userProfile:update */
-/* -------------------------------------------------------------------------- */
+ /* -------------------------------------------------------------------------- */
+ /* userProfile:update */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Additional Fields',
name: 'additionalFields',
@@ -144,9 +144,10 @@ export const userProfileFields = [
},
],
},
-/* -------------------------------------------------------------------------- */
-/* userProfile:get */
-/* -------------------------------------------------------------------------- */
+
+ /* -------------------------------------------------------------------------- */
+ /* userProfile:get */
+ /* -------------------------------------------------------------------------- */
{
displayName: 'Additional Fields',
name: 'additionalFields',