Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../..';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
|
||||
export const createClickupChannelInSpaceFolderOrList = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_channel_in_space_folder_list',
|
||||
description:
|
||||
'Creates a channel in a ClickUp workspace in a space, folder or list',
|
||||
displayName: 'Create Channel in Space/Folder/List',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
description: Property.ShortText({
|
||||
description: 'Description of the channel',
|
||||
displayName: 'Channel Description',
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
}),
|
||||
topic: Property.ShortText({
|
||||
description: 'Topic of the channel',
|
||||
displayName: 'Channel Topic',
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
}),
|
||||
locationType: Property.StaticDropdown({
|
||||
description: 'Type of location',
|
||||
displayName: 'Location Type',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Folder', value: 'folder' },
|
||||
{ label: 'Space', value: 'space' },
|
||||
{ label: 'List', value: 'list' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'folder',
|
||||
}),
|
||||
locationId: Property.ShortText({
|
||||
description: 'ID of the location',
|
||||
displayName: 'Location ID',
|
||||
required: true,
|
||||
}),
|
||||
// TODO: add user ids
|
||||
visibility: Property.StaticDropdown({
|
||||
description: 'Visibility of the channel',
|
||||
displayName: 'Channel Visibility',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Public', value: 'PUBLIC' },
|
||||
{ label: 'Private', value: 'PRIVATE' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'public',
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, description, visibility, locationType, locationId,topic } =
|
||||
configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.POST,
|
||||
`workspaces/${workspace_id}/chat/channels/location`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
topic,
|
||||
description,
|
||||
visibility,
|
||||
location: {
|
||||
id: locationId,
|
||||
type: locationType,
|
||||
},
|
||||
},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
|
||||
export const createClickupChannel = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_channel',
|
||||
description: 'Creates a channel in a ClickUp workspace',
|
||||
displayName: 'Create Channel',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
name: Property.ShortText({
|
||||
description: 'Name of the channel',
|
||||
displayName: 'Channel Name',
|
||||
required: true,
|
||||
defaultValue: '',
|
||||
}),
|
||||
description: Property.ShortText({
|
||||
description: 'Description of the channel',
|
||||
displayName: 'Channel Description',
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
}),
|
||||
topic: Property.ShortText({
|
||||
description: 'Topic of the channel',
|
||||
displayName: 'Channel Topic',
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
}),
|
||||
// TODO: add user ids
|
||||
visibility: Property.StaticDropdown({
|
||||
description: 'Visibility of the channel',
|
||||
displayName: 'Channel Visibility',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Public', value: 'PUBLIC' },
|
||||
{ label: 'Private', value: 'PRIVATE' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'public',
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, name, description, visibility,topic } =
|
||||
configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.POST,
|
||||
`workspaces/${workspace_id}/chat/channels`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
name,
|
||||
topic,
|
||||
description,
|
||||
visibility,
|
||||
},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupMessageReaction = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_message_reaction',
|
||||
description: 'Creates a reaction to a message in a ClickUp channel',
|
||||
displayName: 'Create Message Reaction',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
message_id: Property.ShortText({
|
||||
description: 'ID of the message to create reaction for',
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
}),
|
||||
emoji: Property.ShortText({
|
||||
description: 'Emoji to react with',
|
||||
displayName: 'Emoji',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, message_id, emoji } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.POST,
|
||||
`workspaces/${workspace_id}/chat/messages/${message_id}/reactions`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{ emoji },
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupMessageReply = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_message_reply',
|
||||
description: 'Creates a reply to a message in a ClickUp channel',
|
||||
displayName: 'Create Message Reply',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
message_id: Property.ShortText({
|
||||
description: 'ID of the message to reply to',
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
}),
|
||||
content: Property.LongText({
|
||||
description: 'Content of the message',
|
||||
displayName: 'Message Content',
|
||||
required: true,
|
||||
}),
|
||||
type: Property.StaticDropdown({
|
||||
description: 'Type of the message',
|
||||
displayName: 'Message Type',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Message', value: 'message' },
|
||||
{ label: 'Post', value: 'post' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'message',
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, message_id, content, type } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.POST,
|
||||
`workspaces/${workspace_id}/chat/messages/${message_id}/replies`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
content,
|
||||
type,
|
||||
},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupMessage = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_message',
|
||||
description: 'Creates a message in a ClickUp channel',
|
||||
displayName: 'Create Message',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
channel_id: clickupCommon.channel_id(),
|
||||
content: Property.LongText({
|
||||
description: 'Content of the message',
|
||||
displayName: 'Message Content',
|
||||
required: true,
|
||||
}),
|
||||
type: Property.StaticDropdown({
|
||||
description: 'Type of the message',
|
||||
displayName: 'Message Type',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Message', value: 'message' },
|
||||
{ label: 'Post', value: 'post' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'message',
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, channel_id, content, type } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.POST,
|
||||
`workspaces/${workspace_id}/chat/channels/${channel_id}/messages`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
content,
|
||||
type,
|
||||
},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const deleteClickupMessageReaction = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'delete_message_reaction',
|
||||
description: 'Deletes a reaction from a message in a ClickUp channel',
|
||||
displayName: 'Delete Message Reaction',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
message_id: Property.ShortText({
|
||||
description: 'ID of the message to delete reaction from',
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
}),
|
||||
reaction_id: Property.ShortText({
|
||||
description: 'ID of the reaction to delete',
|
||||
displayName: 'Reaction ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, message_id, reaction_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.DELETE,
|
||||
`workspaces/${workspace_id}/chat/messages/${message_id}/reactions/${reaction_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const deleteClickupMessage = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'delete_message',
|
||||
description: 'Deletes a message in a ClickUp channel',
|
||||
displayName: 'Delete Message',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
message_id: Property.ShortText({
|
||||
description: 'ID of the message to delete',
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, message_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.DELETE,
|
||||
`workspaces/${workspace_id}/chat/messages/${message_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
HttpMethod,
|
||||
getAccessTokenOrThrow,
|
||||
propsValidation,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
import { z } from 'zod';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
|
||||
export const getClickupChannelMessages = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_channel_messages',
|
||||
description: 'Gets all messages in a ClickUp channel',
|
||||
displayName: 'Get Channel Messages',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
channel_id: clickupCommon.channel_id(),
|
||||
limit: Property.Number({
|
||||
description: 'Limit the number of messages returned',
|
||||
displayName: 'Limit',
|
||||
required: false,
|
||||
defaultValue: 50,
|
||||
}),
|
||||
content_format: Property.StaticDropdown({
|
||||
description: 'Format the content of the messages',
|
||||
displayName: 'Format Content',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Markdown', value: 'text/md' },
|
||||
{ label: 'Plain Text', value: 'text/plain' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'text/md',
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
await propsValidation.validateZod(configValue.propsValue, {
|
||||
limit: z
|
||||
.number()
|
||||
.min(0)
|
||||
.max(100, 'You can fetch between 1 and 100 messages'),
|
||||
});
|
||||
|
||||
const { workspace_id, channel_id, limit, content_format } =
|
||||
configValue.propsValue;
|
||||
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.GET,
|
||||
`workspaces/${workspace_id}/chat/channels/${channel_id}/messages`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
undefined,
|
||||
{
|
||||
limit,
|
||||
content_format,
|
||||
}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupChannel = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_channel',
|
||||
description: 'Gets a channel in a ClickUp workspace',
|
||||
displayName: 'Get Channel',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
channel_id: clickupCommon.channel_id(),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, channel_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.GET,
|
||||
`workspaces/${workspace_id}/chat/channels/${channel_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
undefined,
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
HttpMethod,
|
||||
getAccessTokenOrThrow,
|
||||
propsValidation,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const getClickupChannels = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_channels',
|
||||
description: 'Gets all channels in a ClickUp workspace',
|
||||
displayName: 'Get Channels',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
include_hidden: Property.Checkbox({
|
||||
description: 'Include hidden channels',
|
||||
displayName: 'Include Hidden',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
limit: Property.Number({
|
||||
description: 'Limit the number of channels returned',
|
||||
displayName: 'Limit',
|
||||
required: false,
|
||||
defaultValue: 50,
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
await propsValidation.validateZod(configValue.propsValue, {
|
||||
limit: z
|
||||
.number()
|
||||
.min(0)
|
||||
.max(100, 'You can fetch between 1 and 100 messages'),
|
||||
});
|
||||
|
||||
const { workspace_id, include_hidden, limit } = configValue.propsValue;
|
||||
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.GET,
|
||||
`workspaces/${workspace_id}/chat/channels`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
undefined,
|
||||
{
|
||||
limit,
|
||||
is_follower: false,
|
||||
include_hidden,
|
||||
}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupMessageReactions = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_message_reactions',
|
||||
description: 'Gets the reactions of a message in a ClickUp channel',
|
||||
displayName: 'Get Message Reactions',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
message_id: Property.ShortText({
|
||||
description: 'ID of the message to get reactions for',
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, message_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.GET,
|
||||
`workspaces/${workspace_id}/chat/messages/${message_id}/reactions`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupMessageReplies = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_message_replies',
|
||||
description: 'Gets the replies of a message in a ClickUp channel',
|
||||
displayName: 'Get Message Replies',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
message_id: Property.ShortText({
|
||||
description: 'ID of the message to get replies for',
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, message_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.GET,
|
||||
`workspaces/${workspace_id}/chat/messages/${message_id}/replies`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi3, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const updateClickupMessage = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'update_message',
|
||||
description: 'Updates a message in a ClickUp channel',
|
||||
displayName: 'Update Message',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
message_id: Property.ShortText({
|
||||
description: 'ID of the message to update',
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
}),
|
||||
content: Property.LongText({
|
||||
description: 'Content of the message',
|
||||
displayName: 'Message Content',
|
||||
required: true,
|
||||
}),
|
||||
content_format: Property.StaticDropdown({
|
||||
description: 'Format of the message content',
|
||||
displayName: 'Message Content Format',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Markdown', value: 'text/md' },
|
||||
{ label: 'Plain Text', value: 'text/plain' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const { workspace_id, message_id, content, content_format } = configValue.propsValue;
|
||||
const response = await callClickUpApi3(
|
||||
HttpMethod.PATCH,
|
||||
`workspaces/${workspace_id}/chat/messages/${message_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
content,
|
||||
content_format,
|
||||
},
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { clickupCommon, callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupTaskComment = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_task_comments',
|
||||
description: 'Creates a comment on a task in ClickUp',
|
||||
displayName: 'Create Task Comment',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
list_id: clickupCommon.list_id(),
|
||||
task_id: clickupCommon.task_id(),
|
||||
comment: Property.LongText({
|
||||
description: 'Comment to make on the task',
|
||||
displayName: 'Comment',
|
||||
required: true,
|
||||
}),
|
||||
assignee_id: clickupCommon.single_assignee_id(
|
||||
false,
|
||||
'Assignee Id',
|
||||
'ID of assignee for Task Comment'
|
||||
),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { task_id, comment } = configValue.propsValue;
|
||||
|
||||
let assignee_id = configValue.propsValue.assignee_id;
|
||||
|
||||
if (!assignee_id) {
|
||||
const user_request = await callClickUpApi(
|
||||
HttpMethod.GET,
|
||||
`/user`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{}
|
||||
);
|
||||
|
||||
if (user_request.body['user'] === undefined) {
|
||||
throw 'Please connect to your ClickUp account';
|
||||
}
|
||||
|
||||
assignee_id = user_request.body['user']['id'];
|
||||
}
|
||||
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.POST,
|
||||
`/task/${task_id}/comment`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
comment_text: comment,
|
||||
assignee: assignee_id,
|
||||
notify_all: true,
|
||||
}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupTaskComments = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_task_comments',
|
||||
description: 'Gets comments from a task in ClickUp',
|
||||
displayName: 'Get Task Comments',
|
||||
props: {
|
||||
task_id: Property.ShortText({
|
||||
description: 'The ID of the task to get',
|
||||
displayName: 'Task ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { task_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.GET,
|
||||
`/task/${task_id}/comment`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createAction } from "@activepieces/pieces-framework";
|
||||
import { getAccessTokenOrThrow } from "@activepieces/pieces-common";
|
||||
import { clickupCommon, listAccessibleCustomFields } from "../../common"
|
||||
import { clickupAuth } from "../../../";
|
||||
|
||||
export const getClickupAccessibleCustomFields = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_accessible_custom_fields',
|
||||
displayName: 'Get Accessible Custom Fields',
|
||||
description: 'View the Custom Fields available on tasks in a specific List.',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(true),
|
||||
space_id: clickupCommon.space_id(true),
|
||||
list_id: clickupCommon.list_id(true)
|
||||
},
|
||||
async run(configValue) {
|
||||
const { list_id } = configValue.propsValue;
|
||||
const auth = getAccessTokenOrThrow(configValue.auth)
|
||||
|
||||
return (await listAccessibleCustomFields(auth, list_id as unknown as string)).fields
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Property, createAction } from "@activepieces/pieces-framework";
|
||||
import { HttpMethod, getAccessTokenOrThrow } from "@activepieces/pieces-common";
|
||||
import { callClickUpApi, clickupCommon } from "../../common"
|
||||
import { clickupAuth } from "../../../";
|
||||
|
||||
export const setClickupCustomFieldValue = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'set_custom_fields_value',
|
||||
displayName: 'Set Custom Field Value',
|
||||
description: 'Add data to a Custom field on a task.',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(true),
|
||||
space_id: clickupCommon.space_id(true),
|
||||
list_id: clickupCommon.list_id(false),
|
||||
task_id: clickupCommon.task_id(true),
|
||||
field_id: clickupCommon.field_id(true),
|
||||
value: Property.LongText({
|
||||
displayName: "Value",
|
||||
description: "The new value to be set",
|
||||
required: true
|
||||
})
|
||||
},
|
||||
async run(configValue) {
|
||||
const { field_id, task_id, value } = configValue.propsValue;
|
||||
|
||||
const response = await callClickUpApi<Record<string, unknown>>(
|
||||
HttpMethod.POST,
|
||||
`task/${task_id}/field/${field_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{ value: value }
|
||||
);
|
||||
|
||||
return response.body
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { clickupCommon, callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupFolderlessList = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_folderless_list',
|
||||
description: 'Create a new folderless list in a ClickUp workspace and space',
|
||||
displayName: 'Create Folderless List',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
name: Property.ShortText({
|
||||
description: 'The name of the list to create',
|
||||
displayName: 'List Name',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { space_id, name } = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.POST,
|
||||
`space/${space_id}/list`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
name,
|
||||
}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupList = createAction({
|
||||
auth: clickupAuth,
|
||||
|
||||
name: 'get_list',
|
||||
description: 'Gets a list in a ClickUp',
|
||||
displayName: 'Get List',
|
||||
props: {
|
||||
list_id: Property.ShortText({
|
||||
description: 'The id of the list to get',
|
||||
displayName: 'List ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { list_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.GET,
|
||||
`list/${list_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
|
||||
import { callClickUpApi, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupSpace = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_space',
|
||||
description: 'Gets a space in a ClickUp',
|
||||
displayName: 'Get Space',
|
||||
props: {
|
||||
space_id: clickupCommon.space_id(),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { space_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.GET,
|
||||
`space/${space_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{}
|
||||
);
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { clickupCommon, callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
|
||||
export const getClickupSpaces = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_spaces',
|
||||
description: 'Gets spaces in a ClickUp workspace',
|
||||
displayName: 'Get Spaces',
|
||||
props: {
|
||||
team_id: clickupCommon.workspace_id(),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { team_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.GET,
|
||||
`team/${team_id}/space`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,213 @@
|
||||
import {
|
||||
OAuth2PropertyValue,
|
||||
Property,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { MarkdownVariant } from '@activepieces/shared';
|
||||
|
||||
import {
|
||||
clickupCommon,
|
||||
callClickUpApi,
|
||||
listAccessibleCustomFields,
|
||||
} from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupSubtask = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_subtask',
|
||||
description: 'Creates a subtask in ClickUp',
|
||||
displayName: 'Create Subtask',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
list_id: clickupCommon.list_id(),
|
||||
task_id: clickupCommon.task_id(),
|
||||
name: Property.ShortText({
|
||||
description: 'The name of the subtask to create',
|
||||
displayName: 'Subtask Name',
|
||||
required: true,
|
||||
}),
|
||||
status_id: clickupCommon.status_id(),
|
||||
priority_id: clickupCommon.priority_id(),
|
||||
assignee_id: clickupCommon.assignee_id(
|
||||
false,
|
||||
'Assignee Id',
|
||||
'ID of assignee for Clickup Subtask'
|
||||
),
|
||||
description: Property.LongText({
|
||||
description: 'The description of the subtask to create',
|
||||
displayName: 'Subtask Description',
|
||||
required: false,
|
||||
}),
|
||||
is_markdown: Property.Checkbox({
|
||||
description: 'Is the description in markdown format',
|
||||
displayName: 'Is Markdown',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
due_date: Property.DateTime({
|
||||
description: 'The due date of the subtask',
|
||||
displayName: 'Due Date',
|
||||
required: false,
|
||||
}),
|
||||
due_date_time: Property.Checkbox({
|
||||
description: 'Whether to include time in the due date',
|
||||
displayName: 'Due Date Time',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
start_date: Property.DateTime({
|
||||
description: 'The start date of the subtask',
|
||||
displayName: 'Start Date',
|
||||
required: false,
|
||||
}),
|
||||
start_date_time: Property.Checkbox({
|
||||
description: 'Whether to include time in the start date',
|
||||
displayName: 'Start Date Time',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
time_estimate: Property.Number({
|
||||
description: 'The time estimate for the subtask in milliseconds',
|
||||
displayName: 'Time Estimate',
|
||||
required: false,
|
||||
}),
|
||||
check_required_custom_fields: Property.Checkbox({
|
||||
description: 'Re-enable required custom fields validation for the subtask',
|
||||
displayName: 'Check Required Custom Fields',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
custom_fields_info: Property.MarkDown({
|
||||
value: `Select custom fields\n\nFor custom dropdown fields, choose a dropdown value based on the index (in the list, the first option is index 0, second is 1, third is 2, etc.)`,
|
||||
variant: MarkdownVariant.INFO,
|
||||
}),
|
||||
custom_fields: Property.DynamicProperties({
|
||||
auth: clickupAuth,
|
||||
displayName: 'Custom Fields',
|
||||
required: true,
|
||||
refreshers: ['list_id', 'auth'],
|
||||
props: async ({ list_id, auth }) => {
|
||||
if (!list_id || !auth) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Ensure `auth` is of the correct type
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
|
||||
// Fetch custom fields using clickupCommon
|
||||
const { fields: customFields } = await listAccessibleCustomFields(
|
||||
accessToken,
|
||||
list_id.toString()
|
||||
);
|
||||
|
||||
// Map custom fields to InputPropertyMap
|
||||
const dynamicProps: Record<string, any> = {};
|
||||
customFields.forEach((field) => {
|
||||
dynamicProps[field.id] = Property.ShortText({
|
||||
displayName: field.name,
|
||||
description: `Value for the custom field: ${field.name}`,
|
||||
required: false,
|
||||
});
|
||||
});
|
||||
|
||||
return dynamicProps;
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const {
|
||||
list_id,
|
||||
task_id,
|
||||
name,
|
||||
description,
|
||||
status_id,
|
||||
priority_id,
|
||||
assignee_id,
|
||||
is_markdown,
|
||||
due_date,
|
||||
due_date_time,
|
||||
start_date,
|
||||
start_date_time,
|
||||
time_estimate,
|
||||
check_required_custom_fields,
|
||||
custom_fields,
|
||||
} = configValue.propsValue;
|
||||
|
||||
type SubtaskData = {
|
||||
name: string;
|
||||
parent: string | undefined;
|
||||
status?: string | undefined | string[];
|
||||
priority?: number | undefined;
|
||||
assignees?: number[] | undefined;
|
||||
markdown_content?: string;
|
||||
description?: string;
|
||||
due_date?: number;
|
||||
due_date_time?: boolean;
|
||||
start_date?: number;
|
||||
start_date_time?: boolean;
|
||||
time_estimate?: number;
|
||||
check_required_custom_fields?: boolean;
|
||||
custom_fields?: { id: string; value: any }[];
|
||||
};
|
||||
|
||||
const data: SubtaskData = {
|
||||
name,
|
||||
parent: task_id, // Parent task ID for the subtask
|
||||
status: status_id,
|
||||
priority: priority_id,
|
||||
assignees: assignee_id,
|
||||
};
|
||||
|
||||
// Add description or markdown content
|
||||
if (is_markdown && description) {
|
||||
data.markdown_content = description;
|
||||
} else if (description) {
|
||||
data.description = description;
|
||||
}
|
||||
|
||||
// Convert due_date to integer format and add it
|
||||
if (due_date) {
|
||||
data.due_date = new Date(due_date).getTime();
|
||||
data.due_date_time = due_date_time || false;
|
||||
}
|
||||
|
||||
// Convert start_date to integer format and add it
|
||||
if (start_date) {
|
||||
data.start_date = new Date(start_date).getTime();
|
||||
data.start_date_time = start_date_time || false;
|
||||
}
|
||||
|
||||
// Add time estimate
|
||||
if (time_estimate) {
|
||||
data.time_estimate = time_estimate;
|
||||
}
|
||||
|
||||
// Add check_required_custom_fields
|
||||
if (check_required_custom_fields) {
|
||||
data.check_required_custom_fields = check_required_custom_fields;
|
||||
}
|
||||
|
||||
// Map custom_fields into the required format
|
||||
if (custom_fields) {
|
||||
data.custom_fields = Object.entries(custom_fields).map(
|
||||
([fieldId, value]) => ({
|
||||
id: fieldId,
|
||||
value,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// Make the API request
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.POST,
|
||||
`list/${list_id}/task`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
data
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
|
||||
import { clickupCommon, callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupTaskFromTemplate = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_task_from_template',
|
||||
description: 'Create a new task from Template',
|
||||
displayName: 'Create Task From Template',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
list_id: clickupCommon.list_id(),
|
||||
template_id: clickupCommon.template_id(true),
|
||||
name: Property.ShortText({
|
||||
description: 'The name of the task to create',
|
||||
displayName: 'Task Name',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { list_id, name, template_id } = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.POST,
|
||||
`list/${list_id}/taskTemplate/${template_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
name,
|
||||
}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,209 @@
|
||||
import {
|
||||
OAuth2PropertyValue,
|
||||
Property,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { MarkdownVariant } from '@activepieces/shared';
|
||||
|
||||
import {
|
||||
clickupCommon,
|
||||
callClickUpApi,
|
||||
listAccessibleCustomFields,
|
||||
} from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const createClickupTask = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'create_task',
|
||||
description: 'Create a new task in a ClickUp workspace and list',
|
||||
displayName: 'Create Task',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
list_id: clickupCommon.list_id(),
|
||||
name: Property.ShortText({
|
||||
description: 'The name of task',
|
||||
displayName: 'Name',
|
||||
required: true,
|
||||
}),
|
||||
status_id: clickupCommon.status_id(),
|
||||
priority_id: clickupCommon.priority_id(),
|
||||
assignee_id: clickupCommon.assignee_id(
|
||||
false,
|
||||
'Assignee Id',
|
||||
'ID of assignee for Clickup Task'
|
||||
),
|
||||
description: Property.LongText({
|
||||
description: 'The description of task',
|
||||
displayName: 'Description',
|
||||
required: false,
|
||||
}),
|
||||
is_markdown: Property.Checkbox({
|
||||
description: 'Is the description in markdown format',
|
||||
displayName: 'Is Markdown',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
due_date: Property.DateTime({
|
||||
description: 'The due date of the task',
|
||||
displayName: 'Due Date',
|
||||
required: false,
|
||||
}),
|
||||
due_date_time: Property.Checkbox({
|
||||
description: 'Whether to include time in the due date',
|
||||
displayName: 'Due Date Time',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
start_date: Property.DateTime({
|
||||
description: 'The start date of the task',
|
||||
displayName: 'Start Date',
|
||||
required: false,
|
||||
}),
|
||||
start_date_time: Property.Checkbox({
|
||||
description: 'Whether to include time in the start date',
|
||||
displayName: 'Start Date Time',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
time_estimate: Property.Number({
|
||||
description: 'The time estimate for the task in milliseconds',
|
||||
displayName: 'Time Estimate',
|
||||
required: false,
|
||||
}),
|
||||
check_required_custom_fields: Property.Checkbox({
|
||||
description: 'Re-enable required custom fields validation for the task',
|
||||
displayName: 'Check Required Custom Fields',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
custom_fields_info: Property.MarkDown({
|
||||
value: `Select custom fields\n\nFor custom dropdown fields, choose a dropdown value based on the index (in the list, the first option is index 0, second is 1, third is 2, etc.)`,
|
||||
variant: MarkdownVariant.INFO,
|
||||
}),
|
||||
custom_fields: Property.DynamicProperties({
|
||||
auth: clickupAuth,
|
||||
displayName: 'Custom Fields',
|
||||
required: true,
|
||||
refreshers: ['list_id', 'auth'],
|
||||
props: async ({ list_id, auth }) => {
|
||||
if (!list_id || !auth) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Ensure `auth` is of the correct type
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
|
||||
// Fetch custom fields using clickupCommon
|
||||
const { fields: customFields } = await listAccessibleCustomFields(
|
||||
accessToken,
|
||||
list_id.toString()
|
||||
);
|
||||
|
||||
// Map custom fields to InputPropertyMap
|
||||
const dynamicProps: Record<string, any> = {};
|
||||
customFields.forEach((field) => {
|
||||
dynamicProps[field.id] = Property.ShortText({
|
||||
displayName: field.name,
|
||||
description: `Value for the custom field: ${field.name}`,
|
||||
required: false,
|
||||
});
|
||||
});
|
||||
|
||||
return dynamicProps;
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
async run(configValue) {
|
||||
const {
|
||||
list_id,
|
||||
name,
|
||||
description,
|
||||
status_id,
|
||||
priority_id,
|
||||
assignee_id,
|
||||
is_markdown,
|
||||
due_date,
|
||||
due_date_time,
|
||||
start_date,
|
||||
start_date_time,
|
||||
time_estimate,
|
||||
check_required_custom_fields,
|
||||
custom_fields,
|
||||
} = configValue.propsValue;
|
||||
|
||||
type TaskData = {
|
||||
name: string;
|
||||
status?: string | undefined | string[];
|
||||
priority?: number | undefined;
|
||||
assignees?: number[] | undefined;
|
||||
markdown_content?: string;
|
||||
description?: string;
|
||||
due_date?: number;
|
||||
due_date_time?: boolean;
|
||||
start_date?: number;
|
||||
start_date_time?: boolean;
|
||||
time_estimate?: number;
|
||||
check_required_custom_fields?: boolean;
|
||||
custom_fields?: { id: string; value: any }[];
|
||||
};
|
||||
|
||||
const data: TaskData = {
|
||||
name,
|
||||
status: status_id,
|
||||
priority: priority_id,
|
||||
assignees: assignee_id,
|
||||
};
|
||||
|
||||
// Add description or markdown content
|
||||
if (is_markdown && description) {
|
||||
data.markdown_content = description;
|
||||
} else if (description) {
|
||||
data.description = description;
|
||||
}
|
||||
|
||||
// Convert due_date to integer format and add it
|
||||
if (due_date) {
|
||||
data.due_date = new Date(due_date).getTime();
|
||||
data.due_date_time = due_date_time || false;
|
||||
}
|
||||
|
||||
// Convert start_date to integer format and add it
|
||||
if (start_date) {
|
||||
data.start_date = new Date(start_date).getTime();
|
||||
data.start_date_time = start_date_time || false;
|
||||
}
|
||||
|
||||
// Add time estimate
|
||||
if (time_estimate) {
|
||||
data.time_estimate = time_estimate;
|
||||
}
|
||||
|
||||
// Add check_required_custom_fields
|
||||
if (check_required_custom_fields) {
|
||||
data.check_required_custom_fields = check_required_custom_fields;
|
||||
}
|
||||
|
||||
// Map custom_fields into the required format
|
||||
if (custom_fields) {
|
||||
data.custom_fields = Object.entries(custom_fields).map(
|
||||
([fieldId, value]) => ({
|
||||
id: fieldId,
|
||||
value,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// Make the API request
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.POST,
|
||||
`list/${list_id}/task`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
data
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
|
||||
import { clickupCommon, callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const deleteClickupTask = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'delete_task',
|
||||
description: 'Delete a task in a workspace and list',
|
||||
displayName: 'Delete Task',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
list_id: clickupCommon.list_id(),
|
||||
task_id: clickupCommon.task_id()
|
||||
},
|
||||
async run(configValue) {
|
||||
const {
|
||||
task_id,
|
||||
} = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.DELETE,
|
||||
`task/${task_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
undefined
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import {
|
||||
OAuth2PropertyValue,
|
||||
Property,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import qs from 'qs';
|
||||
import { clickupAuth } from '../../..';
|
||||
import { callClickUpApi, clickupCommon, listTags } from '../../common';
|
||||
import { ClickupTask } from '../../common/models';
|
||||
|
||||
export const filterClickupWorkspaceTasks = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'list_workspace_tasks',
|
||||
displayName: 'List Team Tasks',
|
||||
description:
|
||||
'Retrieves the tasks that meet specific criteria from a Workspace.',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(true),
|
||||
space_id: clickupCommon.space_id(false, true),
|
||||
folder_id: clickupCommon.folder_id(false, true),
|
||||
list_id: clickupCommon.list_id(false, true),
|
||||
|
||||
assignees: clickupCommon.assignee_id(
|
||||
false,
|
||||
'Assignee Id',
|
||||
'ID of assignee for Clickup Task'
|
||||
),
|
||||
tags: Property.MultiSelectDropdown({
|
||||
auth: clickupAuth,
|
||||
displayName: 'Tags',
|
||||
description: 'The tags to filter for',
|
||||
refreshers: ['space_id', 'workspace_id'],
|
||||
required: false,
|
||||
options: async ({ auth, workspace_id, space_id }) => {
|
||||
if (!auth || !workspace_id || !space_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder:
|
||||
'connect your account first and select workspace and space',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
const response = await listTags(accessToken, space_id as string);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.tags.map((tag) => {
|
||||
return {
|
||||
label: tag.name,
|
||||
value: encodeURIComponent(tag.name),
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
page: Property.Number({
|
||||
displayName: 'Page',
|
||||
description: 'Page to fetch (starts at 0).',
|
||||
required: false,
|
||||
defaultValue: 0,
|
||||
}),
|
||||
reverse: Property.Checkbox({
|
||||
displayName: 'Reverse',
|
||||
description: 'Tasks are displayed in reverse order.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
include_closed: Property.Checkbox({
|
||||
displayName: 'Include Closed',
|
||||
description:
|
||||
'Include or exclude closed tasks. By default, they are excluded.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
order_by: Property.StaticDropdown({
|
||||
displayName: 'Order By',
|
||||
description:
|
||||
'Order by a particular field. By default, tasks are ordered by created.',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ value: 'id', label: 'Id' },
|
||||
{ value: 'created', label: 'Created at' },
|
||||
{ value: 'updated', label: 'Last updated' },
|
||||
{ value: 'due_date', label: 'Due date' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { list_id, folder_id, space_id, workspace_id, ...params } =
|
||||
configValue.propsValue;
|
||||
const auth = getAccessTokenOrThrow(configValue.auth);
|
||||
|
||||
const query: Record<string, unknown> = {
|
||||
assignees: params.assignees,
|
||||
tags: params.tags,
|
||||
page: params.page,
|
||||
reverse: params.reverse,
|
||||
include_closed: params.include_closed,
|
||||
order_by: params.order_by,
|
||||
};
|
||||
|
||||
if (list_id) query['list_ids'] = list_id;
|
||||
if (folder_id) query['project_ids'] = folder_id;
|
||||
if (space_id) query['space_ids'] = space_id;
|
||||
|
||||
return (
|
||||
await callClickUpApi<ClickupTask>(
|
||||
HttpMethod.GET,
|
||||
`team/${workspace_id}/task?${decodeURIComponent(qs.stringify(query))}`,
|
||||
auth,
|
||||
undefined,
|
||||
undefined,
|
||||
{
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
)
|
||||
).body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,94 @@
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import dayjs from 'dayjs';
|
||||
import qs from 'qs';
|
||||
import { clickupAuth } from '../../..';
|
||||
import { callClickUpApi, clickupCommon } from '../../common';
|
||||
import { ClickupTask } from '../../common/models';
|
||||
|
||||
export const filterClickupWorkspaceTimeEntries = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'list_workspace_time_entries',
|
||||
displayName: 'List Time Entries',
|
||||
description: 'Retrieves time entries filtered by start and end date.',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(true),
|
||||
|
||||
start_date: Property.DateTime({
|
||||
displayName: 'Start date',
|
||||
description: '',
|
||||
required: false,
|
||||
}),
|
||||
end_date: Property.DateTime({
|
||||
displayName: 'End date',
|
||||
required: false,
|
||||
}),
|
||||
|
||||
space_id: clickupCommon.space_id(false),
|
||||
folder_id: clickupCommon.folder_id(false),
|
||||
list_id: clickupCommon.list_id(false),
|
||||
task_id: clickupCommon.task_id(false, 'Task'),
|
||||
|
||||
assignee: clickupCommon.assignee_id(
|
||||
false,
|
||||
'Assignee Id',
|
||||
'ID of assignee for Clickup Task'
|
||||
),
|
||||
|
||||
include_task_tags: Property.Checkbox({
|
||||
displayName: 'Include task tags',
|
||||
description:
|
||||
'Include task tags in the response for time entries associated with tasks.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
include_location_names: Property.Checkbox({
|
||||
displayName: 'Include location names',
|
||||
description:
|
||||
'Include the names of the List, Folder, and Space along with the list_id, folder_id, and space_id.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { task_id, list_id, folder_id, space_id, workspace_id, ...params } =
|
||||
context.propsValue;
|
||||
const auth = getAccessTokenOrThrow(context.auth);
|
||||
|
||||
const query: Record<string, unknown> = {
|
||||
assignee: params.assignee?.join(','),
|
||||
include_task_tags: params.include_task_tags,
|
||||
include_location_names: params.include_location_names,
|
||||
};
|
||||
|
||||
if (params.start_date)
|
||||
query['start_date'] = dayjs(params.start_date).valueOf();
|
||||
|
||||
if (params.end_date) query['end_date'] = dayjs(params.end_date).valueOf();
|
||||
|
||||
if (task_id) {
|
||||
query['task_id'] = task_id;
|
||||
} else if (list_id) {
|
||||
query['list_id'] = list_id;
|
||||
} else if (folder_id) {
|
||||
query['project_id'] = folder_id;
|
||||
} else if (space_id) {
|
||||
query['space_id'] = space_id;
|
||||
}
|
||||
|
||||
return (
|
||||
await callClickUpApi<ClickupTask>(
|
||||
HttpMethod.GET,
|
||||
`team/${workspace_id}/time_entries?${decodeURIComponent(
|
||||
qs.stringify(query)
|
||||
)}`,
|
||||
auth,
|
||||
undefined,
|
||||
undefined,
|
||||
{
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
)
|
||||
).body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi, clickupCommon } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupTaskByName = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_task_by_name',
|
||||
description: 'Fetches a task by name in a ClickUp list',
|
||||
displayName: 'Get Task by Name',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
list_id: clickupCommon.list_id(),
|
||||
task_name: Property.ShortText({
|
||||
description: 'The name of the task to find',
|
||||
displayName: 'Task Name',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { list_id, task_name } = configValue.propsValue;
|
||||
const accessToken = getAccessTokenOrThrow(configValue.auth);
|
||||
|
||||
let page = 0;
|
||||
const pageSize = 100;
|
||||
let hasMorePages = true;
|
||||
|
||||
while (hasMorePages) {
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.GET,
|
||||
`list/${list_id}/task`,
|
||||
accessToken,
|
||||
undefined,
|
||||
{ page, limit: pageSize }
|
||||
);
|
||||
|
||||
|
||||
const tasks = response.body.tasks;
|
||||
|
||||
if (!tasks || tasks.length === 0) {
|
||||
hasMorePages = false;
|
||||
break;
|
||||
}
|
||||
|
||||
const matchingTask = tasks.find((task: any) => task.name === task_name);
|
||||
|
||||
if (matchingTask) {
|
||||
return matchingTask;
|
||||
}
|
||||
|
||||
page++;
|
||||
}
|
||||
|
||||
throw new Error(`Task with name "${task_name}" not found in list "${list_id}".`);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const getClickupTask = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'get_list_task',
|
||||
description: 'Gets a task in a ClickUp list',
|
||||
displayName: 'Get Task',
|
||||
props: {
|
||||
task_id: Property.ShortText({
|
||||
description: 'The ID of the task to get',
|
||||
displayName: 'Task ID',
|
||||
required: true,
|
||||
}),
|
||||
include_subtasks: Property.Checkbox({
|
||||
description: 'Include subtasks in the response',
|
||||
displayName: 'Include Subtasks',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run(configValue) {
|
||||
const { task_id } = configValue.propsValue;
|
||||
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.GET,
|
||||
`task/${task_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
undefined
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
|
||||
import { clickupCommon, callClickUpApi } from '../../common';
|
||||
import { clickupAuth } from '../../../';
|
||||
|
||||
export const updateClickupTask = createAction({
|
||||
auth: clickupAuth,
|
||||
name: 'update_task',
|
||||
description: 'Update task in a ClickUp workspace and list',
|
||||
displayName: 'Update Task',
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(),
|
||||
space_id: clickupCommon.space_id(),
|
||||
list_id: clickupCommon.list_id(),
|
||||
task_id: clickupCommon.task_id(),
|
||||
name: Property.ShortText({
|
||||
description: 'The name of the task to update',
|
||||
displayName: 'Task Name',
|
||||
required: false,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
description: 'The description of the task to update',
|
||||
displayName: 'Task Description',
|
||||
required: false,
|
||||
}),
|
||||
status_id: clickupCommon.status_id(),
|
||||
priority_id: clickupCommon.priority_id(),
|
||||
add_assignee: clickupCommon.assignee_id(
|
||||
false,
|
||||
'Add Assignees',
|
||||
'assignee(s) you want to add for the task'
|
||||
),
|
||||
rem_assignee: clickupCommon.assignee_id(
|
||||
false,
|
||||
'Remove Assignees',
|
||||
'assignee(s) you want to remove from the task'
|
||||
),
|
||||
},
|
||||
async run(configValue) {
|
||||
const {
|
||||
task_id,
|
||||
name,
|
||||
description,
|
||||
status_id,
|
||||
priority_id,
|
||||
add_assignee,
|
||||
rem_assignee,
|
||||
} = configValue.propsValue;
|
||||
const response = await callClickUpApi(
|
||||
HttpMethod.PUT,
|
||||
`task/${task_id}`,
|
||||
getAccessTokenOrThrow(configValue.auth),
|
||||
{
|
||||
name: name,
|
||||
description: description,
|
||||
status: status_id,
|
||||
priority: priority_id,
|
||||
assignees: {
|
||||
add: add_assignee,
|
||||
rem: rem_assignee,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
## How to get a list ID
|
||||
|
||||
To obtain a list ID
|
||||
|
||||
1. Go to ClickUp application (https://app.clickup.com/) and select into a space and a list within the space
|
||||
2. In the URL bar, it should look something like this: https://app.clickup.com/2499706/v/l/li/901000754585
|
||||
3. Go ahead and copy the numbers after the final slash (/)
|
||||
|
||||
## How to get a space ID
|
||||
|
||||
To obtain a space ID
|
||||
|
||||
1. Go to ClickUp application (https://app.clickup.com/) and select into a space
|
||||
2. In the URL bar, it should look something like this: https://app.clickup.com/2499706/v/l/s/38651852
|
||||
3. Go ahead and copy the numbers after the final slash (/)
|
||||
|
||||
## How to get a Team ID
|
||||
|
||||
To obtain a team ID
|
||||
|
||||
1. Go to ClickUp application (https://app.clickup.com/)
|
||||
2. Select your preferred workspace (if you haven't already)
|
||||
3. In the URL bar, it should look something like this: https://app.clickup.com/2499706/home
|
||||
4. Copy the numbers just after the app.clickup.com (https://app.clickup.com/[COPY NUMBERS HERE]/home)
|
||||
|
||||
---
|
||||
|
||||
## Triggers
|
||||
|
||||
TRIGGERS
|
||||
|
||||
---
|
||||
|
||||
## Actions
|
||||
|
||||
ACTIONS
|
||||
@@ -0,0 +1,668 @@
|
||||
import { Property, OAuth2PropertyValue } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
getAccessTokenOrThrow,
|
||||
HttpMethod,
|
||||
HttpMessageBody,
|
||||
HttpResponse,
|
||||
httpClient,
|
||||
AuthenticationType,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { ClickupTask, ClickupWorkspace } from './models';
|
||||
import { clickupAuth } from '../..';
|
||||
|
||||
export const clickupCommon = {
|
||||
workspace_id: (required = true) =>
|
||||
Property.Dropdown({
|
||||
auth: clickupAuth,
|
||||
description: 'The ID of the ClickUp workspace',
|
||||
displayName: 'Workspace',
|
||||
required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = (
|
||||
await callClickUpApi<{
|
||||
teams: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, 'team', accessToken, undefined)
|
||||
).body;
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.teams.map((workspace) => {
|
||||
return {
|
||||
label: workspace.name,
|
||||
value: workspace.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
space_id: (required = true, multi = false) => {
|
||||
const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
|
||||
return Dropdown({
|
||||
auth: clickupAuth,
|
||||
description: 'The ID of the ClickUp space to create the task in',
|
||||
displayName: 'Space',
|
||||
required,
|
||||
refreshers: ['workspace_id'],
|
||||
options: async ({ auth, workspace_id }) => {
|
||||
if (!auth || !workspace_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first and select workspace',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await listSpaces(accessToken, workspace_id as string);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.spaces.map((space) => {
|
||||
return {
|
||||
label: space.name,
|
||||
value: space.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
list_id: (required = true, multi = false) => {
|
||||
const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
|
||||
return Dropdown({
|
||||
auth: clickupAuth,
|
||||
description: 'The ID of the ClickUp space to create the task in',
|
||||
displayName: 'List',
|
||||
required,
|
||||
refreshers: ['space_id', 'workspace_id', 'folder_id'],
|
||||
options: async ({ auth, space_id }) => {
|
||||
if (!auth || !space_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first and select a space',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const lists: { name: string; id: string }[] = await listAllLists(
|
||||
accessToken,
|
||||
space_id as string
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: lists.map((list) => {
|
||||
return {
|
||||
label: list.name,
|
||||
value: list.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
task_id: (required = true, label: string | undefined = undefined) =>
|
||||
Property.Dropdown({
|
||||
auth: clickupAuth,
|
||||
description: 'The ID of the ClickUp task',
|
||||
displayName: label ?? 'Task Id',
|
||||
required,
|
||||
defaultValue: null,
|
||||
refreshers: ['space_id', 'list_id', 'workspace_id', 'folder_id'],
|
||||
options: async ({ auth, space_id, list_id }) => {
|
||||
if (!auth || !list_id || !space_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder:
|
||||
'connect your account first and select workspace, space and list',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await listTasks(accessToken, list_id as string);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.tasks.map((task) => {
|
||||
return {
|
||||
label: task.name,
|
||||
value: task.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
folder_id: (required = false, multi = false) => {
|
||||
const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
|
||||
return Dropdown({
|
||||
auth: clickupAuth,
|
||||
description: 'The ID of the ClickUp folder',
|
||||
displayName: 'Folder Id',
|
||||
refreshers: ['space_id', 'workspace_id'],
|
||||
required,
|
||||
options: async ({ auth, space_id, workspace_id }) => {
|
||||
if (!auth || !workspace_id || !space_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder:
|
||||
'connect your account first and select workspace and space',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await listFolders(accessToken, space_id as string);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.folders.map((task) => {
|
||||
return {
|
||||
label: task.name,
|
||||
value: task.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
field_id: (required = false) =>
|
||||
Property.Dropdown({
|
||||
auth: clickupAuth,
|
||||
displayName: 'Field',
|
||||
description: 'The ID of the ClickUp custom field',
|
||||
refreshers: ['task_id', 'list_id'],
|
||||
defaultValue: null,
|
||||
required,
|
||||
options: async ({ auth, task_id, list_id }) => {
|
||||
if (!auth || !task_id || !list_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first and select a task',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await listAccessibleCustomFields(
|
||||
accessToken,
|
||||
list_id as string
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.fields.map((field) => {
|
||||
return {
|
||||
label: field.name,
|
||||
value: field.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
status_id: (required = false, multi = false) => {
|
||||
const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
|
||||
return Dropdown({
|
||||
auth: clickupAuth,
|
||||
description: 'The ID of Clickup Issue Status',
|
||||
displayName: 'Status Id',
|
||||
refreshers: ['list_id'],
|
||||
required,
|
||||
options: async ({ auth, list_id }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!list_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'select list',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await getStatuses(accessToken, list_id as string);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.statuses.map((status) => {
|
||||
return {
|
||||
label: status.status,
|
||||
value: status.status,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
priority_id: (required = false) =>
|
||||
Property.StaticDropdown({
|
||||
displayName: 'Priority Id',
|
||||
defaultValue: null,
|
||||
description: 'The ID of Clickup Issue Priority',
|
||||
required,
|
||||
options: {
|
||||
options: [
|
||||
{
|
||||
label: 'Urgent',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'High',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: 'Normal',
|
||||
value: 3,
|
||||
},
|
||||
{
|
||||
label: 'Low',
|
||||
value: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
assignee_id: (
|
||||
required = false,
|
||||
displayName = 'Assignee Id',
|
||||
description: string
|
||||
) =>
|
||||
Property.MultiSelectDropdown({
|
||||
auth: clickupAuth,
|
||||
displayName: displayName,
|
||||
description: description,
|
||||
required,
|
||||
refreshers: ['workspace_id'],
|
||||
options: async ({ auth, workspace_id }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!workspace_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'select workspace',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await listWorkspaceMembers(
|
||||
accessToken,
|
||||
workspace_id as string
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((member) => {
|
||||
return {
|
||||
label: member.user.username,
|
||||
value: member.user.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
single_assignee_id: (
|
||||
required = false,
|
||||
displayName = 'Assignee Id',
|
||||
description: string
|
||||
) =>
|
||||
Property.Dropdown({
|
||||
auth: clickupAuth,
|
||||
displayName: displayName,
|
||||
description: description,
|
||||
required,
|
||||
refreshers: ['workspace_id'],
|
||||
options: async ({ auth, workspace_id }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!workspace_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'select workspace',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await listWorkspaceMembers(
|
||||
accessToken,
|
||||
workspace_id as string
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((member) => {
|
||||
return {
|
||||
label: member.user.username,
|
||||
value: member.user.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
template_id: (required = false) =>
|
||||
Property.Dropdown({
|
||||
auth: clickupAuth,
|
||||
displayName: 'Template Id',
|
||||
required,
|
||||
description: 'The ID of Clickup Task Template',
|
||||
refreshers: ['workspace_id'],
|
||||
options: async ({ auth, workspace_id }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!workspace_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'select workspace',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
const response = await listWorkspaceTemplates(
|
||||
accessToken,
|
||||
workspace_id as string
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.templates.map((template) => {
|
||||
return {
|
||||
label: template.name,
|
||||
value: template.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
channel_id: (required = false) =>
|
||||
Property.Dropdown({
|
||||
auth: clickupAuth,
|
||||
displayName: 'Channel Id',
|
||||
required,
|
||||
description: 'The ID of Clickup Channel',
|
||||
refreshers: ['workspace_id'],
|
||||
options: async ({ auth, workspace_id }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'connect your account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!workspace_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'select workspace',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const accessToken = getAccessTokenOrThrow(auth);
|
||||
const response = await retrieveChannels(
|
||||
accessToken,
|
||||
workspace_id as string
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.data
|
||||
.filter((channel) => channel.name && channel.name !== '')
|
||||
.map((channel) => {
|
||||
return {
|
||||
label: channel.name,
|
||||
value: channel.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
async function listWorkspaces(accessToken: string) {
|
||||
return (
|
||||
await callClickUpApi<{ teams: ClickupWorkspace[] }>(
|
||||
HttpMethod.GET,
|
||||
'team',
|
||||
accessToken,
|
||||
undefined
|
||||
)
|
||||
).body;
|
||||
}
|
||||
|
||||
async function getWorkspace(accessToken: string, workspaceId: string) {
|
||||
const { teams } = await listWorkspaces(accessToken as string);
|
||||
const workspace = teams.filter((workspace) => workspace.id === workspaceId);
|
||||
return workspace[0];
|
||||
}
|
||||
|
||||
async function listWorkspaceMembers(accessToken: string, workspaceId: string) {
|
||||
const workspace = await getWorkspace(accessToken, workspaceId);
|
||||
return workspace.members;
|
||||
}
|
||||
|
||||
async function listWorkspaceTemplates(
|
||||
accessToken: string,
|
||||
workspaceId: string
|
||||
) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
templates: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(
|
||||
HttpMethod.GET,
|
||||
`team/${workspaceId}/taskTemplate`,
|
||||
accessToken,
|
||||
undefined
|
||||
)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function listSpaces(accessToken: string, workspaceId: string) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
spaces: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `team/${workspaceId}/space`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function listAllLists(accessToken: string, spaceId: string) {
|
||||
const responseFolders = await listFolders(accessToken, spaceId as string);
|
||||
const promises: Promise<{ lists: { id: string; name: string }[] }>[] = [
|
||||
listFolderlessList(accessToken, spaceId as string),
|
||||
];
|
||||
for (let i = 0; i < responseFolders.folders.length; ++i) {
|
||||
promises.push(listLists(accessToken, responseFolders.folders[i].id));
|
||||
}
|
||||
const listsResponses = await Promise.all(promises);
|
||||
|
||||
let lists: { name: string; id: string }[] = [];
|
||||
for (let i = 0; i < listsResponses.length; ++i) {
|
||||
lists = [...lists, ...listsResponses[i].lists];
|
||||
}
|
||||
|
||||
return lists;
|
||||
}
|
||||
|
||||
export async function listLists(accessToken: string, folderId: string) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
lists: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `folder/${folderId}/list`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
async function getStatuses(accessToken: string, listId: string) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
statuses: {
|
||||
id: string;
|
||||
status: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `list/${listId}`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function listFolders(accessToken: string, spaceId: string) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
folders: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `space/${spaceId}/folder`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function listAccessibleCustomFields(
|
||||
accessToken: string,
|
||||
listId: string
|
||||
) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
fields: {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
type_config: Record<string, unknown>;
|
||||
date_created: string;
|
||||
hide_from_guests: false;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `list/${listId}/field`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
|
||||
async function listFolderlessList(accessToken: string, spaceId: string) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
lists: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `space/${spaceId}/list`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function listTags(accessToken: string, spaceId: string) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
tags: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `space/${spaceId}/tag`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function listTasks(accessToken: string, listId: string) {
|
||||
return (
|
||||
await callClickUpApi<{
|
||||
tasks: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(HttpMethod.GET, `list/${listId}/task`, accessToken, undefined)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function retrieveChannels(
|
||||
accessToken: string,
|
||||
workspaceId: string
|
||||
) {
|
||||
return (
|
||||
await callClickUpApi3<{
|
||||
data: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}>(
|
||||
HttpMethod.GET,
|
||||
`workspaces/${workspaceId}/chat/channels`,
|
||||
accessToken,
|
||||
undefined
|
||||
)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function callClickupGetTask(accessToken: string, taskId: string) {
|
||||
return (
|
||||
await callClickUpApi<ClickupTask>(
|
||||
HttpMethod.GET,
|
||||
`task/${taskId}`,
|
||||
accessToken,
|
||||
undefined
|
||||
)
|
||||
).body;
|
||||
}
|
||||
|
||||
export async function callClickUpApi<T extends HttpMessageBody = any>(
|
||||
method: HttpMethod,
|
||||
apiUrl: string,
|
||||
accessToken: string,
|
||||
body: any | undefined,
|
||||
queryParams: any | undefined = undefined,
|
||||
headers: any | undefined = undefined
|
||||
): Promise<HttpResponse<T>> {
|
||||
headers = {
|
||||
accept: 'application/json',
|
||||
...headers,
|
||||
};
|
||||
|
||||
return await httpClient.sendRequest<T>({
|
||||
method: method,
|
||||
url: `https://api.clickup.com/api/v2/${apiUrl}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: accessToken,
|
||||
},
|
||||
headers,
|
||||
body: method === 'GET' ? undefined : body,
|
||||
queryParams,
|
||||
});
|
||||
}
|
||||
|
||||
export async function callClickUpApi3<T extends HttpMessageBody = any>(
|
||||
method: HttpMethod,
|
||||
apiUrl: string,
|
||||
accessToken: string,
|
||||
body: any | undefined,
|
||||
queryParams: any | undefined = undefined,
|
||||
headers: any | undefined = {}
|
||||
): Promise<HttpResponse<T>> {
|
||||
headers = {
|
||||
accept: 'application/json',
|
||||
...headers,
|
||||
};
|
||||
|
||||
return await httpClient.sendRequest<T>({
|
||||
method: method,
|
||||
url: `https://api.clickup.com/api/v3/${apiUrl}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: accessToken,
|
||||
},
|
||||
headers,
|
||||
body: method === 'GET' ? undefined : body,
|
||||
queryParams,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
export const enum ClickupEventType {
|
||||
TASK_CREATED = 'taskCreated',
|
||||
TASK_UPDATED = 'taskUpdated',
|
||||
TASK_DELETED = 'taskDeleted',
|
||||
TASK_PRIORITY_UPDATED = 'taskPriorityUpdated',
|
||||
TASK_STATUS_UPDATED = 'taskStatusUpdated',
|
||||
TASK_ASSIGNEE_UPDATED = 'taskAssigneeUpdated',
|
||||
TASK_DUEDATE_UPDATED = 'taskDueDateUpdated',
|
||||
TASK_TAG_UPDATED = 'taskTagUpdated',
|
||||
TASK_MOVED = 'taskMoved',
|
||||
TASK_COMMENT_POSTED = 'taskCommentPosted',
|
||||
TASK_COMMENT_UPDATED = 'taskCommentUpdated',
|
||||
TASK_TIME_ESTIMATE_UPDATED = 'taskTimeEstimateUpdated',
|
||||
TASK_TIME_TRACKED_UPDATED = 'taskTimeTrackedUpdated',
|
||||
LIST_CREATED = 'listCreated',
|
||||
LIST_UPDATED = 'listUpdated',
|
||||
LIST_DELETED = 'listDeleted',
|
||||
FOLDER_CREATED = 'folderCreated',
|
||||
FOLDER_UPDATED = 'folderUpdated',
|
||||
FOLDER_DELETED = 'folderDeleted',
|
||||
SPACE_CREATED = 'spaceCreated',
|
||||
SPACE_UPDATED = 'spaceUpdated',
|
||||
SPACE_DELETED = 'spaceDeleted',
|
||||
GOAL_CREATED = 'goalCreated',
|
||||
GOAL_UPDATED = 'goalUpdated',
|
||||
GOAL_DELETED = 'goalDeleted',
|
||||
KEY_RESULT_CREATED = 'keyResultCreated',
|
||||
KEY_RESULT_UPDATED = 'keyResultUpdated',
|
||||
KEY_RESULT_DELETED = 'keyResultDeleted',
|
||||
AUTOMATION_CREATED = 'automationCreated',
|
||||
}
|
||||
|
||||
export interface ClickupTask {
|
||||
id: string;
|
||||
custom_id: string;
|
||||
name: string;
|
||||
text_content: string;
|
||||
description: string;
|
||||
status: {
|
||||
status: string;
|
||||
color: string;
|
||||
orderindex: number;
|
||||
type: string;
|
||||
};
|
||||
orderindex: string;
|
||||
date_created: string;
|
||||
date_updated: string;
|
||||
date_closed: string;
|
||||
creator: {
|
||||
id: number;
|
||||
username: string;
|
||||
color: string;
|
||||
profilePicture: string;
|
||||
};
|
||||
assignees: string[];
|
||||
checklists: string[];
|
||||
tags: string[];
|
||||
parent: string;
|
||||
priority: string;
|
||||
due_date: string;
|
||||
start_date: string;
|
||||
time_estimate: string;
|
||||
time_spent: string;
|
||||
custom_fields: Record<string, unknown>[];
|
||||
list: {
|
||||
id: string;
|
||||
};
|
||||
folder: {
|
||||
id: string;
|
||||
};
|
||||
space: {
|
||||
id: string;
|
||||
};
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface ClickupWebhookPayload {
|
||||
event: ClickupEventType;
|
||||
history_items: {
|
||||
id: string;
|
||||
type: number;
|
||||
date: string;
|
||||
field: string;
|
||||
parent_id: string;
|
||||
data: Record<string, unknown>;
|
||||
source: string;
|
||||
user: ClickupUser;
|
||||
before: string;
|
||||
after: string;
|
||||
comment: ClickupComment;
|
||||
};
|
||||
task_id: string;
|
||||
webhook_id: string;
|
||||
}
|
||||
|
||||
interface ClickupUser {
|
||||
id: number;
|
||||
username: string;
|
||||
initials: string;
|
||||
email: string;
|
||||
color: string;
|
||||
profilePicture: string;
|
||||
}
|
||||
|
||||
interface ClickupComment {
|
||||
id: string;
|
||||
comment: {
|
||||
text: string;
|
||||
}[];
|
||||
comment_text: string;
|
||||
user: ClickupUser;
|
||||
resolved: boolean;
|
||||
assignee: ClickupUser;
|
||||
assigned_by: ClickupUser;
|
||||
reactions: [];
|
||||
date: string;
|
||||
}
|
||||
export interface ClickupWorkspace {
|
||||
id: string;
|
||||
name: string;
|
||||
color: string;
|
||||
avatar: string;
|
||||
members: {
|
||||
user: ClickupUser;
|
||||
invited_by?: Record<string, unknown>;
|
||||
}[];
|
||||
}
|
||||
@@ -0,0 +1,965 @@
|
||||
import { ClickupEventType } from '../common/models';
|
||||
import { clickupRegisterTrigger } from './register-trigger';
|
||||
import { triggerTaskTagUpdated } from './task-tag-updated';
|
||||
|
||||
export const sampleTask = {
|
||||
id: 'string',
|
||||
custom_id: 'string',
|
||||
name: 'string',
|
||||
text_content: 'string',
|
||||
description: 'string',
|
||||
status: {
|
||||
status: 'in progress',
|
||||
color: '#d3d3d3',
|
||||
orderindex: 1,
|
||||
type: 'custom',
|
||||
},
|
||||
orderindex: 'string',
|
||||
date_created: 'string',
|
||||
date_updated: 'string',
|
||||
date_closed: 'string',
|
||||
creator: {
|
||||
id: 183,
|
||||
username: 'John Doe',
|
||||
color: '#827718',
|
||||
profilePicture:
|
||||
'https://attachments-public.clickup.com/profilePictures/183_abc.jpg',
|
||||
},
|
||||
assignees: ['string'],
|
||||
checklists: ['string'],
|
||||
tags: ['string'],
|
||||
parent: 'string',
|
||||
priority: 'string',
|
||||
due_date: 'string',
|
||||
start_date: 'string',
|
||||
time_estimate: 'string',
|
||||
time_spent: 'string',
|
||||
custom_fields: [
|
||||
{
|
||||
id: 'string',
|
||||
name: 'string',
|
||||
type: 'string',
|
||||
type_config: {},
|
||||
date_created: 'string',
|
||||
hide_from_guests: true,
|
||||
value: {
|
||||
id: 183,
|
||||
username: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
color: '#7b68ee',
|
||||
initials: 'JD',
|
||||
profilePicture: null,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
list: {
|
||||
id: '123',
|
||||
},
|
||||
folder: {
|
||||
id: '456',
|
||||
},
|
||||
space: {
|
||||
id: '789',
|
||||
},
|
||||
url: 'string',
|
||||
};
|
||||
|
||||
export const triggers = [
|
||||
// task created
|
||||
{
|
||||
name: 'task_created',
|
||||
eventType: ClickupEventType.TASK_CREATED,
|
||||
displayName: 'Task Created',
|
||||
description: 'Triggered when a new task is created.',
|
||||
sampleData: {
|
||||
event: 'taskCreated',
|
||||
history_items: [
|
||||
{
|
||||
id: '1394258655167106175',
|
||||
type: 1,
|
||||
date: '1378109721053',
|
||||
field: 'status',
|
||||
parent_id: '900900799744',
|
||||
data: {},
|
||||
source: null,
|
||||
user: {
|
||||
id: 55053258,
|
||||
username: 'Activepieces Apps',
|
||||
email: 'apps@activepieces.com',
|
||||
color: '#aa2fff',
|
||||
initials: 'AA',
|
||||
profilePicture: null,
|
||||
},
|
||||
before: null,
|
||||
after: '90040005586783',
|
||||
},
|
||||
],
|
||||
task: sampleTask,
|
||||
task_id: '8669p1zvv',
|
||||
webhook_id: '9b2708b6-87e8-4fff-851a-2ebf0e35130f',
|
||||
},
|
||||
},
|
||||
// task updated
|
||||
{
|
||||
name: 'task_updated',
|
||||
eventType: ClickupEventType.TASK_UPDATED,
|
||||
displayName: 'Task Updated',
|
||||
description: 'Triggered when a task is updated.',
|
||||
sampleData: {
|
||||
event: 'taskUpdated',
|
||||
history_items: [
|
||||
{
|
||||
id: '3394266113344261722',
|
||||
type: 1,
|
||||
date: '1678110165596',
|
||||
field: 'name',
|
||||
parent_id: '900900799744',
|
||||
data: {},
|
||||
source: null,
|
||||
user: {
|
||||
id: 55053258,
|
||||
username: 'Activepieces Apps',
|
||||
email: 'apps@activepieces.com',
|
||||
color: '#aa2fff',
|
||||
initials: 'AA',
|
||||
profilePicture: null,
|
||||
},
|
||||
before: "Watch over Neriah's",
|
||||
after: "Watch over Neriah's things",
|
||||
},
|
||||
],
|
||||
task: sampleTask,
|
||||
task_id: '8669p1zvv',
|
||||
webhook_id: 'c065bdfd-eb7a-48dc-b25e-0cf5babf5ec8',
|
||||
},
|
||||
},
|
||||
// task deleted
|
||||
{
|
||||
name: 'task_deleted',
|
||||
eventType: ClickupEventType.TASK_DELETED,
|
||||
displayName: 'Task Deleted',
|
||||
description: 'Triggered when a task is deleted.',
|
||||
sampleData: {
|
||||
event: 'taskDeleted',
|
||||
task_id: '8669p1zvv',
|
||||
webhook_id: '78674f1e-ec8e-4302-908f-4190bdcfdf6a',
|
||||
},
|
||||
},
|
||||
// task priority updated
|
||||
{
|
||||
name: 'task_priority_updated',
|
||||
eventType: ClickupEventType.TASK_PRIORITY_UPDATED,
|
||||
displayName: "Task Priority Updated",
|
||||
description: 'Triggered when a task priority is updated.',
|
||||
sampleData: {
|
||||
"event": "taskPriorityUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800773800802162647",
|
||||
"type": 1,
|
||||
"date": "1642735267148",
|
||||
"field": "priority",
|
||||
"parent_id": "162641062",
|
||||
"data": {},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": null,
|
||||
"after": {
|
||||
"id": "2",
|
||||
"priority": "high",
|
||||
"color": "#ffcc00",
|
||||
"orderindex": "2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// task status updated
|
||||
{
|
||||
name: 'task_status_updated',
|
||||
eventType: ClickupEventType.TASK_STATUS_UPDATED,
|
||||
displayName: 'Task Status Updated',
|
||||
description: 'Triggered when a task status is updated.',
|
||||
sampleData: {
|
||||
"event": "taskStatusUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800787326392370170",
|
||||
"type": 1,
|
||||
"date": "1642736073330",
|
||||
"field": "status",
|
||||
"parent_id": "162641062",
|
||||
"data": {
|
||||
"status_type": "custom"
|
||||
},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": {
|
||||
"status": "to do",
|
||||
"color": "#f9d900",
|
||||
"orderindex": 0,
|
||||
"type": "open"
|
||||
},
|
||||
"after": {
|
||||
"status": "in progress",
|
||||
"color": "#7C4DFF",
|
||||
"orderindex": 1,
|
||||
"type": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// task assignee updated
|
||||
{
|
||||
name: 'task_assignee_updated',
|
||||
eventType: ClickupEventType.TASK_ASSIGNEE_UPDATED,
|
||||
displayName: 'Task Assignee Updated',
|
||||
description: 'Triggered when a task assignee is updated.',
|
||||
sampleData: {
|
||||
"event": "taskAssigneeUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800789353868594308",
|
||||
"type": 1,
|
||||
"date": "1642736194135",
|
||||
"field": "assignee_add",
|
||||
"parent_id": "162641062",
|
||||
"data": {},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"after": {
|
||||
"id": 184,
|
||||
"username": "Sam",
|
||||
"email": "sam@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "S",
|
||||
"profilePicture": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// task due date updated
|
||||
{
|
||||
name: 'task_due_date_updated',
|
||||
eventType: ClickupEventType.TASK_DUEDATE_UPDATED,
|
||||
displayName: 'Task Due Date Updated',
|
||||
description: 'Triggered when a task due date is updated.',
|
||||
sampleData: {
|
||||
"event": "taskDueDateUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800792714143635886",
|
||||
"type": 1,
|
||||
"date": "1642736394447",
|
||||
"field": "due_date",
|
||||
"parent_id": "162641062",
|
||||
"data": {
|
||||
"due_date_time": true,
|
||||
"old_due_date_time": false
|
||||
},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": "1642701600000",
|
||||
"after": "1643608800000"
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// task tag updated
|
||||
{
|
||||
name: 'task_tag_updated',
|
||||
eventType: ClickupEventType.TASK_TAG_UPDATED,
|
||||
displayName: 'Task Tag Updated',
|
||||
description: 'Triggered when a task tag is updated.',
|
||||
sampleData: {
|
||||
"event": "taskTagUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800797048554170804",
|
||||
"type": 1,
|
||||
"date": "1642736652800",
|
||||
"field": "tag",
|
||||
"parent_id": "162641062",
|
||||
"data": {},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": null,
|
||||
"after": [
|
||||
{
|
||||
"name": "def",
|
||||
"tag_fg": "#FF4081",
|
||||
"tag_bg": "#FF4081",
|
||||
"creator": 2770032
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// task moved
|
||||
{
|
||||
name: 'task_moved',
|
||||
eventType: ClickupEventType.TASK_MOVED,
|
||||
displayName: 'Task Moved',
|
||||
description: 'Triggered when a task is moved.',
|
||||
sampleData: {
|
||||
"event": "taskMoved",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800800851630274181",
|
||||
"type": 1,
|
||||
"date": "1642736879339",
|
||||
"field": "section_moved",
|
||||
"parent_id": "162641285",
|
||||
"data": {
|
||||
"mute_notifications": true
|
||||
},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": {
|
||||
"id": "162641062",
|
||||
"name": "Webhook payloads",
|
||||
"category": {
|
||||
"id": "96771950",
|
||||
"name": "hidden",
|
||||
"hidden": true
|
||||
},
|
||||
"project": {
|
||||
"id": "7002367",
|
||||
"name": "This is my API Space"
|
||||
}
|
||||
},
|
||||
"after": {
|
||||
"id": "162641285",
|
||||
"name": "webhook payloads 2",
|
||||
"category": {
|
||||
"id": "96772049",
|
||||
"name": "hidden",
|
||||
"hidden": true
|
||||
},
|
||||
"project": {
|
||||
"id": "7002367",
|
||||
"name": "This is my API Space"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// task comment posted
|
||||
{
|
||||
name: 'task_comment_posted',
|
||||
eventType: ClickupEventType.TASK_COMMENT_POSTED,
|
||||
displayName: 'Task Comment Posted',
|
||||
description: 'Triggered when a task comment is posted.',
|
||||
sampleData: {
|
||||
event: 'taskCommentPosted',
|
||||
history_items: [
|
||||
{
|
||||
id: '3394271120907039255',
|
||||
type: 1,
|
||||
date: '1678110464062',
|
||||
field: 'comment',
|
||||
parent_id: '900900799744',
|
||||
data: {},
|
||||
source: null,
|
||||
user: {
|
||||
id: 55053258,
|
||||
username: 'Activepieces Apps',
|
||||
email: 'apps@activepieces.com',
|
||||
color: '#aa2fff',
|
||||
initials: 'AA',
|
||||
profilePicture: null,
|
||||
},
|
||||
before: null,
|
||||
after: '90090008088251',
|
||||
comment: [
|
||||
{
|
||||
text: 'asdsada',
|
||||
attributes: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
task: sampleTask,
|
||||
task_id: '8669p1zvv',
|
||||
webhook_id: '6a86ce24-6276-4315-87f7-b580a9264284',
|
||||
},
|
||||
},
|
||||
// task comment updated
|
||||
{
|
||||
name: 'task_comment_updated',
|
||||
eventType: ClickupEventType.TASK_COMMENT_UPDATED,
|
||||
displayName: 'Task Comment Updated',
|
||||
description: 'Triggered when a task comment is updated.',
|
||||
sampleData: {
|
||||
event: 'taskCommentUpdated',
|
||||
history_items: [
|
||||
{
|
||||
id: '3394271120907039255',
|
||||
type: 1,
|
||||
date: '1678110464062',
|
||||
field: 'comment',
|
||||
parent_id: '900900799744',
|
||||
data: {},
|
||||
source: null,
|
||||
user: {
|
||||
id: 55053258,
|
||||
username: 'Activepieces Apps',
|
||||
email: 'apps@activepieces.com',
|
||||
color: '#aa2fff',
|
||||
initials: 'AA',
|
||||
profilePicture: null,
|
||||
},
|
||||
before: null,
|
||||
after: '90090008088251',
|
||||
comment: [
|
||||
{
|
||||
text: 'asdsada',
|
||||
attributes: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
task: sampleTask,
|
||||
task_id: '8669p1zvv',
|
||||
webhook_id: '1c14c8af-5509-4d81-ae7f-c0790c0f9683',
|
||||
},
|
||||
},
|
||||
// task time estimate updated
|
||||
{
|
||||
name: 'task_time_estimate_updated',
|
||||
eventType: ClickupEventType.TASK_TIME_ESTIMATE_UPDATED,
|
||||
displayName: 'Task Time Estimate Updated',
|
||||
description: 'Triggered when a task time estimate is updated.',
|
||||
sampleData: {
|
||||
"event": "taskTimeEstimateUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800808904123520175",
|
||||
"type": 1,
|
||||
"date": "1642737359443",
|
||||
"field": "time_estimate",
|
||||
"parent_id": "162641285",
|
||||
"data": {
|
||||
"time_estimate_string": "1 hour 30 minutes",
|
||||
"old_time_estimate_string": null,
|
||||
"rolled_up_time_estimate": 5400000,
|
||||
"time_estimate": 5400000,
|
||||
"time_estimates_by_user": [
|
||||
{
|
||||
"userid": 2770032,
|
||||
"user_time_estimate": "5400000",
|
||||
"user_rollup_time_estimate": "5400000"
|
||||
}
|
||||
]
|
||||
},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": null,
|
||||
"after": "5400000"
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// task time tracked updated
|
||||
{
|
||||
name: 'task_time_tracked_updated',
|
||||
eventType: ClickupEventType.TASK_TIME_TRACKED_UPDATED,
|
||||
displayName: 'Task Time Tracked Updated',
|
||||
description: 'Triggered when a task time tracked is updated.',
|
||||
sampleData: {
|
||||
"event": "taskTimeTrackedUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800809188061123931",
|
||||
"type": 1,
|
||||
"date": "1642737376354",
|
||||
"field": "time_spent",
|
||||
"parent_id": "162641285",
|
||||
"data": {
|
||||
"total_time": "900000",
|
||||
"rollup_time": "900000"
|
||||
},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": null,
|
||||
"after": {
|
||||
"id": "2800809188061119507",
|
||||
"start": "1642736476215",
|
||||
"end": "1642737376215",
|
||||
"time": "900000",
|
||||
"source": "clickup",
|
||||
"date_added": "1642737376354"
|
||||
}
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"data": {
|
||||
"description": "Time Tracking Created",
|
||||
"interval_id": "2800809188061119507"
|
||||
},
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// list created
|
||||
{
|
||||
name: 'list_created',
|
||||
eventType: ClickupEventType.LIST_CREATED,
|
||||
displayName: 'List Created',
|
||||
description: 'Triggered when a new list is created.',
|
||||
sampleData: {
|
||||
event: 'listCreated',
|
||||
list_id: '900201745120',
|
||||
webhook_id: 'eda9be69-dbb9-4c59-a3e2-3f871d5d3b9e',
|
||||
},
|
||||
},
|
||||
// list updated
|
||||
{
|
||||
name: 'list_updated',
|
||||
eventType: ClickupEventType.LIST_UPDATED,
|
||||
displayName: 'List Updated',
|
||||
description: 'Triggered when a list is updated.',
|
||||
sampleData: {
|
||||
"event": "listUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "8a2f82db-7718-4fdb-9493-4849e67f009d",
|
||||
"type": 6,
|
||||
"date": "1642740510345",
|
||||
"field": "name",
|
||||
"parent_id": "162641285",
|
||||
"data": {},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": "webhook payloads 2",
|
||||
"after": "Webhook payloads round 2"
|
||||
}
|
||||
],
|
||||
"list_id": "162641285",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// list deleted
|
||||
{
|
||||
name: 'list_deleted',
|
||||
eventType: ClickupEventType.LIST_DELETED,
|
||||
displayName: 'List Deleted',
|
||||
description: 'Triggered when a list is deleted.',
|
||||
sampleData: {
|
||||
"event": "listDeleted",
|
||||
"list_id": "162641062",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// folder created
|
||||
{
|
||||
name: 'folder_created',
|
||||
eventType: ClickupEventType.FOLDER_CREATED,
|
||||
displayName: 'Folder Created',
|
||||
description: 'Triggered when a new folder is created.',
|
||||
sampleData: {
|
||||
"event": "folderCreated",
|
||||
"folder_id": "96772212",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// folder updated
|
||||
{
|
||||
name: 'folder_updated',
|
||||
eventType: ClickupEventType.FOLDER_UPDATED,
|
||||
displayName: 'Folder Updated',
|
||||
description: 'Triggered when a folder is updated.',
|
||||
sampleData: { "event": "folderUpdated",
|
||||
"folder_id": "96772212",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// folder deleted
|
||||
{
|
||||
name: 'folder_deleted',
|
||||
eventType: ClickupEventType.FOLDER_DELETED,
|
||||
displayName: 'Folder Deleted',
|
||||
description: 'Triggered when a folder is deleted.',
|
||||
sampleData: {
|
||||
"event": "listDeleted",
|
||||
"list_id": "162641543",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// space created
|
||||
{
|
||||
name: 'space_created',
|
||||
eventType: ClickupEventType.SPACE_CREATED,
|
||||
displayName: 'Space Created',
|
||||
description: 'Triggered when a new space is created.',
|
||||
sampleData: {
|
||||
"event": "spaceCreated",
|
||||
"space_id": "54650507",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// space updated
|
||||
{
|
||||
name: 'space_updated',
|
||||
eventType: ClickupEventType.SPACE_UPDATED,
|
||||
displayName: 'Space Updated',
|
||||
description: 'Triggered when a space is updated.',
|
||||
sampleData: {
|
||||
"event": "spaceUpdated",
|
||||
"space_id": "54650507",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// space deleted
|
||||
{
|
||||
name: 'space_deleted',
|
||||
eventType: ClickupEventType.SPACE_DELETED,
|
||||
displayName: 'Space Deleted',
|
||||
description: 'Triggered when a space is deleted.',
|
||||
sampleData: {
|
||||
"event": "spaceDeleted",
|
||||
"space_id": "54650507",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
}
|
||||
},
|
||||
// automation created
|
||||
{
|
||||
name: 'automation_created',
|
||||
eventType: ClickupEventType.AUTOMATION_CREATED,
|
||||
displayName: 'Automation Created',
|
||||
description: 'Triggered when a new automation is created.',
|
||||
sampleData: {
|
||||
"id": "b4ced072-ae72-4c70-b898-fea5dd142408:main",
|
||||
"trigger_id": "6f612d16-9ff7-4db2-a2f6-19528ee3b90c",
|
||||
"date": "2024-01-11T19:40:17.927Z",
|
||||
"payload": {
|
||||
"id": "8687096vn",
|
||||
"custom_id": "DEF-43",
|
||||
"custom_item_id": 0,
|
||||
"name": "task name",
|
||||
"text_content": "",
|
||||
"description": "",
|
||||
"status": {
|
||||
"id": "p90090203753_p54073272_p54073128_p54071092_p54067915_r9V2QX7O",
|
||||
"status": "complete",
|
||||
"color": "#008844",
|
||||
"orderindex": 1,
|
||||
"type": "closed"
|
||||
},
|
||||
"orderindex": "39906954.00000000000000000000000000000000",
|
||||
"date_created": "1705002014968",
|
||||
"date_updated": "1705002016108",
|
||||
"date_closed": "1705002016108",
|
||||
"date_done": "1705002016108",
|
||||
"archived": false,
|
||||
"creator": {
|
||||
"id": 26191384,
|
||||
"username": "John",
|
||||
"color": "#5f7c8a",
|
||||
"email": "john@company.com",
|
||||
"profilePicture": "https://attachments.clickup.com/profilePictures/26191384_HoB.jpg"
|
||||
},
|
||||
"assignees": [],
|
||||
"watchers": [
|
||||
{
|
||||
"id": 26191384,
|
||||
"username": "John",
|
||||
"color": "#5f7c8a",
|
||||
"initials": "J",
|
||||
"email": "john@company.com",
|
||||
"profilePicture": "https://attachments.clickup.com/profilePictures/26191384_HoB.jpg"
|
||||
}
|
||||
],
|
||||
"checklists": [],
|
||||
"tags": [],
|
||||
"parent": null,
|
||||
"priority": null,
|
||||
"due_date": null,
|
||||
"start_date": null,
|
||||
"points": null,
|
||||
"time_estimate": null,
|
||||
"time_spent": 0,
|
||||
"custom_fields": [
|
||||
{
|
||||
"id": "ede917d5-4dbb-46eb-9f7c-5d4f0a652b1f",
|
||||
"name": "ijjb",
|
||||
"type": "formula",
|
||||
"type_config": {
|
||||
"version": "1.6",
|
||||
"is_dynamic": false,
|
||||
"return_types": [
|
||||
"null"
|
||||
],
|
||||
"calculation_state": "ready"
|
||||
},
|
||||
"date_created": "1698260411360",
|
||||
"hide_from_guests": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "7d979288-84e1-48b0-abaf-238ecb27e0fa",
|
||||
"name": "formula 1",
|
||||
"type": "currency",
|
||||
"type_config": {
|
||||
"default": null,
|
||||
"precision": 2,
|
||||
"currency_type": "USD"
|
||||
},
|
||||
"date_created": "1694298925344",
|
||||
"hide_from_guests": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "89bbdeeb-6724-4ec0-a8a7-c21d944199a7",
|
||||
"name": "Marketing Task Type",
|
||||
"type": "drop_down",
|
||||
"type_config": {
|
||||
"default": 0,
|
||||
"placeholder": null,
|
||||
"options": [
|
||||
{
|
||||
"id": "d73a55af-88f5-4161-a948-7341d2bbb045",
|
||||
"name": "Campaign",
|
||||
"color": null,
|
||||
"orderindex": 0
|
||||
},
|
||||
{
|
||||
"id": "0010111d-91da-4cb7-8cc1-d642f90ef194",
|
||||
"name": "asd",
|
||||
"color": null,
|
||||
"orderindex": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_created": "1698177406311",
|
||||
"hide_from_guests": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "07119fd9-e1eb-4457-bc69-3e5913707ca2",
|
||||
"name": "files",
|
||||
"type": "attachment",
|
||||
"type_config": {},
|
||||
"date_created": "1700237528128",
|
||||
"hide_from_guests": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "60392065-eb67-40c3-afe2-10f288d0695d",
|
||||
"name": "new field",
|
||||
"type": "currency",
|
||||
"type_config": {
|
||||
"precision": 2,
|
||||
"currency_type": "EUR"
|
||||
},
|
||||
"date_created": "1696603471462",
|
||||
"hide_from_guests": true,
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"dependencies": [],
|
||||
"linked_tasks": [],
|
||||
"locations": [],
|
||||
"team_id": "36003581",
|
||||
"url": "https://app.clickup.com/t/8687096vn",
|
||||
"sharing": {
|
||||
"public": false,
|
||||
"public_share_expires_on": null,
|
||||
"public_fields": [
|
||||
"assignees",
|
||||
"priority",
|
||||
"due_date",
|
||||
"content",
|
||||
"comments",
|
||||
"attachments",
|
||||
"customFields",
|
||||
"subtasks",
|
||||
"tags",
|
||||
"checklists",
|
||||
"coverimage"
|
||||
],
|
||||
"token": null,
|
||||
"seo_optimized": false
|
||||
},
|
||||
"list": {
|
||||
"id": "901102008938",
|
||||
"name": "List",
|
||||
"access": true
|
||||
},
|
||||
"project": {
|
||||
"id": "90110993233",
|
||||
"name": "test folder",
|
||||
"hidden": false,
|
||||
"access": true
|
||||
},
|
||||
"folder": {
|
||||
"id": "90110993233",
|
||||
"name": "test folder",
|
||||
"hidden": false,
|
||||
"access": true
|
||||
},
|
||||
"space": {
|
||||
"id": "90090203753"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// goal created
|
||||
{
|
||||
name: 'goal_created',
|
||||
eventType: ClickupEventType.GOAL_CREATED,
|
||||
displayName: 'Goal Created',
|
||||
description: 'Triggered when a new goal is created.',
|
||||
sampleData: {
|
||||
"event": "goalCreated",
|
||||
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
|
||||
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
|
||||
}
|
||||
},
|
||||
// goal updated
|
||||
{
|
||||
name: 'goal_updated',
|
||||
eventType: ClickupEventType.GOAL_UPDATED,
|
||||
displayName: 'Goal Updated',
|
||||
description: 'Triggered when a goal is updated.',
|
||||
sampleData: {
|
||||
"event": "goalUpdated",
|
||||
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
|
||||
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
|
||||
}
|
||||
},
|
||||
// goal deleted
|
||||
{
|
||||
name: 'goal_deleted',
|
||||
eventType: ClickupEventType.GOAL_DELETED,
|
||||
displayName: 'Goal Deleted',
|
||||
description: 'Triggered when a goal is deleted.',
|
||||
sampleData: {
|
||||
"event": "goalDeleted",
|
||||
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
|
||||
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
|
||||
}
|
||||
},
|
||||
// key result created
|
||||
{
|
||||
name: 'key_result_created',
|
||||
eventType: ClickupEventType.KEY_RESULT_CREATED,
|
||||
displayName: 'Key Result Created',
|
||||
description: 'Triggered when a new key result is created.',
|
||||
sampleData: {
|
||||
"event": "keyResultCreated",
|
||||
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
|
||||
"key_result_id": "47608e42-ad0e-4934-a39e-950539c77e79",
|
||||
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
|
||||
}
|
||||
},
|
||||
// key result updated
|
||||
{
|
||||
name: 'key_result_updated',
|
||||
eventType: ClickupEventType.KEY_RESULT_UPDATED,
|
||||
displayName: 'Key Result Updated',
|
||||
description: 'Triggered when a key result is updated.',
|
||||
sampleData: {
|
||||
"event": "keyResultUpdated",
|
||||
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
|
||||
"key_result_id": "47608e42-ad0e-4934-a39e-950539c77e79",
|
||||
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
|
||||
}
|
||||
},
|
||||
// key result deleted
|
||||
{
|
||||
name: 'key_result_deleted',
|
||||
eventType: ClickupEventType.KEY_RESULT_DELETED,
|
||||
displayName: 'Key Result Deleted',
|
||||
description: 'Triggered when a key result is deleted.',
|
||||
sampleData: {
|
||||
"event": "keyResultDeleted",
|
||||
"goal_id": "a23e5a3d-74b5-44c2-ab53-917ebe85045a",
|
||||
"key_result_id": "47608e42-ad0e-4934-a39e-950539c77e79",
|
||||
"webhook_id": "d5eddb2d-db2b-49e9-87d4-bc6cfbe2313b"
|
||||
}
|
||||
},
|
||||
].map((props) => clickupRegisterTrigger(props));
|
||||
|
||||
export const clickupTriggers = [...triggers, triggerTaskTagUpdated];
|
||||
@@ -0,0 +1,140 @@
|
||||
import { TriggerStrategy, createTrigger } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
httpClient,
|
||||
HttpRequest,
|
||||
HttpMethod,
|
||||
AuthenticationType,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { callClickupGetTask, clickupCommon } from '../common';
|
||||
import { ClickupEventType, ClickupWebhookPayload } from '../common/models';
|
||||
import { clickupAuth } from '../../';
|
||||
|
||||
export const clickupRegisterTrigger = ({
|
||||
name,
|
||||
displayName,
|
||||
eventType,
|
||||
description,
|
||||
sampleData,
|
||||
}: {
|
||||
name: string;
|
||||
displayName: string;
|
||||
eventType: ClickupEventType;
|
||||
description: string;
|
||||
sampleData: unknown;
|
||||
}) =>
|
||||
createTrigger({
|
||||
auth: clickupAuth,
|
||||
name: `clickup_trigger_${name}`,
|
||||
displayName,
|
||||
description,
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(true),
|
||||
space_id: clickupCommon.space_id(false), // Optional, depends on workspace
|
||||
folder_id: clickupCommon.folder_id(false), // Optional, depends on space
|
||||
list_id: clickupCommon.list_id(false), // Optional, depends on folder or space
|
||||
task_id: clickupCommon.task_id(false), // Optional, depends on list
|
||||
},
|
||||
sampleData,
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const { workspace_id, space_id, folder_id, list_id, task_id } =
|
||||
context.propsValue;
|
||||
|
||||
const requestBody: Record<string, unknown> = {
|
||||
endpoint: context.webhookUrl,
|
||||
events: [eventType],
|
||||
};
|
||||
|
||||
// Add scope narrowing properties to the webhook request body
|
||||
if (space_id) requestBody.space_id = space_id;
|
||||
if (folder_id) requestBody.folder_id = folder_id;
|
||||
if (list_id) requestBody.list_id = list_id;
|
||||
if (task_id) requestBody.task_id = task_id;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.clickup.com/api/v2/team/${workspace_id}/webhook`,
|
||||
body: requestBody,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.auth.access_token,
|
||||
},
|
||||
queryParams: {},
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<WebhookInformation>(
|
||||
request
|
||||
);
|
||||
console.debug(`clickup.${eventType}.onEnable`, response);
|
||||
|
||||
await context.store.put<WebhookInformation>(
|
||||
`clickup_${name}_trigger`,
|
||||
response.body
|
||||
);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhook = await context.store.get<WebhookInformation>(
|
||||
`clickup_${name}_trigger`
|
||||
);
|
||||
if (webhook != null) {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.DELETE,
|
||||
url: `https://api.clickup.com/api/v2/webhook/${webhook.id}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.auth['access_token'],
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest(request);
|
||||
console.debug(`clickup.${eventType}.onDisable`, response);
|
||||
}
|
||||
},
|
||||
async run(context) {
|
||||
const payload = context.payload.body as ClickupWebhookPayload;
|
||||
|
||||
if (
|
||||
[
|
||||
ClickupEventType.TASK_CREATED,
|
||||
ClickupEventType.TASK_UPDATED,
|
||||
ClickupEventType.TASK_COMMENT_POSTED,
|
||||
ClickupEventType.TASK_COMMENT_UPDATED,
|
||||
].includes(eventType)
|
||||
) {
|
||||
const enriched = [
|
||||
{
|
||||
...payload,
|
||||
task: await callClickupGetTask(
|
||||
context.auth['access_token'],
|
||||
payload.task_id
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
console.debug('payload enriched', enriched);
|
||||
return enriched;
|
||||
}
|
||||
|
||||
return [context.payload.body];
|
||||
},
|
||||
});
|
||||
|
||||
interface WebhookInformation {
|
||||
id: string;
|
||||
webhook: {
|
||||
id: string;
|
||||
userid: number;
|
||||
team_id: number;
|
||||
endpoint: string;
|
||||
client_id: string;
|
||||
events: ClickupEventType[];
|
||||
task_id?: string;
|
||||
list_id?: string;
|
||||
folder_id?: string;
|
||||
space_id?: string;
|
||||
health: {
|
||||
status: string;
|
||||
fail_count: number;
|
||||
};
|
||||
secret: string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import {
|
||||
TriggerStrategy, createTrigger
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
httpClient,
|
||||
HttpRequest,
|
||||
HttpMethod,
|
||||
AuthenticationType,
|
||||
} from "@activepieces/pieces-common";
|
||||
import { callClickupGetTask, clickupCommon } from '../common';
|
||||
import { ClickupEventType, ClickupWebhookPayload } from '../common/models';
|
||||
import { clickupAuth } from "../../";
|
||||
|
||||
export const triggerTaskTagUpdated = createTrigger({
|
||||
auth: clickupAuth,
|
||||
name: 'task_tag_updated',
|
||||
displayName: 'Task Tag Updated',
|
||||
description: 'Triggered when a tag is added or removed or renamed on a task.',
|
||||
sampleData: {
|
||||
"event": "taskTagUpdated",
|
||||
"history_items": [
|
||||
{
|
||||
"id": "2800797048554170804",
|
||||
"type": 1,
|
||||
"date": "1642736652800",
|
||||
"field": "tag",
|
||||
"parent_id": "162641062",
|
||||
"data": {},
|
||||
"source": null,
|
||||
"user": {
|
||||
"id": 183,
|
||||
"username": "John",
|
||||
"email": "john@company.com",
|
||||
"color": "#7b68ee",
|
||||
"initials": "J",
|
||||
"profilePicture": null
|
||||
},
|
||||
"before": null,
|
||||
"after": [
|
||||
{
|
||||
"name": "def",
|
||||
"tag_fg": "#FF4081",
|
||||
"tag_bg": "#FF4081",
|
||||
"creator": 2770032
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"task_id": "1vj38vv",
|
||||
"webhook_id": "7fa3ec74-69a8-4530-a251-8a13730bd204"
|
||||
},
|
||||
props: {
|
||||
workspace_id: clickupCommon.workspace_id(true),
|
||||
space_id: clickupCommon.space_id(true),
|
||||
list_id: clickupCommon.list_id(false),
|
||||
task_id: clickupCommon.task_id(false),
|
||||
},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const { workspace_id } = context.propsValue
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.clickup.com/api/v2/team/${workspace_id}/webhook`,
|
||||
body: {
|
||||
endpoint: context.webhookUrl,
|
||||
events: [ClickupEventType.TASK_TAG_UPDATED]
|
||||
},
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.auth.access_token
|
||||
},
|
||||
queryParams: {},
|
||||
}
|
||||
|
||||
const response = await httpClient.sendRequest<WebhookInformation>(request);
|
||||
console.debug(`clickup.${ClickupEventType.TASK_TAG_UPDATED}.onEnable`, response)
|
||||
|
||||
await context.store.put<WebhookInformation>(`clickup_task_tag_updated_trigger`, response.body);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhook = await context.store.get<WebhookInformation>(`clickup_task_tag_updated_trigger`);
|
||||
if (webhook != null) {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.DELETE,
|
||||
url: `https://api.clickup.com/api/v2/webhook/${webhook.id}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.auth['access_token'],
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest(request);
|
||||
console.debug(`clickup.${ClickupEventType.TASK_TAG_UPDATED}.onDisable`, response)
|
||||
}
|
||||
},
|
||||
async run(context) {
|
||||
const payload = context.payload.body as ClickupWebhookPayload
|
||||
|
||||
return [{
|
||||
...payload,
|
||||
task: await callClickupGetTask(
|
||||
context.auth['access_token'],
|
||||
payload.task_id
|
||||
)
|
||||
}];
|
||||
}
|
||||
});
|
||||
|
||||
interface WebhookInformation {
|
||||
id: string
|
||||
webhook: {
|
||||
id: string
|
||||
userid: number
|
||||
team_id: number
|
||||
endpoint: string
|
||||
client_id: string
|
||||
events: ClickupEventType[]
|
||||
task_id: string
|
||||
list_id: string
|
||||
folder_id: string
|
||||
space_id: string
|
||||
health: {
|
||||
status: string
|
||||
fail_count: number
|
||||
},
|
||||
secret: string
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user