Skip to main content
Glama
reply-to-comment.ts3.98 kB
import type { OAuth2Client } from "google-auth-library"; import { google } from "googleapis"; import { z } from "zod"; export const tool = { name: "gdrive_reply_to_comment", description: "Reply to an existing comment thread on a Google Doc. Can optionally resolve the thread or assign it to someone.", inputSchema: z.object({ doc_id_or_url: z .string() .describe( "Google Docs URL (e.g., https://docs.google.com/document/d/...) or document ID", ), comment_id: z .string() .describe( "The ID of the comment thread to reply to (get this from gdrive_list_doc_comments)", ), reply: z.string().describe("The reply text to add"), resolve: z .boolean() .optional() .describe( "Optional: Set to true to mark the thread as resolved after adding the reply", ), assignee_email: z .string() .optional() .describe( "Optional: Email address of the person to assign this comment to", ), }), annotations: { readOnlyHint: false, idempotentHint: false, }, } as const; export const handler = async ( args: z.infer<typeof tool.inputSchema>, auth: OAuth2Client, ) => { const { doc_id_or_url, comment_id, reply, resolve, assignee_email } = args; try { const result = await replyToComment( auth, doc_id_or_url, comment_id, reply, resolve, assignee_email, ); return { content: [ { type: "text" as const, text: result, }, ], }; } catch (error: unknown) { if (error instanceof Error) { return { content: [ { type: "text" as const, text: `Error: ${error.message}`, }, ], isError: true, }; } throw error; } }; const extractDocId = (input: string): string | null => { // Try to extract document ID from URL const urlMatch = input.match(/\/document\/d\/([a-zA-Z0-9-_]+)/); if (urlMatch) { return urlMatch[1] ?? null; } // If it's not a URL, assume it's already a document ID if (/^[a-zA-Z0-9-_]+$/.test(input)) { return input; } return null; }; const replyToComment = async ( auth: OAuth2Client, docIdOrUrl: string, commentId: string, content: string, resolve?: boolean, assigneeEmail?: string, ): Promise<string> => { const docId = extractDocId(docIdOrUrl); if (!docId) { throw new Error("Invalid document ID or URL"); } const drive = google.drive({ version: "v3", auth }); try { // Create the reply const response = await drive.replies.create({ fileId: docId, commentId, requestBody: { content, }, fields: "id,content,author,createdTime", }); let result = `Reply added successfully!\n\n`; result += `Reply ID: ${response.data.id}\n`; result += `Author: ${response.data.author?.displayName}\n`; result += `Created: ${response.data.createdTime}\n`; result += `Content: ${response.data.content}\n`; // Resolve the thread if requested if (resolve) { await drive.comments.update({ fileId: docId, commentId, requestBody: { resolved: true, }, }); result += `\nThread marked as RESOLVED.\n`; } // Update assignee if specified if (assigneeEmail) { try { await drive.comments.update({ fileId: docId, commentId, requestBody: { content: response.data.content || content, }, }); result += `\nNote: Assignee feature may require additional permissions.\n`; } catch { result += `\nWarning: Could not set assignee. This feature may not be available.\n`; } } return result; } catch (error: unknown) { if (error instanceof Error) { throw new Error(`Failed to reply to comment: ${error.message}`); } throw error; } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/benjamine/gdrive-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server