import { Command } from 'commander' import { cliOutput } from '@/shared/utils/cli-output' import type { BotOption } from './shared' import { getClient, getCurrentServer } from './shared' interface MessageResult { id?: string channel_id?: string content?: string author?: string timestamp?: string edited_timestamp?: string thread_id?: string | null messages?: Array<{ id: string channel_id: string content: string author: string timestamp: string thread_id?: string | null }> deleted?: string error?: string } export async function sendAction( channel: string, text: string, options: BotOption & { thread?: string; reply?: string }, ): Promise { try { const client = await getClient(options) const serverId = await getCurrentServer(options) const channelId = await client.resolveChannel(serverId, channel) const message = await client.sendMessage(channelId, text, { thread_id: options.thread, reply_to: options.reply, }) return { id: message.id, channel_id: message.channel_id, content: message.content, author: message.author.username, timestamp: message.timestamp, } } catch (error) { return { error: (error as Error).message } } } export async function listAction(channel: string, options: BotOption & { limit?: string }): Promise { try { const client = await getClient(options) const serverId = await getCurrentServer(options) const channelId = await client.resolveChannel(serverId, channel) const limit = options.limit ? parseInt(options.limit, 10) : 50 const messages = await client.getMessages(channelId, limit) return { messages: messages.map((msg) => ({ id: msg.id, channel_id: msg.channel_id, content: msg.content, author: msg.author.username, timestamp: msg.timestamp, thread_id: msg.thread_id || null, })), } } catch (error) { return { error: (error as Error).message } } } export async function getAction(channel: string, messageId: string, options: BotOption): Promise { try { const client = await getClient(options) const serverId = await getCurrentServer(options) const channelId = await client.resolveChannel(serverId, channel) const message = await client.getMessage(channelId, messageId) return { id: message.id, channel_id: message.channel_id, content: message.content, author: message.author.username, timestamp: message.timestamp, edited_timestamp: message.edited_timestamp, thread_id: message.thread_id || null, } } catch (error) { return { error: (error as Error).message } } } export async function editAction( channel: string, messageId: string, text: string, options: BotOption, ): Promise { try { const client = await getClient(options) const serverId = await getCurrentServer(options) const channelId = await client.resolveChannel(serverId, channel) const message = await client.editMessage(channelId, messageId, text) return { id: message.id, channel_id: message.channel_id, content: message.content, author: message.author.username, timestamp: message.timestamp, edited_timestamp: message.edited_timestamp, } } catch (error) { return { error: (error as Error).message } } } export async function deleteAction( channel: string, messageId: string, options: BotOption & { force?: boolean }, ): Promise { if (!options.force) { return { error: 'Use --force to confirm deletion' } } try { const client = await getClient(options) const serverId = await getCurrentServer(options) const channelId = await client.resolveChannel(serverId, channel) await client.deleteMessage(channelId, messageId) return { deleted: messageId } } catch (error) { return { error: (error as Error).message } } } export async function repliesAction( _channel: string, threadId: string, options: BotOption & { limit?: string }, ): Promise { try { const client = await getClient(options) const limit = options.limit ? parseInt(options.limit, 10) : 50 const messages = await client.getMessages(threadId, limit) return { messages: messages.map((msg) => ({ id: msg.id, channel_id: msg.channel_id, content: msg.content, author: msg.author.username, timestamp: msg.timestamp, thread_id: msg.thread_id || null, })), } } catch (error) { return { error: (error as Error).message } } } export const messageCommand = new Command('message') .description('Message commands') .addCommand( new Command('send') .description('Send a message to a channel') .argument('', 'Channel ID or name') .argument('', 'Message text') .option('--thread ', 'Thread ID for replies') .option('--reply ', 'Reply to a message by ID') .option('--bot ', 'Use specific bot') .option('--server ', 'Server ID') .option('--pretty', 'Pretty print JSON output') .action(async (channel: string, text: string, opts: BotOption & { thread?: string; reply?: string }) => { cliOutput(await sendAction(channel, text, opts), opts.pretty) }), ) .addCommand( new Command('list') .description('List messages in a channel') .argument('', 'Channel ID or name') .option('--limit ', 'Number of messages to fetch', '50') .option('--bot ', 'Use specific bot') .option('--server ', 'Server ID') .option('--pretty', 'Pretty print JSON output') .action(async (channel: string, opts: BotOption & { limit?: string }) => { cliOutput(await listAction(channel, opts), opts.pretty) }), ) .addCommand( new Command('get') .description('Get a single message') .argument('', 'Channel ID or name') .argument('', 'Message ID') .option('--bot ', 'Use specific bot') .option('--server ', 'Server ID') .option('--pretty', 'Pretty print JSON output') .action(async (channel: string, messageId: string, opts: BotOption) => { cliOutput(await getAction(channel, messageId, opts), opts.pretty) }), ) .addCommand( new Command('edit') .description('Edit a message') .argument('', 'Channel ID or name') .argument('', 'Message ID') .argument('', 'New message text') .option('--bot ', 'Use specific bot') .option('--server ', 'Server ID') .option('--pretty', 'Pretty print JSON output') .action(async (channel: string, messageId: string, text: string, opts: BotOption) => { cliOutput(await editAction(channel, messageId, text, opts), opts.pretty) }), ) .addCommand( new Command('delete') .description('Delete a message') .argument('', 'Channel ID or name') .argument('', 'Message ID') .option('--force', 'Confirm deletion') .option('--bot ', 'Use specific bot') .option('--server ', 'Server ID') .option('--pretty', 'Pretty print JSON output') .action(async (channel: string, messageId: string, opts: BotOption & { force?: boolean }) => { cliOutput(await deleteAction(channel, messageId, opts), opts.pretty) }), ) .addCommand( new Command('replies') .description('Get thread replies') .argument('', 'Channel ID or name') .argument('', 'Thread ID') .option('--limit ', 'Number of replies to fetch', '50') .option('--bot ', 'Use specific bot') .option('--server ', 'Server ID') .option('--pretty', 'Pretty print JSON output') .action(async (channel: string, threadId: string, opts: BotOption & { limit?: string }) => { cliOutput(await repliesAction(channel, threadId, opts), opts.pretty) }), )