n8n/packages/nodes-base/nodes/Slack/V2/MessageDescription.ts
OlegIvaniv aa53c46367
feat(Slack Node): Add option to include link to workflow in Slack node (#6611)
* feat(Slack Node): Add “automated by” message to Slack node’s post message

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>

* Pass instanceBaseUrl to node context

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>

* Move `includeLinkToWorkflow` to options

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>

* keep "includeLinkToWorkflow" hidden

* Only append the message for version 2.1 and up

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>

---------

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
2023-07-10 15:03:21 +02:00

1168 lines
25 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { INodeProperties } from 'n8n-workflow';
export const messageOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['message'],
},
},
options: [
{
name: 'Delete',
value: 'delete',
action: 'Delete a message',
},
{
name: 'Get Permalink',
value: 'getPermalink',
action: 'Get a message permalink',
},
{
name: 'Search',
value: 'search',
action: 'Search for messages',
},
{
name: 'Send',
value: 'post',
action: 'Send a message',
},
{
name: 'Update',
value: 'update',
action: 'Update a message',
},
],
default: 'post',
},
];
export const messageFields: INodeProperties[] = [
/* ----------------------------------------------------------------------- */
/* message:getPermalink
/* ----------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a channel...',
description: 'The Slack channel to get the message permalink from',
displayOptions: {
show: {
resource: ['message'],
operation: ['getPermalink'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a channel...',
typeOptions: {
searchListMethod: 'getChannels',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Slack Channel ID',
},
},
],
placeholder: 'C0122KQ70S7E',
},
{
displayName: 'By URL',
name: 'url',
type: 'string',
placeholder: 'https://app.slack.com/client/TS9594PZK/B0556F47Z3A',
validation: [
{
type: 'regex',
properties: {
regex: 'http(s)?://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
errorMessage: 'Not a valid Slack Channel URL',
},
},
],
extractValue: {
type: 'regex',
regex: 'https://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
},
},
],
},
{
displayName: 'Message Timestamp',
name: 'timestamp',
required: true,
type: 'number',
default: undefined,
displayOptions: {
show: {
resource: ['message'],
operation: ['getPermalink'],
},
},
description: 'Timestamp of the message to message',
placeholder: '1663233118.856619',
},
/* -------------------------------------------------------------------------- */
/* message:post */
/* -------------------------------------------------------------------------- */
{
displayName: 'Send Message To',
name: 'select',
type: 'options',
required: true,
displayOptions: {
show: {
resource: ['message'],
operation: ['post'],
},
},
options: [
{
name: 'Channel',
value: 'channel',
},
{
name: 'User',
value: 'user',
},
],
default: '',
placeholder: 'Select...',
},
{
displayName: 'Channel',
name: 'channelId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a channel...',
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a channel...',
typeOptions: {
searchListMethod: 'getChannels',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Slack Channel ID',
},
},
],
placeholder: 'C0122KQ70S7E',
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: '#general',
},
{
displayName: 'By URL',
name: 'url',
type: 'string',
placeholder: 'https://app.slack.com/client/TS9594PZK/B0556F47Z3A',
validation: [
{
type: 'regex',
properties: {
regex: 'http(s)?://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
errorMessage: 'Not a valid Slack Channel URL',
},
},
],
extractValue: {
type: 'regex',
regex: 'https://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
},
},
],
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
select: ['channel'],
},
},
required: true,
description: 'The Slack channel to send to',
},
{
displayName: 'User',
name: 'user',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a user...',
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
select: ['user'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a user...',
typeOptions: {
searchListMethod: 'getUsers',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Slack User ID',
},
},
],
placeholder: 'U123AB45JGM',
},
{
displayName: 'By username',
name: 'username',
type: 'string',
placeholder: '@username',
},
],
},
{
displayName: 'Message Type',
name: 'messageType',
type: 'options',
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
},
},
description:
'Whether to send a simple text message, or use Slacks Blocks UI builder for more sophisticated messages that include form fields, sections and more',
options: [
{
name: 'Simple Text Message',
value: 'text',
description: 'Supports basic Markdown',
},
{
name: 'Blocks',
value: 'block',
description:
"Combine text, buttons, form elements, dividers and more in Slack 's visual builder",
},
{
name: 'Attachments',
value: 'attachment',
},
],
default: 'text',
},
{
displayName: 'Message Text',
name: 'text',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
messageType: ['text'],
},
},
description:
'The message text to post. Supports <a href="https://api.slack.com/reference/surfaces/formatting">markdown</a> by default - this can be disabled in "Options".',
},
{
displayName: 'Blocks',
name: 'blocksUi',
type: 'string',
required: true,
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
messageType: ['block'],
},
},
typeOptions: {
rows: 3,
},
description:
"Enter the JSON output from Slack's visual Block Kit Builder here. You can then use expressions to add variable content to your blocks. To create blocks, use <a target='_blank' href='https://app.slack.com/block-kit-builder'>Slack's Block Kit Builder</a>",
hint: "To create blocks, use <a target='_blank' href='https://app.slack.com/block-kit-builder'>Slack's Block Kit Builder</a>",
default: '',
},
{
displayName: 'Notification Text',
name: 'text',
type: 'string',
default: '',
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
messageType: ['block'],
},
},
description:
'Fallback text to display in slack notifications. Supports <a href="https://api.slack.com/reference/surfaces/formatting">markdown</a> by default - this can be disabled in "Options".',
},
{
displayName: 'This is a legacy Slack feature. Slack advises to instead use Blocks.',
name: 'noticeAttachments',
type: 'notice',
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
messageType: ['attachment'],
},
},
default: '',
},
{
displayName: 'Attachments',
name: 'attachments',
type: 'collection',
typeOptions: {
multipleValues: true,
multipleValueButtonText: 'Add attachment',
},
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
messageType: ['attachment'],
},
},
default: {}, // TODO: Remove comment: has to make default array for the main property, check where that happens in UI
placeholder: 'Add attachment item',
options: [
{
displayName: 'Fallback Text',
name: 'fallback',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
description: 'Required plain-text summary of the attachment',
},
{
displayName: 'Text',
name: 'text',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
},
{
displayName: 'Title Link',
name: 'title_link',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
},
{
displayName: 'Color',
name: 'color',
type: 'color',
default: '#ff0000',
description: 'Color of the line left of text',
},
{
displayName: 'Pretext',
name: 'pretext',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
description: 'Text which appears before the message block',
},
{
displayName: 'Author Name',
name: 'author_name',
type: 'string',
default: '',
description: 'Name that should appear',
},
{
displayName: 'Author Link',
name: 'author_link',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
},
{
displayName: 'Author Icon',
name: 'author_icon',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
description: 'Icon which should appear for the user',
},
{
displayName: 'Image URL',
name: 'image_url',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
},
{
displayName: 'Thumbnail URL',
name: 'thumb_url',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
},
{
displayName: 'Footer',
name: 'footer',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
description: 'Text of footer to add',
},
{
displayName: 'Footer Icon',
name: 'footer_icon',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
description: 'Icon which should appear next to footer',
},
{
displayName: 'Message Timestamp',
name: 'ts',
type: 'number',
default: 0,
description: 'Timestamp of the message to post',
placeholder: '1663233118.856619',
},
{
displayName: 'Fields',
name: 'fields',
placeholder: 'Add Fields',
description: 'Fields to add to message',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
default: {},
options: [
{
name: 'item',
displayName: 'Item',
values: [
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
},
{
displayName: 'Short',
name: 'short',
type: 'boolean',
default: true,
description: 'Whether items can be displayed next to each other',
},
],
},
],
},
],
},
{
displayName: 'Options',
name: 'otherOptions',
type: 'collection',
displayOptions: {
show: {
operation: ['post'],
resource: ['message'],
},
},
default: {},
description: 'Other options to set',
placeholder: 'Add options',
options: [
{
displayName: 'Include Link To Workflow',
name: 'includeLinkToWorkflow',
type: 'boolean',
default: true,
description:
'Whether to append a link to this workflow at the end of the message. This is helpful if you have many workflows sending Slack messages.',
},
{
displayName: 'Custom Bot Profile Photo',
name: 'botProfile',
type: 'fixedCollection',
default: {
imageValues: [
{
profilePhotoType: '',
},
],
},
description:
'Set an image or an emoji as the Profile Photo (avatar) of the bot sending the message. Will not be used if sending message as a user.',
options: [
{
name: 'imageValues',
displayName: 'Add Bot Profile Photo',
values: [
{
displayName: 'Profile Photo Type',
name: 'profilePhotoType',
type: 'options',
options: [
{
name: 'Image URL',
value: 'image',
},
{
name: 'Emoji Code',
value: 'emoji',
},
],
default: '',
placeholder: 'Select a type…',
},
{
displayName: 'Emoji Code',
name: 'icon_emoji',
type: 'string',
default: '',
displayOptions: {
show: {
profilePhotoType: ['emoji'],
},
},
description:
'Only used if sending message as a bot. Use emoji codes like +1, not an actual emoji like 👍. <a target="_blank" href=" https://www.webfx.com/tools/emoji-cheat-sheet/">List of common emoji codes</a>',
},
{
displayName: 'Image URL',
name: 'icon_url',
type: 'string',
default: '',
displayOptions: {
show: {
profilePhotoType: ['image'],
},
},
description: 'Only used if sending message as a bot',
},
],
},
],
},
{
displayName: 'Link User and Channel Names',
name: 'link_names',
type: 'boolean',
default: false,
description: 'Whether to turn @users and #channels in message text into clickable links',
},
{
displayName: 'Reply to a Message',
name: 'thread_ts',
type: 'fixedCollection',
default: {},
placeholder: 'Reply to a Message',
description: "Provide another message's Timestamp value to make this message a reply",
options: [
{
displayName: 'Reply to a Message',
name: 'replyValues',
values: [
{
displayName: 'Message Timestamp to Reply To',
name: 'thread_ts',
type: 'number',
default: undefined,
placeholder: '1663233118.856619',
description:
'Message timestamps are included in output data of Slack nodes, abbreviated to ts',
},
{
displayName: 'Reply to Thread',
name: 'reply_broadcast',
type: 'boolean',
default: false,
description:
'Whether the reply should be made visible to everyone in the channel or conversation',
},
],
},
],
},
{
displayName: 'Use Markdown?',
name: 'mrkdwn',
type: 'boolean',
default: true,
description: 'Whether to use Slack Markdown to format the message',
},
{
displayName: 'Unfurl Links',
name: 'unfurl_links',
type: 'boolean',
default: false,
description: 'Whether to enable unfurling of primarily text-based content',
},
{
displayName: 'Unfurl Media',
name: 'unfurl_media',
type: 'boolean',
default: true,
description: 'Whether to disable unfurling of media content',
},
{
displayName: 'Send as Ephemeral Message',
name: 'ephemeral',
type: 'fixedCollection',
default: {},
displayOptions: {
show: {
'/select': ['channel'],
},
},
placeholder: 'Send as Ephemeral Message',
description: 'Whether to send a temporary, ephemeral message',
options: [
{
displayName: 'Send as Ephemeral Message',
name: 'ephemeralValues',
values: [
{
displayName: 'User to Send',
name: 'user',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a user...',
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a user...',
typeOptions: {
searchListMethod: 'getUsers',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Slack User ID',
},
},
],
placeholder: 'U123AB45JGM',
},
],
},
{
displayName: 'Send as Ephemeral Message',
name: 'ephemeral',
type: 'boolean',
default: true,
description: 'Whether to send a temporary, ephemeral message',
},
],
},
],
},
{
displayName: 'Send as Ephemeral Message',
name: 'ephemeral',
type: 'boolean',
displayOptions: {
show: {
'/select': ['user'],
},
},
default: true,
description: 'Whether to send a temporary, ephemeral message',
},
{
displayName: 'Send as User',
name: 'sendAsUser',
type: 'string',
displayOptions: {
show: {
'/authentication': ['accessToken'],
},
},
default: '',
description:
'The message will be sent from this username (i.e. as if this individual sent the message). Add chat:write.customize scope on Slack API',
},
],
},
/* ----------------------------------------------------------------------- */
/* message:update */
/* ----------------------------------------------------------------------- */
{
displayName: 'Channel',
name: 'channelId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a channel...',
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a channel...',
typeOptions: {
searchListMethod: 'getChannels',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Slack Channel ID',
},
},
],
placeholder: 'C0122KQ70S7E',
},
{
displayName: 'By URL',
name: 'url',
type: 'string',
placeholder: 'https://app.slack.com/client/TS9594PZK/B0556F47Z3A',
validation: [
{
type: 'regex',
properties: {
regex: 'http(s)?://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
errorMessage: 'Not a valid Slack Channel URL',
},
},
],
extractValue: {
type: 'regex',
regex: 'https://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
},
},
],
required: true,
displayOptions: {
show: {
resource: ['message'],
operation: ['update'],
},
},
description: 'The Slack channel to update the message from',
},
{
displayName: 'Message Timestamp',
name: 'ts',
required: true,
type: 'number',
default: undefined,
displayOptions: {
show: {
resource: ['message'],
operation: ['update'],
},
},
description: 'Timestamp of the message to update',
placeholder: '1663233118.856619',
},
{
displayName: 'Message Text',
name: 'text',
type: 'string',
default: '',
displayOptions: {
show: {
resource: ['message'],
operation: ['update'],
},
},
description:
'The message text to update. Supports <a href="https://api.slack.com/reference/surfaces/formatting/">markdown</a> by default - this can be disabled in "Options".',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Option',
default: {},
displayOptions: {
show: {
resource: ['message'],
operation: ['update'],
},
},
options: [
{
displayName: 'Link User and Channel Names',
name: 'link_names',
type: 'boolean',
default: false,
description: 'Whether to find and link channel names and usernames',
},
{
displayName: 'Parse',
name: 'parse',
type: 'options',
options: [
{
name: 'Client',
value: 'client',
},
{
name: 'Full',
value: 'full',
},
{
name: 'None',
value: 'none',
},
],
default: 'client',
description: 'Change how messages are treated',
},
],
},
/* ----------------------------------------------------------------------- */
/* message:delete
/* ----------------------------------------------------------------------- */
{
displayName: 'Delete Message From',
name: 'select',
type: 'options',
required: true,
displayOptions: {
show: {
resource: ['message'],
operation: ['delete'],
},
},
options: [
{
name: 'Channel',
value: 'channel',
},
{
name: 'User',
value: 'user',
},
],
default: '',
placeholder: 'Select...',
},
{
displayName: 'Channel',
name: 'channelId',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a channel...',
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a channel...',
typeOptions: {
searchListMethod: 'getChannels',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Slack Channel ID',
},
},
],
placeholder: 'C0122KQ70S7E',
},
{
displayName: 'By URL',
name: 'url',
type: 'string',
placeholder: 'https://app.slack.com/client/TS9594PZK/B0556F47Z3A',
validation: [
{
type: 'regex',
properties: {
regex: 'http(s)?://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
errorMessage: 'Not a valid Slack Channel URL',
},
},
],
extractValue: {
type: 'regex',
regex: 'https://app.slack.com/client/.*/([a-zA-Z0-9]{2,})',
},
},
],
displayOptions: {
show: {
operation: ['delete'],
resource: ['message'],
select: ['channel'],
},
},
required: true,
description: 'The Slack channel to delete the message from',
},
{
displayName: 'User',
name: 'user',
type: 'resourceLocator',
default: { mode: 'list', value: '' },
placeholder: 'Select a user...',
displayOptions: {
show: {
operation: ['delete'],
resource: ['message'],
select: ['user'],
},
},
modes: [
{
displayName: 'From List',
name: 'list',
type: 'list',
placeholder: 'Select a user...',
typeOptions: {
searchListMethod: 'getUsers',
searchable: true,
},
},
{
displayName: 'By ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Slack User ID',
},
},
],
placeholder: 'U123AB45JGM',
},
],
},
{
displayName: 'Message Timestamp',
name: 'timestamp',
required: true,
type: 'number',
default: undefined,
displayOptions: {
show: {
resource: ['message'],
operation: ['delete'],
},
},
description: 'Timestamp of the message to delete',
placeholder: '1663233118.856619',
},
/* ----------------------------------------------------------------------- */
/* message:search
/* ----------------------------------------------------------------------- */
{
displayName: 'Search Query',
name: 'query',
type: 'string',
description: 'The text to search for within messages',
required: true,
default: '',
displayOptions: {
show: {
resource: ['message'],
operation: ['search'],
},
},
},
{
displayName: 'Sort By',
name: 'sort',
description: 'How search results should be sorted. You can sort by.',
type: 'options',
displayOptions: {
show: {
resource: ['message'],
operation: ['search'],
},
},
options: [
{
name: 'Newest',
value: 'desc',
},
{
name: 'Oldest',
value: 'asc',
},
{
name: 'Relevance Score',
value: 'relevance',
},
],
default: 'desc',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: ['message'],
operation: ['search'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: ['message'],
operation: ['search'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 50,
},
default: 25,
description: 'Max number of results to return',
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
displayOptions: {
show: {
resource: ['message'],
operation: ['search'],
},
},
options: [
{
displayName: 'Search in Channel',
name: 'searchChannel',
type: 'multiOptions',
description:
'Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
default: [],
placeholder: 'Select a channel...',
typeOptions: {
loadOptionsMethod: 'getChannelsName',
},
},
],
default: {},
},
];