mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
✨ Extend Twist Node (#1721)
* Add get/getAll:messageConversation to Twist node
* Add delete:messageConversation to Twist node
* Add update:messageConversation to Twist node
* Add archive/unarchive/delete:channel to Twist node
* Add add/update/get/getAll/remove:Thread to Twist node
* Add add/update/get/getAll/remove:Comment to Twist node
* Lint fixes
* Fix operations's descriptions
* Enhance Twist node code
* Reorder attributes alphabetically
* Fix typos
* Fix the ouput of get:Comment operation
* Fix getAll:Comment & getAll:Thread operations outputs
* 🐛 Add missing scopes and remove not needed parameters
Co-authored-by: dali <servfrdali@yahoo.fr>
This commit is contained in:
parent
fc54f7c82b
commit
f79bc633c0
|
@ -6,7 +6,9 @@ import {
|
|||
const scopes = [
|
||||
'attachments:write',
|
||||
'channels:remove',
|
||||
'comments:remove',
|
||||
'messages:remove',
|
||||
'threads:remove',
|
||||
'workspaces:read',
|
||||
];
|
||||
|
||||
|
|
|
@ -15,11 +15,21 @@ export const channelOperations = [
|
|||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Archive',
|
||||
value: 'archive',
|
||||
description: 'Archive a channel',
|
||||
},
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
description: 'Initiates a public or private channel-based conversation',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'Delete a channel',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
|
@ -30,6 +40,11 @@ export const channelOperations = [
|
|||
value: 'getAll',
|
||||
description: 'Get all channels',
|
||||
},
|
||||
{
|
||||
name: 'Unarchive',
|
||||
value: 'unarchive',
|
||||
description: 'Unarchive a channel',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
|
@ -64,7 +79,7 @@ export const channelFields = [
|
|||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The id of the workspace.',
|
||||
description: 'The ID of the workspace.',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
|
@ -156,28 +171,28 @@ export const channelFields = [
|
|||
},
|
||||
],
|
||||
default: 0,
|
||||
description: 'The color of the channel',
|
||||
description: 'The color of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Description',
|
||||
name: 'description',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The description of the channel',
|
||||
description: 'The description of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Public',
|
||||
name: 'public',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If enabled, the channel will be marked as public',
|
||||
description: 'If enabled, the channel will be marked as public.',
|
||||
},
|
||||
{
|
||||
displayName: 'Temp ID',
|
||||
name: 'temp_id',
|
||||
type: 'number',
|
||||
default: -1,
|
||||
description: 'The temporary id of the channel. It needs to be a negative number.',
|
||||
description: 'The temporary ID of the channel. It needs to be a negative number.',
|
||||
},
|
||||
{
|
||||
displayName: 'User IDs',
|
||||
|
@ -194,8 +209,9 @@ export const channelFields = [
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* channel:get */
|
||||
/* channel:get/archive/unarchive/delete */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Channel ID',
|
||||
|
@ -205,7 +221,10 @@ export const channelFields = [
|
|||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'archive',
|
||||
'delete',
|
||||
'get',
|
||||
'unarchive',
|
||||
],
|
||||
resource: [
|
||||
'channel',
|
||||
|
@ -213,8 +232,9 @@ export const channelFields = [
|
|||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the channel',
|
||||
description: 'The ID of the channel.',
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* channel:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -302,7 +322,7 @@ export const channelFields = [
|
|||
name: 'archived',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If enabled, only archived conversations are returned',
|
||||
description: 'If enabled, only archived conversations are returned.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -400,28 +420,28 @@ export const channelFields = [
|
|||
},
|
||||
],
|
||||
default: 0,
|
||||
description: 'The color of the channel',
|
||||
description: 'The color of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Description',
|
||||
name: 'description',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The description of the channel',
|
||||
description: 'The description of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Name',
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The name of the channel',
|
||||
description: 'The name of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Public',
|
||||
name: 'public',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If enabled, the channel will be marked as public',
|
||||
description: 'If enabled, the channel will be marked as public.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
561
packages/nodes-base/nodes/Twist/CommentDescription.ts
Normal file
561
packages/nodes-base/nodes/Twist/CommentDescription.ts
Normal file
|
@ -0,0 +1,561 @@
|
|||
import {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export const commentOperations = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
description: 'Create a new comment to a thread',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'Delete a comment',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get information about a comment',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
value: 'getAll',
|
||||
description: 'Get all comments',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
description: 'Update a comment',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
description: 'The operation to perform.',
|
||||
},
|
||||
] as INodeProperties[];
|
||||
|
||||
export const commentFields = [
|
||||
/*-------------------------------------------------------------------------- */
|
||||
/* comment:create */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Thread ID',
|
||||
name: 'threadId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the thread.',
|
||||
},
|
||||
{
|
||||
displayName: 'Content',
|
||||
name: 'content',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The content of the comment.',
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Actions',
|
||||
name: 'actionsUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Action',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'actionValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'action',
|
||||
type: 'options',
|
||||
description: 'The action of the button.',
|
||||
options: [
|
||||
{
|
||||
name: 'Open URL',
|
||||
value: 'open_url',
|
||||
},
|
||||
{
|
||||
name: 'Prefill Message',
|
||||
value: 'prefill_message',
|
||||
},
|
||||
{
|
||||
name: 'Send Reply',
|
||||
value: 'send_reply',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Button Text',
|
||||
name: 'button_text',
|
||||
type: 'string',
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Message',
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'send_reply',
|
||||
'prefill_message',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
description: 'The type of the button. (Currently only <code>action</code> is available).',
|
||||
options: [
|
||||
{
|
||||
name: 'Action',
|
||||
value: 'action',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'open_url',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'URL to redirect.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Attachments',
|
||||
name: 'binaryProperties',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
description: 'Name of the property that holds the binary data. Multiple can be defined separated by comma.',
|
||||
},
|
||||
{
|
||||
displayName: 'Direct Mentions',
|
||||
name: 'direct_mentions',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getUsers',
|
||||
loadOptionsDependsOn: [
|
||||
'workspaceId',
|
||||
],
|
||||
},
|
||||
default: [],
|
||||
description: 'The users that are directly mentioned.',
|
||||
},
|
||||
{
|
||||
displayName: 'Mark thread position',
|
||||
name: 'mark_thread_position',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'By default, the position of the thread is marked.',
|
||||
},
|
||||
{
|
||||
displayName: 'Recipients',
|
||||
name: 'recipients',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getUsers',
|
||||
loadOptionsDependsOn: [
|
||||
'workspaceId',
|
||||
],
|
||||
},
|
||||
default: [],
|
||||
description: 'The users that will attached to the comment.',
|
||||
},
|
||||
{
|
||||
displayName: 'Temporary ID',
|
||||
name: 'temp_id',
|
||||
type: 'number',
|
||||
default: 0,
|
||||
description: 'The temporary ID of the comment.',
|
||||
},
|
||||
{
|
||||
displayName: 'Send as integration',
|
||||
name: 'send_as_integration',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Displays the integration as the comment creator.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* comment:get/delete */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Comment ID',
|
||||
name: 'commentId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'get',
|
||||
'delete',
|
||||
],
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the comment.',
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* comment:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Thread ID',
|
||||
name: 'threadId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'If all results should be returned or only up to a given limit.',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 100,
|
||||
},
|
||||
default: 50,
|
||||
description: 'How many results to return.',
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filters',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'As IDs',
|
||||
name: 'as_ids',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If enabled, only the ids of the comments are returned.',
|
||||
},
|
||||
{
|
||||
displayName: 'Ending Object Index',
|
||||
name: 'to_obj_index',
|
||||
type: 'number',
|
||||
default: 50,
|
||||
description: 'Limit comments ending at the specified object index.',
|
||||
},
|
||||
{
|
||||
displayName: 'Newer Than',
|
||||
name: 'newer_than_ts',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description: 'Limits comments to those newer when the specified Unix time.',
|
||||
},
|
||||
{
|
||||
displayName: 'Older Than',
|
||||
name: 'older_than_ts',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description: 'Limits comments to those older than the specified Unix time.',
|
||||
},
|
||||
{
|
||||
displayName: 'Order By',
|
||||
name: 'order_by',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'ASC',
|
||||
value: 'ASC',
|
||||
},
|
||||
{
|
||||
name: 'DESC',
|
||||
value: 'DESC',
|
||||
},
|
||||
],
|
||||
default: 'ASC',
|
||||
description: 'The order of the comments returned - one of DESC or ASC.',
|
||||
},
|
||||
{
|
||||
displayName: 'Starting Object Index',
|
||||
name: 'from_obj_index',
|
||||
type: 'number',
|
||||
default: 0,
|
||||
description: 'Limit comments starting at the specified object index.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* comment:update */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Comment ID',
|
||||
name: 'commentId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the comment.',
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'comment',
|
||||
],
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Actions',
|
||||
name: 'actionsUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Action',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'actionValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'action',
|
||||
type: 'options',
|
||||
description: 'The action of the button.',
|
||||
options: [
|
||||
{
|
||||
name: 'Open URL',
|
||||
value: 'open_url',
|
||||
},
|
||||
{
|
||||
name: 'Prefill Message',
|
||||
value: 'prefill_message',
|
||||
},
|
||||
{
|
||||
name: 'Send Reply',
|
||||
value: 'send_reply',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Button Text',
|
||||
name: 'button_text',
|
||||
type: 'string',
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Message',
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'send_reply',
|
||||
'prefill_message',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
description: 'The type of the button. (Currently only <code>action</code> is available).',
|
||||
options: [
|
||||
{
|
||||
name: 'Action',
|
||||
value: 'action',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'open_url',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'URL to redirect.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Attachments',
|
||||
name: 'binaryProperties',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
description: 'Name of the property that holds the binary data. Multiple can be defined separated by comma.',
|
||||
},
|
||||
{
|
||||
displayName: 'Content',
|
||||
name: 'content',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The content of the comment.',
|
||||
},
|
||||
{
|
||||
displayName: 'Direct Mentions',
|
||||
name: 'direct_mentions',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getUsers',
|
||||
loadOptionsDependsOn: [
|
||||
'workspaceId',
|
||||
],
|
||||
},
|
||||
default: [],
|
||||
description: 'The users that are directly mentioned.',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as INodeProperties[];
|
|
@ -20,6 +20,26 @@ export const messageConversationOperations = [
|
|||
value: 'create',
|
||||
description: 'Create a message in a conversation',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'Delete a message in a conversation',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get a message in a conversation',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
value: 'getAll',
|
||||
description: 'Get all messages in a conversation',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
description: 'Update a message in a conversation',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
description: 'The operation to perform.',
|
||||
|
@ -91,7 +111,7 @@ export const messageConversationFields = [
|
|||
],
|
||||
},
|
||||
},
|
||||
description: `The content of the new message. Mentions can be used as [Name](twist-mention://user_id) for users or [Group name](twist-group-mention://group_id) for groups.`,
|
||||
description: 'The content of the new message. Mentions can be used as <code>[Name](twist-mention://user_id)</code> for users or <code>[Group name](twist-group-mention://group_id)</code> for groups.',
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
|
@ -108,7 +128,7 @@ export const messageConversationFields = [
|
|||
},
|
||||
},
|
||||
default: {},
|
||||
description: 'Other options to set',
|
||||
description: 'Other options to set.',
|
||||
placeholder: 'Add options',
|
||||
options: [
|
||||
{
|
||||
|
@ -128,7 +148,7 @@ export const messageConversationFields = [
|
|||
displayName: 'Action',
|
||||
name: 'action',
|
||||
type: 'options',
|
||||
description: 'The action of the button',
|
||||
description: 'The action of the button.',
|
||||
options: [
|
||||
{
|
||||
name: 'Open URL',
|
||||
|
@ -171,7 +191,7 @@ export const messageConversationFields = [
|
|||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
description: 'The type of the button, for now just action is available.',
|
||||
description: 'The type of the button. (Currently only <code>action</code> is available).',
|
||||
options: [
|
||||
{
|
||||
name: 'Action',
|
||||
|
@ -191,7 +211,7 @@ export const messageConversationFields = [
|
|||
],
|
||||
},
|
||||
},
|
||||
description: 'URL to redirect',
|
||||
description: 'URL to redirect.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
|
@ -213,7 +233,7 @@ export const messageConversationFields = [
|
|||
loadOptionsMethod: 'getUsers',
|
||||
},
|
||||
default: [],
|
||||
description: `The users that are directly mentioned`,
|
||||
description: 'The users that are directly mentioned.',
|
||||
},
|
||||
// {
|
||||
// displayName: 'Direct Group Mentions ',
|
||||
|
@ -223,8 +243,289 @@ export const messageConversationFields = [
|
|||
// loadOptionsMethod: 'getGroups',
|
||||
// },
|
||||
// default: [],
|
||||
// description: `The groups that are directly mentioned`,
|
||||
// description: 'The groups that are directly mentioned.',
|
||||
// },
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* messageConversation:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Workspace ID',
|
||||
name: 'workspaceId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getWorkspaces',
|
||||
},
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
resource: [
|
||||
'messageConversation',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the workspace.',
|
||||
},
|
||||
{
|
||||
displayName: 'Conversation ID',
|
||||
name: 'conversationId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getConversations',
|
||||
loadOptionsDependsOn: [
|
||||
'workspaceId',
|
||||
],
|
||||
},
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
resource: [
|
||||
'messageConversation',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the conversation.',
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
resource: [
|
||||
'messageConversation',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
description: 'Other options to set.',
|
||||
options: [
|
||||
{
|
||||
displayName: 'Ending Object Index',
|
||||
name: 'to_obj_index',
|
||||
type: 'number',
|
||||
default: 50,
|
||||
description: 'Limit messages ending at the specified object index.',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 50,
|
||||
description: 'Limits the number of messages returned.',
|
||||
},
|
||||
{
|
||||
displayName: 'Order By',
|
||||
name: 'order_by',
|
||||
type: 'options',
|
||||
default: 'ASC',
|
||||
description: 'The order of the conversations returned - one of DESC or ASC.',
|
||||
options: [
|
||||
{
|
||||
name: 'ASC',
|
||||
value: 'ASC',
|
||||
},
|
||||
{
|
||||
name: 'DESC',
|
||||
value: 'DESC',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Starting Object Index',
|
||||
name: 'from_obj_index',
|
||||
type: 'number',
|
||||
default: 0,
|
||||
description: 'Limit messages starting at the specified object index.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* messageConversation:get/delete/update */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Message ID',
|
||||
name: 'id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'delete',
|
||||
'get',
|
||||
],
|
||||
resource: [
|
||||
'messageConversation',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the conversation message.',
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* messageConversation:update */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Conversation Message ID',
|
||||
name: 'id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
resource: [
|
||||
'messageConversation',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the conversation message.',
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
resource: [
|
||||
'messageConversation',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
description: 'Other options to set.',
|
||||
options: [
|
||||
{
|
||||
displayName: 'Actions',
|
||||
name: 'actionsUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Action',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'actionValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'action',
|
||||
type: 'options',
|
||||
description: 'The action of the button.',
|
||||
options: [
|
||||
{
|
||||
name: 'Open URL',
|
||||
value: 'open_url',
|
||||
},
|
||||
{
|
||||
name: 'Prefill Message',
|
||||
value: 'prefill_message',
|
||||
},
|
||||
{
|
||||
name: 'Send Reply',
|
||||
value: 'send_reply',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Button Text',
|
||||
name: 'button_text',
|
||||
type: 'string',
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Message',
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'send_reply',
|
||||
'prefill_message',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
description: 'The type of the button. (Currently only <code>action</code> is available).',
|
||||
options: [
|
||||
{
|
||||
name: 'Action',
|
||||
value: 'action',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'open_url',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'URL to redirect.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Attachments',
|
||||
name: 'binaryProperties',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
description: 'Name of the property that holds the binary data. Multiple can be defined separated by comma.',
|
||||
},
|
||||
{
|
||||
displayName: 'Content',
|
||||
name: 'content',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The content of the new message. Mentions can be used as <code>[Name](twist-mention://user_id)</code> for users or <code>[Group name](twist-group-mention://group_id)</code> for groups.',
|
||||
},
|
||||
{
|
||||
displayName: 'Direct Mentions',
|
||||
name: 'direct_mentions',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getUsers',
|
||||
},
|
||||
default: [],
|
||||
description: 'The users that are directly mentioned.',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as INodeProperties[];
|
||||
|
|
567
packages/nodes-base/nodes/Twist/ThreadDescription.ts
Normal file
567
packages/nodes-base/nodes/Twist/ThreadDescription.ts
Normal file
|
@ -0,0 +1,567 @@
|
|||
import {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export const threadOperations = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
description: 'Create a new thread in a channel',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'Delete a thread',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get information about a thread',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
value: 'getAll',
|
||||
description: 'Get all threads',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
description: 'Update a thread',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
description: 'The operation to perform.',
|
||||
},
|
||||
] as INodeProperties[];
|
||||
|
||||
export const threadFields = [
|
||||
/*-------------------------------------------------------------------------- */
|
||||
/* thread:create */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Channel ID',
|
||||
name: 'channelId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Title',
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The title of the new thread (1 < length < 300).',
|
||||
},
|
||||
{
|
||||
displayName: 'Content',
|
||||
name: 'content',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The content of the thread.',
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Actions',
|
||||
name: 'actionsUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Action',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'actionValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'action',
|
||||
type: 'options',
|
||||
description: 'The action of the button.',
|
||||
options: [
|
||||
{
|
||||
name: 'Open URL',
|
||||
value: 'open_url',
|
||||
},
|
||||
{
|
||||
name: 'Prefill Message',
|
||||
value: 'prefill_message',
|
||||
},
|
||||
{
|
||||
name: 'Send Reply',
|
||||
value: 'send_reply',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Button Text',
|
||||
name: 'button_text',
|
||||
type: 'string',
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Message',
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'send_reply',
|
||||
'prefill_message',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
description: 'The type of the button. (Currently only <code>action</code> is available).',
|
||||
options: [
|
||||
{
|
||||
name: 'Action',
|
||||
value: 'action',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'open_url',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'URL to redirect.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Attachments',
|
||||
name: 'binaryProperties',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
description: 'Name of the property that holds the binary data. Multiple can be defined separated by comma.',
|
||||
},
|
||||
{
|
||||
displayName: 'Direct Mentions',
|
||||
name: 'direct_mentions',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getUsers',
|
||||
loadOptionsDependsOn: [
|
||||
'workspaceId',
|
||||
],
|
||||
},
|
||||
default: [],
|
||||
description: 'The users that are directly mentioned.',
|
||||
},
|
||||
{
|
||||
displayName: 'Recipients',
|
||||
name: 'recipients',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getUsers',
|
||||
loadOptionsDependsOn: [
|
||||
'workspaceId',
|
||||
],
|
||||
},
|
||||
default: [],
|
||||
description: 'The users that will attached to the thread.',
|
||||
},
|
||||
{
|
||||
displayName: 'Send as integration',
|
||||
name: 'send_as_integration',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Displays the integration as the thread creator.',
|
||||
},
|
||||
{
|
||||
displayName: 'Temporary ID',
|
||||
name: 'temp_id',
|
||||
type: 'number',
|
||||
default: 0,
|
||||
description: 'The temporary ID of the thread.',
|
||||
},
|
||||
],
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* thread:get/delete */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Thread ID',
|
||||
name: 'threadId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'get',
|
||||
'delete',
|
||||
],
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the thread.',
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* thread:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Channel ID',
|
||||
name: 'channelId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the channel.',
|
||||
},
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'If all results should be returned or only up to a given limit.',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 100,
|
||||
},
|
||||
default: 50,
|
||||
description: 'How many results to return.',
|
||||
},
|
||||
{
|
||||
displayName: 'Filters',
|
||||
name: 'filters',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'As IDs',
|
||||
name: 'as_ids',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'If enabled, only the IDs of the threads are returned.',
|
||||
},
|
||||
{
|
||||
displayName: 'Filter By',
|
||||
name: 'filter_by',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Attached to me',
|
||||
value: 'attached_to_me',
|
||||
},
|
||||
{
|
||||
name: 'Everyone',
|
||||
value: 'everyone',
|
||||
},
|
||||
{
|
||||
name: 'Starred',
|
||||
value: 'is_starred',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
description: 'A filter can be one of <code>attached_to_me</code>, <code>everyone</code> and <code>is_starred</code>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Newer Than',
|
||||
name: 'newer_than_ts',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description: 'Limits threads to those newer when the specified Unix time.',
|
||||
},
|
||||
{
|
||||
displayName: 'Older Than',
|
||||
name: 'older_than_ts',
|
||||
type: 'dateTime',
|
||||
default: '',
|
||||
description: 'Limits threads to those older than the specified Unix time.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* thread:update */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Thread ID',
|
||||
name: 'threadId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
description: 'The ID of the thread.',
|
||||
},
|
||||
{
|
||||
displayName: 'Update Fields',
|
||||
name: 'updateFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'thread',
|
||||
],
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Actions',
|
||||
name: 'actionsUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Action',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'actionValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Action',
|
||||
name: 'action',
|
||||
type: 'options',
|
||||
description: 'The action of the button.',
|
||||
options: [
|
||||
{
|
||||
name: 'Open URL',
|
||||
value: 'open_url',
|
||||
},
|
||||
{
|
||||
name: 'Prefill Message',
|
||||
value: 'prefill_message',
|
||||
},
|
||||
{
|
||||
name: 'Send Reply',
|
||||
value: 'send_reply',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Button Text',
|
||||
name: 'button_text',
|
||||
type: 'string',
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Message',
|
||||
name: 'message',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'send_reply',
|
||||
'prefill_message',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'The text for the action button.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
description: 'The type of the button. (Currently only <code>action</code> is available).',
|
||||
options: [
|
||||
{
|
||||
name: 'Action',
|
||||
value: 'action',
|
||||
},
|
||||
],
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
action: [
|
||||
'open_url',
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'URL to redirect.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Attachments',
|
||||
name: 'binaryProperties',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
description: 'Name of the property that holds the binary data. Multiple can be defined separated by comma.',
|
||||
},
|
||||
{
|
||||
displayName: 'Content',
|
||||
name: 'content',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The content of the thread.',
|
||||
},
|
||||
{
|
||||
displayName: 'Direct Mentions',
|
||||
name: 'direct_mentions',
|
||||
type: 'multiOptions',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getUsers',
|
||||
loadOptionsDependsOn: [
|
||||
'workspaceId',
|
||||
],
|
||||
},
|
||||
default: [],
|
||||
description: 'The users that are directly mentioned.',
|
||||
},
|
||||
{
|
||||
displayName: 'Title',
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'The title of the thread (1 < length < 300).',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as INodeProperties[];
|
|
@ -29,7 +29,16 @@ import {
|
|||
messageConversationOperations,
|
||||
} from './MessageConversationDescription';
|
||||
|
||||
import {
|
||||
threadFields,
|
||||
threadOperations
|
||||
} from './ThreadDescription';
|
||||
import {
|
||||
commentFields,
|
||||
commentOperations
|
||||
} from './CommentDescription';
|
||||
import uuid = require('uuid');
|
||||
import * as moment from 'moment';
|
||||
|
||||
export class Twist implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
|
@ -62,18 +71,30 @@ export class Twist implements INodeType {
|
|||
name: 'Channel',
|
||||
value: 'channel',
|
||||
},
|
||||
{
|
||||
name: 'Comment',
|
||||
value: 'comment',
|
||||
},
|
||||
{
|
||||
name: 'Message Conversation',
|
||||
value: 'messageConversation',
|
||||
},
|
||||
{
|
||||
name: 'Thread',
|
||||
value: 'thread',
|
||||
},
|
||||
],
|
||||
default: 'messageConversation',
|
||||
description: 'The resource to operate on.',
|
||||
},
|
||||
...channelOperations,
|
||||
...channelFields,
|
||||
...commentOperations,
|
||||
...commentFields,
|
||||
...messageConversationOperations,
|
||||
...messageConversationFields,
|
||||
...threadOperations,
|
||||
...threadFields,
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -169,10 +190,15 @@ export class Twist implements INodeType {
|
|||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/channels/add', body);
|
||||
}
|
||||
//https://developer.twist.com/v3/#remove-channel
|
||||
if (operation === 'delete') {
|
||||
qs.id = this.getNodeParameter('channelId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/channels/remove', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#get-channel
|
||||
if (operation === 'get') {
|
||||
const channelId = this.getNodeParameter('channelId', i) as string;
|
||||
qs.id = channelId;
|
||||
qs.id = this.getNodeParameter('channelId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'GET', '/channels/getone', {}, qs);
|
||||
}
|
||||
|
@ -202,6 +228,190 @@ export class Twist implements INodeType {
|
|||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/channels/update', body);
|
||||
}
|
||||
//https://developer.twist.com/v3/#archive-channel
|
||||
if (operation === 'archive') {
|
||||
qs.id = this.getNodeParameter('channelId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/channels/archive', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#unarchive-channel
|
||||
if (operation === 'unarchive') {
|
||||
qs.id = this.getNodeParameter('channelId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/channels/unarchive', {}, qs);
|
||||
}
|
||||
}
|
||||
if (resource === 'comment') {
|
||||
//https://developer.twist.com/v3/#add-comment
|
||||
if (operation === 'create') {
|
||||
const threadId = this.getNodeParameter('threadId', i) as string;
|
||||
const content = this.getNodeParameter('content', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
const body: IDataObject = {
|
||||
thread_id: threadId,
|
||||
content,
|
||||
};
|
||||
Object.assign(body, additionalFields);
|
||||
|
||||
if (body.actionsUi) {
|
||||
const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[];
|
||||
|
||||
if (actions) {
|
||||
body.actions = actions;
|
||||
delete body.actionsUi;
|
||||
}
|
||||
}
|
||||
|
||||
if (body.binaryProperties) {
|
||||
const binaryProperties = (body.binaryProperties as string).split(',') as string[];
|
||||
|
||||
const attachments: IDataObject[] = [];
|
||||
|
||||
for (const binaryProperty of binaryProperties) {
|
||||
|
||||
const item = items[i].binary as IBinaryKeyData;
|
||||
|
||||
const binaryData = item[binaryProperty] as IBinaryData;
|
||||
|
||||
if (binaryData === undefined) {
|
||||
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
|
||||
}
|
||||
|
||||
attachments.push(await twistApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
'/attachments/upload',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
formData: {
|
||||
file_name: {
|
||||
value: Buffer.from(binaryData.data, BINARY_ENCODING),
|
||||
options: {
|
||||
filename: binaryData.fileName,
|
||||
},
|
||||
},
|
||||
attachment_id: uuid(),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
body.attachments = attachments;
|
||||
}
|
||||
|
||||
if (body.direct_mentions) {
|
||||
const directMentions: string[] = [];
|
||||
for (const directMention of body.direct_mentions as number[]) {
|
||||
directMentions.push(`[name](twist-mention://${directMention})`);
|
||||
}
|
||||
body.content = `${directMentions.join(' ')} ${body.content}`;
|
||||
}
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/comments/add', body);
|
||||
}
|
||||
//https://developer.twist.com/v3/#remove-comment
|
||||
if (operation === 'delete') {
|
||||
qs.id = this.getNodeParameter('commentId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/comments/remove', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#get-comment
|
||||
if (operation === 'get') {
|
||||
qs.id = this.getNodeParameter('commentId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'GET', '/comments/getone', {}, qs);
|
||||
responseData = responseData?.comment;
|
||||
}
|
||||
//https://developer.twist.com/v3/#get-all-comments
|
||||
if (operation === 'getAll') {
|
||||
const threadId = this.getNodeParameter('threadId', i) as string;
|
||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||
const filters = this.getNodeParameter('filters', i) as IDataObject;
|
||||
qs.thread_id = threadId;
|
||||
|
||||
Object.assign(qs, filters);
|
||||
if (!returnAll) {
|
||||
qs.limit = this.getNodeParameter('limit', i) as number;
|
||||
}
|
||||
if (qs.older_than_ts) {
|
||||
qs.older_than_ts = moment(qs.older_than_ts as string).unix();
|
||||
}
|
||||
if (qs.newer_than_ts) {
|
||||
qs.newer_than_ts = moment(qs.newer_than_ts as string).unix();
|
||||
}
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'GET', '/comments/get', {}, qs);
|
||||
if (qs.as_ids) {
|
||||
responseData = (responseData as Array<number>).map(id => ({ ID: id }));
|
||||
}
|
||||
}
|
||||
//https://developer.twist.com/v3/#update-comment
|
||||
if (operation === 'update') {
|
||||
const commentId = this.getNodeParameter('commentId', i) as string;
|
||||
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
|
||||
const body: IDataObject = {
|
||||
id: commentId,
|
||||
};
|
||||
Object.assign(body, updateFields);
|
||||
|
||||
if (body.actionsUi) {
|
||||
const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[];
|
||||
|
||||
if (actions) {
|
||||
body.actions = actions;
|
||||
delete body.actionsUi;
|
||||
}
|
||||
}
|
||||
|
||||
if (body.binaryProperties) {
|
||||
const binaryProperties = (body.binaryProperties as string).split(',') as string[];
|
||||
|
||||
const attachments: IDataObject[] = [];
|
||||
|
||||
for (const binaryProperty of binaryProperties) {
|
||||
|
||||
const item = items[i].binary as IBinaryKeyData;
|
||||
|
||||
const binaryData = item[binaryProperty] as IBinaryData;
|
||||
|
||||
if (binaryData === undefined) {
|
||||
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
|
||||
}
|
||||
|
||||
attachments.push(await twistApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
'/attachments/upload',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
formData: {
|
||||
file_name: {
|
||||
value: Buffer.from(binaryData.data, BINARY_ENCODING),
|
||||
options: {
|
||||
filename: binaryData.fileName,
|
||||
},
|
||||
},
|
||||
attachment_id: uuid(),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
body.attachments = attachments;
|
||||
}
|
||||
|
||||
if (body.direct_mentions) {
|
||||
const directMentions: string[] = [];
|
||||
for (const directMention of body.direct_mentions as number[]) {
|
||||
directMentions.push(`[name](twist-mention://${directMention})`);
|
||||
}
|
||||
body.content = `${directMentions.join(' ')} ${body.content}`;
|
||||
}
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/comments/update', body);
|
||||
}
|
||||
}
|
||||
if (resource === 'messageConversation') {
|
||||
//https://developer.twist.com/v3/#add-message-to-conversation
|
||||
|
@ -244,7 +454,7 @@ export class Twist implements INodeType {
|
|||
attachments.push(await twistApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
`/attachments/upload`,
|
||||
'/attachments/upload',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
|
@ -265,11 +475,11 @@ export class Twist implements INodeType {
|
|||
}
|
||||
|
||||
if (body.direct_mentions) {
|
||||
const direcMentions: string[] = [];
|
||||
const directMentions: string[] = [];
|
||||
for (const directMention of body.direct_mentions as number[]) {
|
||||
direcMentions.push(`[name](twist-mention://${directMention})`);
|
||||
directMentions.push(`[name](twist-mention://${directMention})`);
|
||||
}
|
||||
body.content = `${direcMentions.join(' ')} ${body.content}`;
|
||||
body.content = `${directMentions.join(' ')} ${body.content}`;
|
||||
}
|
||||
|
||||
// if (body.direct_group_mentions) {
|
||||
|
@ -282,6 +492,266 @@ export class Twist implements INodeType {
|
|||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/add', body);
|
||||
}
|
||||
//https://developer.twist.com/v3/#get-message
|
||||
if (operation === 'get') {
|
||||
qs.id = this.getNodeParameter('id', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'GET', '/conversation_messages/getone', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#get-all-messages
|
||||
if (operation === 'getAll') {
|
||||
const conversationId = this.getNodeParameter('conversationId', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
qs.conversation_id = conversationId;
|
||||
Object.assign(qs, additionalFields);
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'GET', '/conversation_messages/get', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#remove-message-from-conversation
|
||||
if (operation === 'delete') {
|
||||
qs.id = this.getNodeParameter('id', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/remove', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#update-message-in-conversation
|
||||
if (operation === 'update') {
|
||||
const id = this.getNodeParameter('id', i) as string;
|
||||
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
|
||||
const body: IDataObject = {
|
||||
id,
|
||||
};
|
||||
Object.assign(body, updateFields);
|
||||
|
||||
if (body.actionsUi) {
|
||||
const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[];
|
||||
|
||||
if (actions) {
|
||||
body.actions = actions;
|
||||
delete body.actionsUi;
|
||||
}
|
||||
}
|
||||
|
||||
if (body.binaryProperties) {
|
||||
const binaryProperties = (body.binaryProperties as string).split(',') as string[];
|
||||
|
||||
const attachments: IDataObject[] = [];
|
||||
|
||||
for (const binaryProperty of binaryProperties) {
|
||||
|
||||
const item = items[i].binary as IBinaryKeyData;
|
||||
|
||||
const binaryData = item[binaryProperty] as IBinaryData;
|
||||
|
||||
if (binaryData === undefined) {
|
||||
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
|
||||
}
|
||||
|
||||
attachments.push(await twistApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
'/attachments/upload',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
formData: {
|
||||
file_name: {
|
||||
value: Buffer.from(binaryData.data, BINARY_ENCODING),
|
||||
options: {
|
||||
filename: binaryData.fileName,
|
||||
},
|
||||
},
|
||||
attachment_id: uuid(),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
body.attachments = attachments;
|
||||
}
|
||||
|
||||
if (body.direct_mentions) {
|
||||
const directMentions: string[] = [];
|
||||
for (const directMention of body.direct_mentions as number[]) {
|
||||
directMentions.push(`[name](twist-mention://${directMention})`);
|
||||
}
|
||||
body.content = `${directMentions.join(' ')} ${body.content}`;
|
||||
}
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/update', body);
|
||||
}
|
||||
}
|
||||
if (resource === 'thread') {
|
||||
//https://developer.twist.com/v3/#add-thread
|
||||
if (operation === 'create') {
|
||||
const channelId = this.getNodeParameter('channelId', i) as string;
|
||||
const title = this.getNodeParameter('title', i) as string;
|
||||
const content = this.getNodeParameter('content', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
const body: IDataObject = {
|
||||
channel_id: channelId,
|
||||
content,
|
||||
title,
|
||||
};
|
||||
Object.assign(body, additionalFields);
|
||||
|
||||
if (body.actionsUi) {
|
||||
const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[];
|
||||
|
||||
if (actions) {
|
||||
body.actions = actions;
|
||||
delete body.actionsUi;
|
||||
}
|
||||
}
|
||||
|
||||
if (body.binaryProperties) {
|
||||
const binaryProperties = (body.binaryProperties as string).split(',') as string[];
|
||||
|
||||
const attachments: IDataObject[] = [];
|
||||
|
||||
for (const binaryProperty of binaryProperties) {
|
||||
|
||||
const item = items[i].binary as IBinaryKeyData;
|
||||
|
||||
const binaryData = item[binaryProperty] as IBinaryData;
|
||||
|
||||
if (binaryData === undefined) {
|
||||
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
|
||||
}
|
||||
|
||||
attachments.push(await twistApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
'/attachments/upload',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
formData: {
|
||||
file_name: {
|
||||
value: Buffer.from(binaryData.data, BINARY_ENCODING),
|
||||
options: {
|
||||
filename: binaryData.fileName,
|
||||
},
|
||||
},
|
||||
attachment_id: uuid(),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
body.attachments = attachments;
|
||||
}
|
||||
|
||||
if (body.direct_mentions) {
|
||||
const directMentions: string[] = [];
|
||||
for (const directMention of body.direct_mentions as number[]) {
|
||||
directMentions.push(`[name](twist-mention://${directMention})`);
|
||||
}
|
||||
body.content = `${directMentions.join(' ')} ${body.content}`;
|
||||
}
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/threads/add', body);
|
||||
}
|
||||
//https://developer.twist.com/v3/#remove-thread
|
||||
if (operation === 'delete') {
|
||||
qs.id = this.getNodeParameter('threadId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/threads/remove', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#get-thread
|
||||
if (operation === 'get') {
|
||||
qs.id = this.getNodeParameter('threadId', i) as string;
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'GET', '/threads/getone', {}, qs);
|
||||
}
|
||||
//https://developer.twist.com/v3/#get-all-threads
|
||||
if (operation === 'getAll') {
|
||||
const channelId = this.getNodeParameter('channelId', i) as string;
|
||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||
const filters = this.getNodeParameter('filters', i) as IDataObject;
|
||||
qs.channel_id = channelId;
|
||||
|
||||
Object.assign(qs, filters);
|
||||
if (!returnAll) {
|
||||
qs.limit = this.getNodeParameter('limit', i) as number;
|
||||
}
|
||||
if (qs.older_than_ts) {
|
||||
qs.older_than_ts = moment(qs.older_than_ts as string).unix();
|
||||
}
|
||||
if (qs.newer_than_ts) {
|
||||
qs.newer_than_ts = moment(qs.newer_than_ts as string).unix();
|
||||
}
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'GET', '/threads/get', {}, qs);
|
||||
if (qs.as_ids) {
|
||||
responseData = (responseData as Array<number>).map(id => ({ ID: id }));
|
||||
}
|
||||
}
|
||||
//https://developer.twist.com/v3/#update-thread
|
||||
if (operation === 'update') {
|
||||
const threadId = this.getNodeParameter('threadId', i) as string;
|
||||
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
|
||||
const body: IDataObject = {
|
||||
id: threadId,
|
||||
};
|
||||
Object.assign(body, updateFields);
|
||||
|
||||
if (body.actionsUi) {
|
||||
const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[];
|
||||
|
||||
if (actions) {
|
||||
body.actions = actions;
|
||||
delete body.actionsUi;
|
||||
}
|
||||
}
|
||||
|
||||
if (body.binaryProperties) {
|
||||
const binaryProperties = (body.binaryProperties as string).split(',') as string[];
|
||||
|
||||
const attachments: IDataObject[] = [];
|
||||
|
||||
for (const binaryProperty of binaryProperties) {
|
||||
|
||||
const item = items[i].binary as IBinaryKeyData;
|
||||
|
||||
const binaryData = item[binaryProperty] as IBinaryData;
|
||||
|
||||
if (binaryData === undefined) {
|
||||
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
|
||||
}
|
||||
|
||||
attachments.push(await twistApiRequest.call(
|
||||
this,
|
||||
'POST',
|
||||
'/attachments/upload',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
formData: {
|
||||
file_name: {
|
||||
value: Buffer.from(binaryData.data, BINARY_ENCODING),
|
||||
options: {
|
||||
filename: binaryData.fileName,
|
||||
},
|
||||
},
|
||||
attachment_id: uuid(),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
body.attachments = attachments;
|
||||
}
|
||||
|
||||
if (body.direct_mentions) {
|
||||
const directMentions: string[] = [];
|
||||
for (const directMention of body.direct_mentions as number[]) {
|
||||
directMentions.push(`[name](twist-mention://${directMention})`);
|
||||
}
|
||||
body.content = `${directMentions.join(' ')} ${body.content}`;
|
||||
}
|
||||
|
||||
responseData = await twistApiRequest.call(this, 'POST', '/threads/update', body);
|
||||
}
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
|
|
Loading…
Reference in a new issue