Skip to content

Commit 861eb92

Browse files
authored
Merge pull request #10 from IQAIcom/patch-2
2 parents 82afeba + 90dc661 commit 861eb92

File tree

8 files changed

+57
-2
lines changed

8 files changed

+57
-2
lines changed

.changeset/cyan-masks-fail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@iqai/mcp-telegram": patch
3+
---
4+
5+
Added support for messaging on topic channels of forum type groups

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Send a message to a Telegram chat or channel.
5959

6060
- `chatId`: Chat ID or username (e.g., @channelname or -1001234567890)
6161
- `text`: Message text
62+
- `topicId`: Optional topic ID for forum channels
6263
- `parseMode`: Optional formatting (HTML, Markdown, MarkdownV2)
6364
- `disableWebPagePreview`: Optional boolean
6465
- `disableNotification`: Optional boolean for silent messages
@@ -311,6 +312,8 @@ The system uses customizable templates for different message types:
311312
- **Contact**: Contact information
312313
- **Poll**: Poll questions and options
313314

315+
All message templates include topic ID information for forum channels, allowing the AI to understand the context of which topic thread the message belongs to.
316+
314317
### Customization
315318

316319
To customize the sampling behavior:
@@ -367,6 +370,19 @@ Send a message to a Telegram channel:
367370
}
368371
```
369372

373+
Send a message to a specific topic in a forum channel:
374+
375+
```json
376+
{
377+
"tool_name": "SEND_MESSAGE",
378+
"arguments": {
379+
"chatId": "@mychannel",
380+
"text": "Hello from the Telegram MCP Server!",
381+
"topicId": 123
382+
}
383+
}
384+
```
385+
370386
### GET_CHANNEL_INFO
371387

372388
Get information about a Telegram channel:

src/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ user_id: {userId}
157157
chat_id: {chatId}
158158
isDM: {isDM}
159159
message_id: {messageId}
160+
topic_id: {topicId}
160161
message_type: ${MessageType.TEXT}
161162
content: {content}`,
162163

@@ -165,6 +166,7 @@ user_id: {userId}
165166
chat_id: {chatId}
166167
isDM: {isDM}
167168
message_id: {messageId}
169+
topic_id: {topicId}
168170
message_type: ${MessageType.PHOTO}
169171
caption: {caption}
170172
photo_info: {photoInfo}`,
@@ -174,6 +176,7 @@ user_id: {userId}
174176
chat_id: {chatId}
175177
isDM: {isDM}
176178
message_id: {messageId}
179+
topic_id: {topicId}
177180
message_type: ${MessageType.DOCUMENT}
178181
filename: {fileName}
179182
mime_type: {mimeType}
@@ -184,6 +187,7 @@ user_id: {userId}
184187
chat_id: {chatId}
185188
isDM: {isDM}
186189
message_id: {messageId}
190+
topic_id: {topicId}
187191
message_type: ${MessageType.VOICE}
188192
duration: {duration}s`,
189193

@@ -192,6 +196,7 @@ user_id: {userId}
192196
chat_id: {chatId}
193197
isDM: {isDM}
194198
message_id: {messageId}
199+
topic_id: {topicId}
195200
message_type: ${MessageType.VIDEO}
196201
caption: {caption}
197202
duration: {duration}s`,
@@ -201,6 +206,7 @@ user_id: {userId}
201206
chat_id: {chatId}
202207
isDM: {isDM}
203208
message_id: {messageId}
209+
topic_id: {topicId}
204210
message_type: ${MessageType.STICKER}
205211
emoji: {stickerEmoji}
206212
set_name: {stickerSetName}`,
@@ -210,6 +216,7 @@ user_id: {userId}
210216
chat_id: {chatId}
211217
isDM: {isDM}
212218
message_id: {messageId}
219+
topic_id: {topicId}
213220
message_type: ${MessageType.LOCATION}
214221
latitude: {latitude}
215222
longitude: {longitude}`,
@@ -219,6 +226,7 @@ user_id: {userId}
219226
chat_id: {chatId}
220227
isDM: {isDM}
221228
message_id: {messageId}
229+
topic_id: {topicId}
222230
message_type: ${MessageType.CONTACT}
223231
contact_name: {contactName}
224232
phone_number: {phoneNumber}`,
@@ -228,6 +236,7 @@ user_id: {userId}
228236
chat_id: {chatId}
229237
isDM: {isDM}
230238
message_id: {messageId}
239+
topic_id: {topicId}
231240
message_type: ${MessageType.POLL}
232241
question: {pollQuestion}
233242
options: {pollOptions}`,
@@ -237,6 +246,7 @@ user_id: {userId}
237246
chat_id: {chatId}
238247
isDM: {isDM}
239248
message_id: {messageId}
249+
topic_id: {topicId}
240250
message_type: {messageType}
241251
content: {content}`,
242252
},

