(msg: TelegramBot.Message)
| 97 | // ------------------------------------------------------------------------- |
| 98 | |
| 99 | private async handleTelegramMessage(msg: TelegramBot.Message) { |
| 100 | if (!this.bot || !this.agent) return; |
| 101 | |
| 102 | const chatId = msg.chat.id; |
| 103 | const messageId = msg.message_id; |
| 104 | const text = (msg.text || msg.caption || "").trim(); |
| 105 | |
| 106 | const channelId = `telegram-${chatId}`; |
| 107 | this.ipcBroadcaster?.broadcastInbound( |
| 108 | channelId, |
| 109 | "telegram", |
| 110 | { |
| 111 | id: String(msg.from?.id || ""), |
| 112 | username: msg.from?.username || msg.from?.first_name || "", |
| 113 | }, |
| 114 | text, |
| 115 | ); |
| 116 | |
| 117 | // --- Extract attachments --- |
| 118 | const attachments = await this.extractAttachments(msg, channelId); |
| 119 | |
| 120 | // Skip messages with no text and no attachments |
| 121 | if (!text && attachments.length === 0) return; |
| 122 | |
| 123 | await this.tryAckReaction(chatId, messageId); |
| 124 | |
| 125 | // --- Command handling --- |
| 126 | if (text) { |
| 127 | const commandKey = text.split(/\s/)[0].toLowerCase(); |
| 128 | const command = this.resolveTelegramCommand(commandKey); |
| 129 | |
| 130 | if (command) { |
| 131 | const result = await this.agent.handleCommand(command, channelId); |
| 132 | await this.sendSafe(chatId, result.message || `/${command} executed.`); |
| 133 | return; |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | // --- Regular message → agent --- |
| 138 | await this.bot.sendChatAction(chatId, "typing"); |
| 139 | |
| 140 | let finalText = ""; |
| 141 | let hasError = false; |
| 142 | let errorMessage = ""; |
| 143 | const pendingFiles: Array<{ filePath: string; caption?: string }> = []; |
| 144 | |
| 145 | const onEvent = (event: AgentEvent) => { |
| 146 | switch (event.type) { |
| 147 | case "text_delta": |
| 148 | finalText += event.delta; |
| 149 | break; |
| 150 | case "file_output": |
| 151 | pendingFiles.push({ |
| 152 | filePath: event.filePath, |
| 153 | caption: event.caption, |
| 154 | }); |
| 155 | break; |
| 156 | } |
no test coverage detected