UNPKG

@taazkareem/clickup-mcp-server

Version:

ClickUp MCP Server - Integrate ClickUp tasks with AI through Model Context Protocol

105 lines (104 loc) 4.37 kB
/** * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com> * SPDX-License-Identifier: MIT * * ClickUp Task Service - Comments Module * * Handles comment operations for ClickUp tasks, including: * - Retrieving comments for a task * - Creating comments on a task */ import { TaskServiceAttachments } from './task-attachments.js'; /** * Comments functionality for the TaskService */ export class TaskServiceComments extends TaskServiceAttachments { /** * Get all comments for a task * * @param taskId ID of the task to get comments for * @param start Optional pagination start * @param startId Optional comment ID to start from * @returns Array of task comments */ async getTaskComments(taskId, start, startId) { this.logOperation('getTaskComments', { taskId, start, startId }); try { // Build query parameters for pagination const queryParams = new URLSearchParams(); if (start !== undefined) { queryParams.append('start', start.toString()); } if (startId) { queryParams.append('start_id', startId); } const queryString = queryParams.toString() ? `?${queryParams.toString()}` : ''; const response = await this.client.get(`/task/${taskId}/comment${queryString}`); return response.data.comments || []; } catch (error) { throw this.handleError(error, 'Failed to get task comments'); } } /** * Create a comment on a task * * @param taskId ID of the task to comment on * @param commentText Text content of the comment * @param notifyAll Whether to notify all assignees * @param assignee Optional user ID to assign the comment to * @returns The created comment */ async createTaskComment(taskId, commentText, notifyAll = false, assignee) { this.logOperation('createTaskComment', { taskId, commentText, notifyAll, assignee }); try { const payload = { comment_text: commentText, notify_all: notifyAll }; if (assignee) { payload.assignee = assignee; } // Make the request directly without using makeRequest for better error handling const response = await this.client.post(`/task/${taskId}/comment`, payload); // Handle different response formats from ClickUp API if (response.data) { if (response.data.comment) { // Standard format: { comment: ClickUpComment } return response.data.comment; } else if (response.data.id && (response.data.comment_text || response.data.comment)) { // Direct format: the comment object itself return response.data; } else { // Fallback: construct a minimal valid comment object return { id: response.data.id || `custom-${Date.now()}`, comment: response.data.comment || commentText, comment_text: response.data.comment_text || commentText, user: response.data.user || { id: 0, username: 'Unknown', email: '', color: '' }, date: response.data.date || new Date().toISOString(), resolved: false }; } } throw new Error('Invalid response from ClickUp API'); } catch (error) { // Check if comment might have been created despite error if (error.response?.status === 200 || error.response?.status === 201) { // Try to construct a comment object from what we know return { id: `fallback-${Date.now()}`, comment: commentText, comment_text: commentText, user: { id: 0, username: 'Unknown', email: '', color: '' }, date: new Date().toISOString(), resolved: false }; } throw this.handleError(error, 'Failed to create task comment'); } } }