src/sampling/handler.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ export class SamplingHandler {
171171
await this.telegramService.sendMessage(
172172
request.chatId,
173173
"Sorry, the AI service is not available right now.",
174+
request.templateData.topicId,
174175
);
175176
}
176177
return;
@@ -212,7 +213,11 @@ export class SamplingHandler {
212213

213214
// Send response back to Telegram (unless in silent mode)
214215
if (!samplingConfig.silentMode) {
215-
await this.telegramService.sendMessage(request.chatId, responseText);
216+
await this.telegramService.sendMessage(
217+
request.chatId,
218+
responseText,
219+
request.templateData.topicId,
220+
);
216221
}
217222

218223
console.log(
@@ -225,6 +230,7 @@ export class SamplingHandler {
225230
await this.telegramService.sendMessage(
226231
request.chatId,
227232
"Sorry, I encountered an error while processing your request. Please try again.",
233+
request.templateData.topicId,
228234
);
229235
}
230236
}

src/sampling/message-handlers.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export function handleTextMessage(ctx: Context): MessageTemplateData | null {
1212
chatId: ctx.chat.id,
1313
isDM: ctx.chat.id === msg.from.id,
1414
messageId: msg.message_id,
15+
topicId: msg.message_thread_id,
1516
messageType: MessageType.TEXT,
1617
};
1718
}
@@ -30,6 +31,7 @@ export function handlePhotoMessage(ctx: Context): MessageTemplateData | null {
3031
chatId: ctx.chat.id,
3132
isDM: ctx.chat.id === msg.from.id,
3233
messageId: msg.message_id,
34+
topicId: msg.message_thread_id,
3335
messageType: MessageType.PHOTO,
3436
};
3537
}
@@ -51,6 +53,7 @@ export function handleDocumentMessage(
5153
chatId: ctx.chat.id,
5254
isDM: ctx.chat.id === msg.from.id,
5355
messageId: msg.message_id,
56+
topicId: msg.message_thread_id,
5457
messageType: MessageType.DOCUMENT,
5558
};
5659
}
@@ -68,6 +71,7 @@ export function handleVoiceMessage(ctx: Context): MessageTemplateData | null {
6871
chatId: ctx.chat.id,
6972
isDM: ctx.chat.id === msg.from.id,
7073
messageId: msg.message_id,
74+
topicId: msg.message_thread_id,
7175
messageType: MessageType.VOICE,
7276
};
7377
}
@@ -86,6 +90,7 @@ export function handleVideoMessage(ctx: Context): MessageTemplateData | null {
8690
chatId: ctx.chat.id,
8791
isDM: ctx.chat.id === msg.from.id,
8892
messageId: msg.message_id,
93+
topicId: msg.message_thread_id,
8994
messageType: MessageType.VIDEO,
9095
};
9196
}
@@ -104,6 +109,7 @@ export function handleStickerMessage(ctx: Context): MessageTemplateData | null {
104109
chatId: ctx.chat.id,
105110
isDM: ctx.chat.id === msg.from.id,
106111
messageId: msg.message_id,
112+
topicId: msg.message_thread_id,
107113
messageType: MessageType.STICKER,
108114
};
109115
}
@@ -124,6 +130,7 @@ export function handleLocationMessage(
124130
chatId: ctx.chat.id,
125131
isDM: ctx.chat.id === msg.from.id,
126132
messageId: msg.message_id,
133+
topicId: msg.message_thread_id,
127134
messageType: MessageType.LOCATION,
128135
};
129136
}
@@ -142,6 +149,7 @@ export function handleContactMessage(ctx: Context): MessageTemplateData | null {
142149
chatId: ctx.chat.id,
143150
isDM: ctx.chat.id === msg.from.id,
144151
messageId: msg.message_id,
152+
topicId: msg.message_thread_id,
145153
messageType: MessageType.CONTACT,
146154
};
147155
}
@@ -160,6 +168,7 @@ export function handlePollMessage(ctx: Context): MessageTemplateData | null {
160168
chatId: ctx.chat.id,
161169
isDM: ctx.chat.id === msg.from.id,
162170
messageId: msg.message_id,
171+
topicId: msg.message_thread_id,
163172
messageType: MessageType.POLL,
164173
};
165174
}

src/sampling/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export interface MessageTemplateData {
5252
chatId: number;
5353
isDM: boolean;
5454
messageId: number;
55+
topicId?: number;
5556
messageType?: string;
5657
caption?: string;
5758
photoInfo?: string;

src/services/telegram-service.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ export class TelegramService {
3030
async sendMessage(
3131
chatId: string | number,
3232
text: string,
33+
topicId?: number,
3334
): Promise<MessageInfo> {
3435
try {
35-
const message = await this.bot.telegram.sendMessage(chatId, text);
36+
const message = await this.bot.telegram.sendMessage(chatId, text, {
37+
message_thread_id: topicId,
38+
});
3639

3740
return {
3841
messageId: message.message_id,

src/tools/send-message.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ const sendMessageParams = z.object({
99
"The chat ID or channel username (e.g., @channelname or -1001234567890)",
1010
),
1111
text: z.string().min(1).describe("The message text to send"),
12+
topicId: z
13+
.number()
14+
.optional()
15+
.describe("The topic ID for forum channels (optional)"),
1216
});
1317

1418
type SendMessageParams = z.infer<typeof sendMessageParams>;
@@ -24,6 +28,7 @@ export const sendMessageTool = {
2428
const messageInfo = await telegramService.sendMessage(
2529
params.chatId,
2630
params.text,
31+
params.topicId,
2732
);
2833

2934
return dedent`

0 commit comments

Comments
 (0)