first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,893 @@
import type { INodeProperties } from 'n8n-workflow';
export const channelOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['channel'],
},
},
options: [
{
name: 'Archive',
value: 'archive',
description: 'Archives a conversation',
action: 'Archive a channel',
},
{
name: 'Close',
value: 'close',
description: 'Closes a direct message or multi-person direct message',
action: 'Close a channel',
},
{
name: 'Create',
value: 'create',
description: 'Initiates a public or private channel-based conversation',
action: 'Create a channel',
},
{
name: 'Get',
value: 'get',
description: 'Get information about a channel',
action: 'Get a channel',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many channels in a Slack team',
action: 'Get many channels',
},
{
name: 'History',
value: 'history',
description: "Get a conversation's history of messages and events",
action: 'Get the history of a channel',
},
{
name: 'Invite',
value: 'invite',
description: 'Invite a user to a channel',
action: 'Invite a user to a channel',
},
{
name: 'Join',
value: 'join',
description: 'Joins an existing conversation',
action: 'Join a channel',
},
{
name: 'Kick',
value: 'kick',
description: 'Removes a user from a channel',
action: 'Kick a user from a channel',
},
{
name: 'Leave',
value: 'leave',
description: 'Leaves a conversation',
action: 'Leave a channel',
},
{
name: 'Member',
value: 'member',
description: 'List members of a conversation',
action: 'Get members of a channel',
},
{
name: 'Open',
value: 'open',
description: 'Opens or resumes a direct message or multi-person direct message',
action: 'Open a channel',
},
{
name: 'Rename',
value: 'rename',
description: 'Renames a conversation',
action: 'Rename a channel',
},
{
name: 'Replies',
value: 'replies',
description: 'Get a thread of messages posted to a channel',
action: 'Get a thread of messages posted to a channel',
},
{
name: 'Set Purpose',
value: 'setPurpose',
description: 'Sets the purpose for a conversation',
action: 'Set the purpose of a channel',
},
{
name: 'Set Topic',
value: 'setTopic',
description: 'Sets the topic for a conversation',
action: 'Set the topic of a channel',
},
{
name: 'Unarchive',
value: 'unarchive',
description: 'Unarchives a conversation',
action: 'Unarchive a channel',
},
],
default: 'create',
},
];
export const channelFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* channel:archive */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
displayOptions: {
show: {
operation: ['archive'],
resource: ['channel'],
},
},
default: '',
required: true,
description:
'The name of the channel to archive. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
/* -------------------------------------------------------------------------- */
/* channel:close */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
displayOptions: {
show: {
operation: ['close'],
resource: ['channel'],
},
},
default: '',
required: true,
description:
'The name of the channel to close. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
/* -------------------------------------------------------------------------- */
/* channel:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
type: 'string',
default: '',
placeholder: 'Channel name',
displayOptions: {
show: {
operation: ['create'],
resource: ['channel'],
},
},
required: true,
description: 'The name of the channel to create',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['channel'],
operation: ['create'],
},
},
options: [
{
displayName: 'Is Private',
name: 'isPrivate',
type: 'boolean',
default: false,
description: 'Whether to create a private channel instead of a public one',
},
],
},
/* -------------------------------------------------------------------------- */
/* channel:invite */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: '',
displayOptions: {
show: {
operation: ['invite'],
resource: ['channel'],
},
},
required: true,
description:
'The ID of the channel to invite user to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'User Names or IDs',
name: 'userIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: [],
displayOptions: {
show: {
operation: ['invite'],
resource: ['channel'],
},
},
required: true,
description:
'The ID of the user to invite into channel. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
/* -------------------------------------------------------------------------- */
/* channel:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['get'],
resource: ['channel'],
},
},
required: true,
description: 'Channel ID to learn more about',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['channel'],
operation: ['get'],
},
},
options: [
{
displayName: 'Include Num of Members',
name: 'includeNumMembers',
type: 'boolean',
default: false,
},
],
},
/* -------------------------------------------------------------------------- */
/* channel:kick */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: '',
placeholder: 'Channel name',
displayOptions: {
show: {
operation: ['kick'],
resource: ['channel'],
},
},
required: true,
description:
'The name of the channel to create. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'User Name or ID',
name: 'userId',
type: 'options',
description:
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
displayOptions: {
show: {
operation: ['kick'],
resource: ['channel'],
},
},
default: '',
},
/* -------------------------------------------------------------------------- */
/* channel:join */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
description:
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: '',
placeholder: 'Channel name',
displayOptions: {
show: {
operation: ['join'],
resource: ['channel'],
},
},
required: true,
},
/* -------------------------------------------------------------------------- */
/* channel:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['channel'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['channel'],
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['channel'],
operation: ['getAll'],
},
},
options: [
{
displayName: 'Exclude Archived',
name: 'excludeArchived',
type: 'boolean',
default: false,
description: 'Whether to exclude archived channels from the list',
},
{
displayName: 'Types',
name: 'types',
type: 'multiOptions',
options: [
{
name: 'Public Channel',
value: 'public_channel',
},
{
name: 'Private Channel',
value: 'private_channel',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'mpim',
value: 'mpim',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'im',
value: 'im',
},
],
default: ['public_channel'],
description: 'Mix and match channel types',
},
],
},
/* -------------------------------------------------------------------------- */
/* channel:history */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: '',
placeholder: 'Channel name',
displayOptions: {
show: {
operation: ['history'],
resource: ['channel'],
},
},
required: true,
description:
'The name of the channel to create. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['channel'],
operation: ['history'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['channel'],
operation: ['history'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['channel'],
operation: ['history'],
},
},
options: [
{
displayName: 'Inclusive',
name: 'inclusive',
type: 'boolean',
default: false,
description:
'Whether to include messages with latest or oldest timestamp in results only when either timestamp is specified',
},
{
displayName: 'Latest',
name: 'latest',
type: 'dateTime',
default: '',
description: 'End of time range of messages to include in results',
},
{
displayName: 'Oldest',
name: 'oldest',
type: 'dateTime',
default: '',
description: 'Start of time range of messages to include in results',
},
],
},
/* -------------------------------------------------------------------------- */
/* channel:leave */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
displayOptions: {
show: {
operation: ['leave'],
resource: ['channel'],
},
},
default: '',
required: true,
description:
'The name of the channel to leave. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
/* -------------------------------------------------------------------------- */
/* channel:member */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
description:
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
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: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
typeOptions: {
minValue: 1,
},
description: 'Max number of results to return',
default: 100,
placeholder: 'Limit',
displayOptions: {
show: {
operation: ['member'],
resource: ['channel'],
returnAll: [false],
},
},
},
{
displayName: 'Resolve Data',
name: 'resolveData',
type: 'boolean',
default: false,
displayOptions: {
show: {
resource: ['channel'],
operation: ['member'],
},
},
description:
'Whether to resolve the data automatically. By default the response only contain the ID to resource.',
},
/* -------------------------------------------------------------------------- */
/* channel:open */
/* -------------------------------------------------------------------------- */
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['channel'],
operation: ['open'],
},
},
options: [
{
displayName: 'Channel ID',
name: 'channelId',
type: 'string',
default: '',
description:
"Resume a conversation by supplying an im or mpim's ID. Or provide the users field instead.",
},
{
displayName: 'Return IM',
name: 'returnIm',
type: 'boolean',
default: false,
description: 'Whether you want the full IM channel definition in the response',
},
{
displayName: 'User Names or IDs',
name: 'users',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: [],
description:
'If only one user is included, this creates a 1:1 DM. The ordering of the users is preserved whenever a multi-person direct message is returned. Supply a channel when not supplying users. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
],
},
/* -------------------------------------------------------------------------- */
/* channel:rename */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
displayOptions: {
show: {
operation: ['rename'],
resource: ['channel'],
},
},
default: '',
required: true,
description:
'The name of the channel to rename. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
displayOptions: {
show: {
operation: ['rename'],
resource: ['channel'],
},
},
default: '',
required: true,
description: 'New name for conversation',
},
/* -------------------------------------------------------------------------- */
/* channel:replies */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: '',
placeholder: 'Channel name',
displayOptions: {
show: {
operation: ['replies'],
resource: ['channel'],
},
},
required: true,
description:
'The name of the channel to create. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'TS',
name: 'ts',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['replies'],
resource: ['channel'],
},
},
required: true,
description: "Unique identifier of a thread's parent message",
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['channel'],
operation: ['replies'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['channel'],
operation: ['replies'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['channel'],
operation: ['replies'],
},
},
options: [
{
displayName: 'Inclusive',
name: 'inclusive',
type: 'boolean',
default: false,
description:
'Whether to include messages with latest or oldest timestamp in results only when either timestamp is specified',
},
{
displayName: 'Latest',
name: 'latest',
type: 'string',
default: '',
description: 'End of time range of messages to include in results',
},
{
displayName: 'Oldest',
name: 'oldest',
type: 'string',
default: '',
description: 'Start of time range of messages to include in results',
},
],
},
/* -------------------------------------------------------------------------- */
/* channel:setPurpose */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
displayOptions: {
show: {
operation: ['setPurpose'],
resource: ['channel'],
},
},
default: '',
required: true,
description:
'Conversation to set the purpose of. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Purpose',
name: 'purpose',
type: 'string',
displayOptions: {
show: {
operation: ['setPurpose'],
resource: ['channel'],
},
},
default: '',
required: true,
description: 'A new, specialer purpose',
},
/* -------------------------------------------------------------------------- */
/* channel:setTopic */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
displayOptions: {
show: {
operation: ['setTopic'],
resource: ['channel'],
},
},
default: '',
required: true,
description:
'Conversation to set the topic of. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Topic',
name: 'topic',
type: 'string',
displayOptions: {
show: {
operation: ['setTopic'],
resource: ['channel'],
},
},
default: '',
required: true,
description: 'The new topic string. Does not support formatting or linkification.',
},
/* -------------------------------------------------------------------------- */
/* channel:unarchive */
/* -------------------------------------------------------------------------- */
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
displayOptions: {
show: {
operation: ['unarchive'],
resource: ['channel'],
},
},
default: '',
required: true,
description:
'The ID of the channel to unarchive. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
];
@@ -0,0 +1,290 @@
import type { INodeProperties } from 'n8n-workflow';
export const fileOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['file'],
},
},
options: [
{
name: 'Get',
value: 'get',
description: 'Get a file info',
action: 'Get a file',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get & filters team files',
action: 'Get many files',
},
{
name: 'Upload',
value: 'upload',
description: 'Create or upload an existing file',
action: 'Upload a file',
},
],
default: 'upload',
},
];
export const fileFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* file:upload */
/* -------------------------------------------------------------------------- */
{
displayName: 'Binary File',
name: 'binaryData',
type: 'boolean',
default: false,
displayOptions: {
show: {
operation: ['upload'],
resource: ['file'],
},
},
description: 'Whether the data to upload should be taken from binary field',
},
{
displayName: 'File Content',
name: 'fileContent',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['upload'],
resource: ['file'],
binaryData: [false],
},
},
placeholder: '',
description: 'The text content of the file to upload',
},
{
displayName: 'Input Binary Field',
name: 'binaryPropertyName',
type: 'string',
default: 'data',
required: true,
displayOptions: {
show: {
operation: ['upload'],
resource: ['file'],
binaryData: [true],
},
},
placeholder: '',
hint: 'The name of the input binary field containing the file to be uploaded',
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
displayOptions: {
show: {
operation: ['upload'],
resource: ['file'],
},
},
default: {},
description: 'Other options to set',
placeholder: 'Add option',
options: [
{
displayName: 'Channel Names or IDs',
name: 'channelIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: [],
description:
'The channels to send the file to. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'File Name',
name: 'fileName',
type: 'string',
default: '',
description: 'Filename of file',
},
{
displayName: 'Initial Comment',
name: 'initialComment',
type: 'string',
default: '',
description: 'The message text introducing the file in specified channels',
},
{
displayName: 'Thread TS',
name: 'threadTs',
type: 'string',
default: '',
description:
"Provide another message's ts value to upload this file as a reply. Never use a reply's ts value; use its parent instead.",
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
description: 'Title of file',
},
],
},
/* ----------------------------------------------------------------------- */
/* file:getAll */
/* ----------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['file'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['file'],
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'Max number of results to return',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['file'],
},
},
default: {},
placeholder: 'Add Field',
options: [
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
default: '',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
description:
'Channel containing the file to be listed. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Show Files Hidden By Limit',
name: 'showFilesHidden',
type: 'boolean',
default: false,
description:
'Whether to show truncated file info for files hidden due to being too old, and the team who owns the file being over the file limit',
},
{
displayName: 'Timestamp From',
name: 'tsFrom',
type: 'string',
default: '',
description: 'Filter files created after this timestamp (inclusive)',
},
{
displayName: 'Timestamp To',
name: 'tsTo',
type: 'string',
default: '',
description: 'Filter files created before this timestamp (inclusive)',
},
{
displayName: 'Types',
name: 'types',
type: 'multiOptions',
options: [
{
name: 'All',
value: 'all',
},
{
name: 'Google Docs',
value: 'gdocs',
},
{
name: 'Images',
value: 'images',
},
{
name: 'PDFs',
value: 'pdfs',
},
{
name: 'Snippets',
value: 'snippets',
},
{
name: 'Spaces',
value: 'spaces',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'zips',
value: 'zips',
},
],
default: ['all'],
description: 'Filter files by type',
},
{
displayName: 'User Name or ID',
name: 'userId',
type: 'options',
default: '',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
description:
'Filter files created by a single user. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
],
},
/* ----------------------------------------------------------------------- */
/* file:get */
/* ----------------------------------------------------------------------- */
{
displayName: 'File ID',
name: 'fileId',
type: 'string',
displayOptions: {
show: {
resource: ['file'],
operation: ['get'],
},
},
default: '',
},
];
@@ -0,0 +1,128 @@
import get from 'lodash/get';
import type {
IExecuteFunctions,
ILoadOptionsFunctions,
IDataObject,
IOAuth2Options,
JsonObject,
IHttpRequestMethods,
IRequestOptions,
} from 'n8n-workflow';
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
export async function slackApiRequest(
this: IExecuteFunctions | ILoadOptionsFunctions,
method: IHttpRequestMethods,
resource: string,
body: object = {},
query: IDataObject = {},
headers: IDataObject | undefined = undefined,
option: IDataObject = {},
): Promise<any> {
const authenticationMethod = this.getNodeParameter('authentication', 0, 'accessToken') as string;
let options: IRequestOptions = {
method,
headers: headers || {
'Content-Type': 'application/json; charset=utf-8',
},
body,
qs: query,
uri: `https://slack.com/api${resource}`,
json: true,
};
options = Object.assign({}, options, option);
if (Object.keys(body).length === 0) {
delete options.body;
}
if (Object.keys(query).length === 0) {
delete options.qs;
}
const oAuth2Options: IOAuth2Options = {
tokenType: 'Bearer',
property: 'authed_user.access_token',
};
try {
const credentialType = authenticationMethod === 'accessToken' ? 'slackApi' : 'slackOAuth2Api';
const response = await this.helpers.requestWithAuthentication.call(
this,
credentialType,
options,
{
oauth2: oAuth2Options,
},
);
if (response.ok === false) {
if (response.error === 'paid_teams_only') {
throw new NodeOperationError(
this.getNode(),
`Your current Slack plan does not include the resource '${this.getNodeParameter(
'resource',
0,
)}'`,
{
description:
'Hint: Upgrate to the Slack plan that includes the funcionality you want to use.',
},
);
}
throw new NodeOperationError(
this.getNode(),
'Slack error response: ' + JSON.stringify(response),
);
}
return response;
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
}
}
export async function slackApiRequestAllItems(
this: IExecuteFunctions | ILoadOptionsFunctions,
propertyName: string,
method: IHttpRequestMethods,
endpoint: string,
body: any = {},
query: IDataObject = {},
): Promise<any> {
const returnData: IDataObject[] = [];
let responseData;
query.page = 1;
//if the endpoint uses legacy pagination use count
//https://api.slack.com/docs/pagination#classic
if (endpoint.includes('files.list')) {
query.count = 100;
} else {
query.limit = 100;
}
do {
responseData = await slackApiRequest.call(this, method, endpoint, body as IDataObject, query);
query.cursor = get(responseData, 'response_metadata.next_cursor');
query.page++;
returnData.push.apply(returnData, responseData[propertyName] as IDataObject[]);
} while (
(responseData.response_metadata?.next_cursor !== undefined &&
responseData.response_metadata.next_cursor !== '' &&
responseData.response_metadata.next_cursor !== null) ||
(responseData.paging?.pages !== undefined &&
responseData.paging.page !== undefined &&
responseData.paging.page < responseData.paging.pages)
);
return returnData;
}
export function validateJSON(json: string | undefined): any {
let result;
try {
result = JSON.parse(json!);
} catch (exception) {
result = undefined;
}
return result;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
export interface IAttachment {
fields: {
item?: object[];
};
}
@@ -0,0 +1,86 @@
import type { INodeProperties } from 'n8n-workflow';
export const reactionOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['reaction'],
},
},
options: [
{
name: 'Add',
value: 'add',
description: 'Adds a reaction to a message',
action: 'Add a reaction',
},
{
name: 'Get',
value: 'get',
description: 'Get the reactions of a message',
action: 'Get a reaction',
},
{
name: 'Remove',
value: 'remove',
description: 'Remove a reaction of a message',
action: 'Remove a reaction',
},
],
default: 'add',
},
];
export const reactionFields: INodeProperties[] = [
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
required: true,
default: '',
displayOptions: {
show: {
resource: ['reaction'],
operation: ['add', 'get', 'remove'],
},
},
description:
'Channel containing the message. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
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',
},
];
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,177 @@
import type { INodeProperties } from 'n8n-workflow';
export const starOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['star'],
},
},
options: [
{
name: 'Add',
value: 'add',
description: 'Add a star to an item',
action: 'Add a star',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a star from an item',
action: 'Delete a star',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many stars of autenticated user',
action: 'Get many stars',
},
],
default: 'add',
},
];
export const starFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* star:add */
/* -------------------------------------------------------------------------- */
{
displayName: 'Options',
name: 'options',
type: 'collection',
displayOptions: {
show: {
operation: ['add'],
resource: ['star'],
},
},
default: {},
description: 'Options to set',
placeholder: 'Add option',
options: [
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: '',
description:
'Channel to add star to, or channel where the message to add star to was posted (used with timestamp). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'File Comment',
name: 'fileComment',
type: 'string',
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',
type: 'string',
default: '',
description: 'Timestamp of the message to add star to',
},
],
},
/* ----------------------------------------------------------------------- */
/* star:delete */
/* ----------------------------------------------------------------------- */
{
displayName: 'Options',
name: 'options',
type: 'collection',
displayOptions: {
show: {
operation: ['delete'],
resource: ['star'],
},
},
default: {},
description: 'Options to set',
placeholder: 'Add option',
options: [
{
displayName: 'Channel Name or ID',
name: 'channelId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: '',
description:
'Channel to add star to, or channel where the message to add star to was posted (used with timestamp). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'File ID',
name: 'fileId',
type: 'string',
default: '',
description: 'File to add star to',
},
{
displayName: 'File Comment',
name: 'fileComment',
type: 'string',
default: '',
description: 'File comment to add star to',
},
{
displayName: 'Timestamp',
name: 'timestamp',
type: 'string',
default: '',
description: 'Timestamp of the message to add star to',
},
],
},
/* -------------------------------------------------------------------------- */
/* star:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['star'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['star'],
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'Max number of results to return',
},
];
@@ -0,0 +1,114 @@
import type { INodeProperties } from 'n8n-workflow';
export const userOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['user'],
},
},
options: [
{
name: 'Info',
value: 'info',
description: 'Get information about a user',
action: 'Get information about a user',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get a list of many users',
action: 'Get many users',
},
{
name: 'Get Presence',
value: 'getPresence',
description: 'Get online status of a user',
action: "Get a user's presence status",
},
],
default: 'info',
},
];
export const userFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* 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:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['user'],
operation: ['getAll'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['user'],
operation: ['getAll'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'Max number of results to return',
},
/* -------------------------------------------------------------------------- */
/* 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',
},
];
@@ -0,0 +1,334 @@
import type { INodeProperties } from 'n8n-workflow';
export const userGroupOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['userGroup'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a user group',
action: 'Create a user group',
},
{
name: 'Disable',
value: 'disable',
description: 'Disable a user group',
action: 'Disable a user group',
},
{
name: 'Enable',
value: 'enable',
description: 'Enable a user group',
action: 'Enable a user group',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many user groups',
action: 'Get many user groups',
},
{
name: 'Update',
value: 'update',
description: 'Update a user group',
action: 'Update a user group',
},
],
default: 'create',
},
];
export const userGroupFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* userGroup:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['create'],
resource: ['userGroup'],
},
},
required: true,
description: 'A name for the User Group. Must be unique among User Groups.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['userGroup'],
operation: ['create'],
},
},
options: [
{
displayName: 'Channel Names or IDs',
name: 'channelIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: [],
description:
'A comma-separated string of encoded channel IDs for which the User Group uses as a default. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
description: 'A short description of the User Group',
},
{
displayName: 'Handle',
name: 'handle',
type: 'string',
default: '',
description: 'A mention handle. Must be unique among channels, users and User Groups.',
},
{
displayName: 'Include Count',
name: 'include_count',
type: 'boolean',
default: true,
description: 'Whether to include the number of users in each User Group',
},
],
},
/* ----------------------------------------------------------------------- */
/* userGroup:disable */
/* ----------------------------------------------------------------------- */
{
displayName: 'User Group ID',
name: 'userGroupId',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['disable'],
resource: ['userGroup'],
},
},
required: true,
description: 'The encoded ID of the User Group to update',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['userGroup'],
operation: ['disable'],
},
},
options: [
{
displayName: 'Include Count',
name: 'include_count',
type: 'boolean',
default: true,
description: 'Whether to include the number of users in each User Group',
},
],
},
/* ----------------------------------------------------------------------- */
/* userGroup:enable */
/* ----------------------------------------------------------------------- */
{
displayName: 'User Group ID',
name: 'userGroupId',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['enable'],
resource: ['userGroup'],
},
},
required: true,
description: 'The encoded ID of the User Group to update',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['userGroup'],
operation: ['enable'],
},
},
options: [
{
displayName: 'Include Count',
name: 'include_count',
type: 'boolean',
default: true,
description: 'Whether to include the number of users in each User Group',
},
],
},
/* -------------------------------------------------------------------------- */
/* userGroup:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['userGroup'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['userGroup'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 500,
},
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['userGroup'],
operation: ['getAll'],
},
},
options: [
{
displayName: 'Include Count',
name: 'include_count',
type: 'boolean',
default: true,
description: 'Whether to include the number of users in each User Group',
},
{
displayName: 'Include Disabled',
name: 'include_disabled',
type: 'boolean',
default: true,
description: 'Whether to include disabled User Groups',
},
{
displayName: 'Include Users',
name: 'include_users',
type: 'boolean',
default: true,
description: 'Whether to include the list of users for each User Group',
},
],
},
/* ----------------------------------------------------------------------- */
/* userGroup:update */
/* ----------------------------------------------------------------------- */
{
displayName: 'User Group ID',
name: 'userGroupId',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['update'],
resource: ['userGroup'],
},
},
required: true,
description: 'The encoded ID of the User Group to update',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['userGroup'],
operation: ['update'],
},
},
options: [
{
displayName: 'Channel Names or IDs',
name: 'channels',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getChannels',
},
default: [],
description:
'A comma-separated string of encoded channel IDs for which the User Group uses as a default. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
description: 'A short description of the User Group',
},
{
displayName: 'Handle',
name: 'handle',
type: 'string',
default: '',
description: 'A mention handle. Must be unique among channels, users and User Groups.',
},
{
displayName: 'Include Count',
name: 'include_count',
type: 'boolean',
default: true,
description: 'Whether to include the number of users in each User Group',
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'A name for the User Group. Must be unique among User Groups.',
},
],
},
];
@@ -0,0 +1,177 @@
import type { INodeProperties } from 'n8n-workflow';
export const userProfileOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['userProfile'],
},
},
options: [
{
name: 'Get',
value: 'get',
description: "Get your user's profile",
action: 'Get a user profile',
},
{
name: 'Update',
value: 'update',
description: "Update user's profile",
action: 'Update a user profile',
},
],
default: 'get',
},
];
export const userProfileFields: INodeProperties[] = [
/* -------------------------------------------------------------------------- */
/* userProfile:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['userProfile'],
operation: ['update'],
},
},
options: [
{
displayName: 'Custom Fields',
name: 'customFieldUi',
placeholder: 'Add Custom Fields',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
default: {},
options: [
{
name: 'customFieldValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field Name or ID',
name: 'id',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getTeamFields',
},
default: '',
description:
'ID of the field to set. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Field Value',
name: 'value',
type: 'string',
default: '',
description: 'Value of the field to set',
},
{
displayName: 'Alt',
name: 'alt',
type: 'string',
default: '',
},
],
},
],
},
{
displayName: 'Email',
name: 'email',
type: 'string',
placeholder: 'name@email.com',
default: '',
description: 'This field can only be changed by admins for users on paid teams',
},
{
displayName: 'First Name',
name: 'first_name',
type: 'string',
default: '',
},
{
displayName: 'Last Name',
name: 'last_name',
type: 'string',
default: '',
},
{
displayName: 'Status Emoji',
name: 'status_emoji',
type: 'string',
default: '',
description:
'Is a string referencing an emoji enabled for the Slack team, such as :mountain_railway:',
},
{
displayName: 'Status Expiration',
name: 'status_expiration',
type: 'dateTime',
default: '',
description:
'Is an integer specifying seconds since the epoch, more commonly known as "UNIX time". Providing 0 or omitting this field results in a custom status that will not expire.',
},
{
displayName: 'Status Text',
name: 'status_text',
type: 'string',
default: '',
description: 'Allows up to 100 characters, though we strongly encourage brevity',
},
{
displayName: 'User ID',
name: 'user',
type: 'string',
default: '',
description:
'ID of user to change. This argument may only be specified by team admins on paid teams.',
},
],
},
/* -------------------------------------------------------------------------- */
/* userProfile:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: ['userProfile'],
operation: ['get'],
},
},
options: [
{
displayName: 'Include Labels',
name: 'include_labels',
type: 'boolean',
default: false,
description: 'Whether to include labels for each ID in custom profile fields',
},
{
displayName: 'User ID',
name: 'user',
type: 'string',
default: '',
description: 'User to retrieve profile info for',
},
],
},
];