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 = [
|
const scopes = [
|
||||||
'attachments:write',
|
'attachments:write',
|
||||||
'channels:remove',
|
'channels:remove',
|
||||||
|
'comments:remove',
|
||||||
'messages:remove',
|
'messages:remove',
|
||||||
|
'threads:remove',
|
||||||
'workspaces:read',
|
'workspaces:read',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,21 @@ export const channelOperations = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Archive',
|
||||||
|
value: 'archive',
|
||||||
|
description: 'Archive a channel',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Create',
|
name: 'Create',
|
||||||
value: 'create',
|
value: 'create',
|
||||||
description: 'Initiates a public or private channel-based conversation',
|
description: 'Initiates a public or private channel-based conversation',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Delete',
|
||||||
|
value: 'delete',
|
||||||
|
description: 'Delete a channel',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Get',
|
name: 'Get',
|
||||||
value: 'get',
|
value: 'get',
|
||||||
|
@ -30,6 +40,11 @@ export const channelOperations = [
|
||||||
value: 'getAll',
|
value: 'getAll',
|
||||||
description: 'Get all channels',
|
description: 'Get all channels',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Unarchive',
|
||||||
|
value: 'unarchive',
|
||||||
|
description: 'Unarchive a channel',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Update',
|
name: 'Update',
|
||||||
value: 'update',
|
value: 'update',
|
||||||
|
@ -64,7 +79,7 @@ export const channelFields = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: true,
|
required: true,
|
||||||
description: 'The id of the workspace.',
|
description: 'The ID of the workspace.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Name',
|
displayName: 'Name',
|
||||||
|
@ -156,28 +171,28 @@ export const channelFields = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
default: 0,
|
default: 0,
|
||||||
description: 'The color of the channel',
|
description: 'The color of the channel.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Description',
|
displayName: 'Description',
|
||||||
name: 'description',
|
name: 'description',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The description of the channel',
|
description: 'The description of the channel.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Public',
|
displayName: 'Public',
|
||||||
name: 'public',
|
name: 'public',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
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',
|
displayName: 'Temp ID',
|
||||||
name: 'temp_id',
|
name: 'temp_id',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
default: -1,
|
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',
|
displayName: 'User IDs',
|
||||||
|
@ -194,8 +209,9 @@ export const channelFields = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* channel:get */
|
/* channel:get/archive/unarchive/delete */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
displayName: 'Channel ID',
|
displayName: 'Channel ID',
|
||||||
|
@ -205,7 +221,10 @@ export const channelFields = [
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
operation: [
|
operation: [
|
||||||
|
'archive',
|
||||||
|
'delete',
|
||||||
'get',
|
'get',
|
||||||
|
'unarchive',
|
||||||
],
|
],
|
||||||
resource: [
|
resource: [
|
||||||
'channel',
|
'channel',
|
||||||
|
@ -213,8 +232,9 @@ export const channelFields = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: true,
|
required: true,
|
||||||
description: 'The ID of the channel',
|
description: 'The ID of the channel.',
|
||||||
},
|
},
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* channel:getAll */
|
/* channel:getAll */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
@ -302,7 +322,7 @@ export const channelFields = [
|
||||||
name: 'archived',
|
name: 'archived',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
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,
|
default: 0,
|
||||||
description: 'The color of the channel',
|
description: 'The color of the channel.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Description',
|
displayName: 'Description',
|
||||||
name: 'description',
|
name: 'description',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The description of the channel',
|
description: 'The description of the channel.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Name',
|
displayName: 'Name',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The name of the channel',
|
description: 'The name of the channel.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Public',
|
displayName: 'Public',
|
||||||
name: 'public',
|
name: 'public',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
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',
|
value: 'create',
|
||||||
description: 'Create a message in a conversation',
|
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',
|
default: 'create',
|
||||||
description: 'The operation to perform.',
|
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',
|
displayName: 'Additional Fields',
|
||||||
|
@ -108,7 +128,7 @@ export const messageConversationFields = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: {},
|
default: {},
|
||||||
description: 'Other options to set',
|
description: 'Other options to set.',
|
||||||
placeholder: 'Add options',
|
placeholder: 'Add options',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
@ -128,7 +148,7 @@ export const messageConversationFields = [
|
||||||
displayName: 'Action',
|
displayName: 'Action',
|
||||||
name: 'action',
|
name: 'action',
|
||||||
type: 'options',
|
type: 'options',
|
||||||
description: 'The action of the button',
|
description: 'The action of the button.',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: 'Open URL',
|
name: 'Open URL',
|
||||||
|
@ -171,7 +191,7 @@ export const messageConversationFields = [
|
||||||
displayName: 'Type',
|
displayName: 'Type',
|
||||||
name: 'type',
|
name: 'type',
|
||||||
type: 'options',
|
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: [
|
options: [
|
||||||
{
|
{
|
||||||
name: 'Action',
|
name: 'Action',
|
||||||
|
@ -191,7 +211,7 @@ export const messageConversationFields = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
description: 'URL to redirect',
|
description: 'URL to redirect.',
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -213,7 +233,7 @@ export const messageConversationFields = [
|
||||||
loadOptionsMethod: 'getUsers',
|
loadOptionsMethod: 'getUsers',
|
||||||
},
|
},
|
||||||
default: [],
|
default: [],
|
||||||
description: `The users that are directly mentioned`,
|
description: 'The users that are directly mentioned.',
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// displayName: 'Direct Group Mentions ',
|
// displayName: 'Direct Group Mentions ',
|
||||||
|
@ -223,8 +243,289 @@ export const messageConversationFields = [
|
||||||
// loadOptionsMethod: 'getGroups',
|
// loadOptionsMethod: 'getGroups',
|
||||||
// },
|
// },
|
||||||
// default: [],
|
// 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[];
|
] 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,
|
messageConversationOperations,
|
||||||
} from './MessageConversationDescription';
|
} from './MessageConversationDescription';
|
||||||
|
|
||||||
|
import {
|
||||||
|
threadFields,
|
||||||
|
threadOperations
|
||||||
|
} from './ThreadDescription';
|
||||||
|
import {
|
||||||
|
commentFields,
|
||||||
|
commentOperations
|
||||||
|
} from './CommentDescription';
|
||||||
import uuid = require('uuid');
|
import uuid = require('uuid');
|
||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
export class Twist implements INodeType {
|
export class Twist implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
|
@ -62,18 +71,30 @@ export class Twist implements INodeType {
|
||||||
name: 'Channel',
|
name: 'Channel',
|
||||||
value: 'channel',
|
value: 'channel',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Comment',
|
||||||
|
value: 'comment',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Message Conversation',
|
name: 'Message Conversation',
|
||||||
value: 'messageConversation',
|
value: 'messageConversation',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Thread',
|
||||||
|
value: 'thread',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
default: 'messageConversation',
|
default: 'messageConversation',
|
||||||
description: 'The resource to operate on.',
|
description: 'The resource to operate on.',
|
||||||
},
|
},
|
||||||
...channelOperations,
|
...channelOperations,
|
||||||
...channelFields,
|
...channelFields,
|
||||||
|
...commentOperations,
|
||||||
|
...commentFields,
|
||||||
...messageConversationOperations,
|
...messageConversationOperations,
|
||||||
...messageConversationFields,
|
...messageConversationFields,
|
||||||
|
...threadOperations,
|
||||||
|
...threadFields,
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,10 +190,15 @@ export class Twist implements INodeType {
|
||||||
|
|
||||||
responseData = await twistApiRequest.call(this, 'POST', '/channels/add', body);
|
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
|
//https://developer.twist.com/v3/#get-channel
|
||||||
if (operation === 'get') {
|
if (operation === 'get') {
|
||||||
const channelId = this.getNodeParameter('channelId', i) as string;
|
qs.id = this.getNodeParameter('channelId', i) as string;
|
||||||
qs.id = channelId;
|
|
||||||
|
|
||||||
responseData = await twistApiRequest.call(this, 'GET', '/channels/getone', {}, qs);
|
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);
|
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') {
|
if (resource === 'messageConversation') {
|
||||||
//https://developer.twist.com/v3/#add-message-to-conversation
|
//https://developer.twist.com/v3/#add-message-to-conversation
|
||||||
|
@ -244,7 +454,7 @@ export class Twist implements INodeType {
|
||||||
attachments.push(await twistApiRequest.call(
|
attachments.push(await twistApiRequest.call(
|
||||||
this,
|
this,
|
||||||
'POST',
|
'POST',
|
||||||
`/attachments/upload`,
|
'/attachments/upload',
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
|
@ -265,11 +475,11 @@ export class Twist implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.direct_mentions) {
|
if (body.direct_mentions) {
|
||||||
const direcMentions: string[] = [];
|
const directMentions: string[] = [];
|
||||||
for (const directMention of body.direct_mentions as number[]) {
|
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) {
|
// if (body.direct_group_mentions) {
|
||||||
|
@ -282,6 +492,266 @@ export class Twist implements INodeType {
|
||||||
|
|
||||||
responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/add', body);
|
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)) {
|
if (Array.isArray(responseData)) {
|
||||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||||
|
|
Loading…
Reference in a new issue