Skip to main content
Glama

Github Project Manager

message-operations.ts10.2 kB
import { BaseSlackTool } from './base-slack-tool.js'; import type { Block, KnownBlock } from '@slack/web-api'; /** * Tool for Slack message operations */ export class MessageOperationsTool extends BaseSlackTool { /** * Post a new message to a Slack channel * * @param channelId The channel ID to post to * @param text The message text to post * @returns Formatted response with posting confirmation */ async postMessage(channelId: string, text: string) { try { const result = await this.client.chat.postMessage({ channel: channelId, text: text, }); const responseText = `Message successfully posted to channel ${channelId}`; if (result.ts) { const messageInfo = { text: text, channel: channelId, timestamp: result.ts, }; return this.createResponse( `${responseText}\n\nMessage details:\n${JSON.stringify(messageInfo, null, 2)}`, ); } return this.createResponse(responseText); } catch (error) { return this.handleError(error, `post message to channel ${channelId}`); } } /** * Post a message with attachments and/or blocks to a Slack channel * * @param channelId The channel ID to post to * @param text The fallback text for the message * @param blocks Optional layout blocks for rich formatting * @param attachments Optional attachments for the message * @returns Formatted response with posting confirmation */ async postRichMessage( channelId: string, text: string, blocks?: Array<Block | KnownBlock>, attachments?: Array<Record<string, unknown>>, ) { try { const result = await this.client.chat.postMessage({ channel: channelId, text: text, blocks: blocks, attachments: attachments, }); const responseText = `Rich message successfully posted to channel ${channelId}`; if (result.ts) { const messageInfo = { text: text, channel: channelId, timestamp: result.ts, has_blocks: !!blocks, has_attachments: !!attachments, }; return this.createResponse( `${responseText}\n\nMessage details:\n${JSON.stringify(messageInfo, null, 2)}`, ); } return this.createResponse(responseText); } catch (error) { return this.handleError(error, `post rich message to channel ${channelId}`); } } /** * Update an existing message * * @param channelId The channel containing the message * @param timestamp Timestamp of the message to update * @param text New text for the message * @param blocks Optional new blocks for the message * @param attachments Optional new attachments for the message * @returns Formatted response with update confirmation */ async updateMessage( channelId: string, timestamp: string, text: string, blocks?: Array<Block | KnownBlock>, attachments?: Array<Record<string, unknown>>, ) { try { const result = await this.client.chat.update({ channel: channelId, ts: timestamp, text: text, blocks: blocks, attachments: attachments, }); const responseText = `Message successfully updated in channel ${channelId}`; if (result.ts) { const messageInfo = { text: text, channel: channelId, timestamp: result.ts, has_blocks: !!blocks, has_attachments: !!attachments, }; return this.createResponse( `${responseText}\n\nMessage details:\n${JSON.stringify(messageInfo, null, 2)}`, ); } return this.createResponse(responseText); } catch (error) { return this.handleError(error, `update message in channel ${channelId}`); } } /** * Delete a message * * @param channelId The channel containing the message * @param timestamp Timestamp of the message to delete * @returns Formatted response with deletion confirmation */ async deleteMessage(channelId: string, timestamp: string) { try { await this.client.chat.delete({ channel: channelId, ts: timestamp, }); const responseText = `Message successfully deleted from channel ${channelId}`; return this.createResponse(responseText); } catch (error) { return this.handleError(error, `delete message from channel ${channelId}`); } } /** * Schedule a message for future delivery * * @param channelId The channel ID to post to * @param text The message text to post * @param postAt Unix timestamp for when message should be sent * @param blocks Optional layout blocks for rich formatting * @param attachments Optional attachments for the message * @returns Formatted response with scheduling confirmation */ async scheduleMessage( channelId: string, text: string, postAt: number, blocks?: Array<Block | KnownBlock>, attachments?: Array<Record<string, unknown>>, ) { try { const result = await this.client.chat.scheduleMessage({ channel: channelId, text: text, post_at: postAt, blocks: blocks, attachments: attachments, }); const responseText = `Message successfully scheduled for channel ${channelId}`; if (result.scheduled_message_id) { const scheduledDate = new Date(postAt * 1000).toISOString(); const messageInfo = { text: text, channel: channelId, scheduled_message_id: result.scheduled_message_id, post_at: postAt, scheduled_for: scheduledDate, has_blocks: !!blocks, has_attachments: !!attachments, }; return this.createResponse( `${responseText}\n\nScheduled message details:\n${JSON.stringify(messageInfo, null, 2)}`, ); } return this.createResponse(responseText); } catch (error) { return this.handleError(error, `schedule message for channel ${channelId}`); } } /** * Reply to a specific message thread * * @param channelId The channel containing the thread * @param threadTs Timestamp of the parent message * @param text The reply text * @returns Formatted response with reply confirmation */ async replyToThread(channelId: string, threadTs: string, text: string) { try { const result = await this.client.chat.postMessage({ channel: channelId, thread_ts: threadTs, text: text, }); const responseText = `Reply successfully posted to thread in channel ${channelId}`; if (result.ts) { const messageInfo = { text: text, channel: channelId, thread_ts: threadTs, reply_ts: result.ts, }; return this.createResponse( `${responseText}\n\nReply details:\n${JSON.stringify(messageInfo, null, 2)}`, ); } return this.createResponse(responseText); } catch (error) { return this.handleError(error, `reply to thread in channel ${channelId}`); } } /** * Add an emoji reaction to a message * * @param channelId The channel containing the message * @param timestamp Message timestamp to react to * @param reaction Emoji name without colons * @returns Formatted response with reaction confirmation */ async addReaction(channelId: string, timestamp: string, reaction: string) { try { // Remove colons if they were included const cleanReaction = reaction.replace(/:/g, ''); await this.client.reactions.add({ channel: channelId, timestamp: timestamp, name: cleanReaction, }); const responseText = `Reaction :${cleanReaction}: added to message in channel ${channelId}`; return this.createResponse(responseText); } catch (error) { return this.handleError(error, `add reaction to message in channel ${channelId}`); } } /** * Get all replies in a message thread * * @param channelId The channel containing the thread * @param threadTs Timestamp of the parent message * @returns Formatted response with thread replies */ async getThreadReplies(channelId: string, threadTs: string) { try { const result = await this.client.conversations.replies({ channel: channelId, ts: threadTs, }); const messages = result.messages || []; let responseText = `Retrieved ${messages.length} messages from thread in channel ${channelId}`; responseText += `\n\n${JSON.stringify(messages, null, 2)}`; return this.createResponse(responseText); } catch (error) { return this.handleError(error, `get thread replies in channel ${channelId}`); } } }

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/Monsoft-Solutions/model-context-protocols'

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