@overpod/mcp-telegram 1.8.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +21 -1
- package/dist/telegram-client.d.ts +19 -0
- package/dist/telegram-client.js +99 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -183,7 +183,7 @@ server.tool("telegram-search-chats", "Search for Telegram chats/users/channels b
|
|
|
183
183
|
try {
|
|
184
184
|
const results = await telegram.searchChats(query, limit);
|
|
185
185
|
const text = results
|
|
186
|
-
.map((c) => `${c.type === "group" ? "G" : c.type === "channel" ? "C" : "P"} ${c.name}${c.username ? ` (@${c.username})` : ""} (${c.id})`)
|
|
186
|
+
.map((c) => `${c.type === "group" ? "G" : c.type === "channel" ? "C" : "P"} ${c.name}${c.username ? ` (@${c.username})` : ""} (${c.id})${c.membersCount ? ` [${c.membersCount} members]` : ""}${c.description ? ` — ${c.description.split("\n")[0].slice(0, 100)}` : ""}`)
|
|
187
187
|
.join("\n");
|
|
188
188
|
return { content: [{ type: "text", text: text || "No results" }] };
|
|
189
189
|
}
|
|
@@ -191,6 +191,26 @@ server.tool("telegram-search-chats", "Search for Telegram chats/users/channels b
|
|
|
191
191
|
return { content: [{ type: "text", text: `Error: ${e.message}` }] };
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
|
+
server.tool("telegram-search-global", "Search messages globally across all public Telegram chats and channels", {
|
|
195
|
+
query: z.string().describe("Search text"),
|
|
196
|
+
limit: z.number().default(20).describe("Max results"),
|
|
197
|
+
minDate: z.number().optional().describe("Unix timestamp: only messages after this date"),
|
|
198
|
+
maxDate: z.number().optional().describe("Unix timestamp: only messages before this date"),
|
|
199
|
+
}, async ({ query, limit, minDate, maxDate }) => {
|
|
200
|
+
const err = await requireConnection();
|
|
201
|
+
if (err)
|
|
202
|
+
return { content: [{ type: "text", text: err }] };
|
|
203
|
+
try {
|
|
204
|
+
const messages = await telegram.searchGlobal(query, limit, minDate, maxDate);
|
|
205
|
+
const text = messages
|
|
206
|
+
.map((m) => `[${m.date}] [${m.chat.type === "channel" ? "C" : m.chat.type === "group" ? "G" : "P"} ${m.chat.name}${m.chat.username ? ` @${m.chat.username}` : ""}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}`)
|
|
207
|
+
.join("\n\n");
|
|
208
|
+
return { content: [{ type: "text", text: text || "No messages found" }] };
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
return { content: [{ type: "text", text: `Error: ${e.message}` }] };
|
|
212
|
+
}
|
|
213
|
+
});
|
|
194
214
|
server.tool("telegram-search-messages", "Search messages in a Telegram chat by text", {
|
|
195
215
|
chatId: z.string().describe("Chat ID or username"),
|
|
196
216
|
query: z.string().describe("Search text"),
|
|
@@ -116,6 +116,25 @@ export declare class TelegramService {
|
|
|
116
116
|
name: string;
|
|
117
117
|
type: string;
|
|
118
118
|
username?: string;
|
|
119
|
+
membersCount?: number;
|
|
120
|
+
description?: string;
|
|
121
|
+
}>>;
|
|
122
|
+
searchGlobal(query: string, limit?: number, minDate?: number, maxDate?: number): Promise<Array<{
|
|
123
|
+
id: number;
|
|
124
|
+
text: string;
|
|
125
|
+
sender: string;
|
|
126
|
+
date: string;
|
|
127
|
+
chat: {
|
|
128
|
+
id: string;
|
|
129
|
+
name: string;
|
|
130
|
+
type: string;
|
|
131
|
+
username?: string;
|
|
132
|
+
};
|
|
133
|
+
media?: {
|
|
134
|
+
type: string;
|
|
135
|
+
fileName?: string;
|
|
136
|
+
size?: number;
|
|
137
|
+
};
|
|
119
138
|
}>>;
|
|
120
139
|
searchMessages(chatId: string, query: string, limit?: number, minDate?: number, maxDate?: number): Promise<Array<{
|
|
121
140
|
id: number;
|
package/dist/telegram-client.js
CHANGED
|
@@ -642,7 +642,12 @@ export class TelegramService {
|
|
|
642
642
|
}
|
|
643
643
|
for (const chat of result.chats) {
|
|
644
644
|
if (chat instanceof Api.Chat) {
|
|
645
|
-
chats.push({
|
|
645
|
+
chats.push({
|
|
646
|
+
id: chat.id.toString(),
|
|
647
|
+
name: chat.title,
|
|
648
|
+
type: "group",
|
|
649
|
+
membersCount: chat.participantsCount ?? undefined,
|
|
650
|
+
});
|
|
646
651
|
}
|
|
647
652
|
else if (chat instanceof Api.Channel) {
|
|
648
653
|
chats.push({
|
|
@@ -650,11 +655,104 @@ export class TelegramService {
|
|
|
650
655
|
name: chat.title,
|
|
651
656
|
type: chat.megagroup ? "group" : "channel",
|
|
652
657
|
username: chat.username ?? undefined,
|
|
658
|
+
membersCount: chat.participantsCount ?? undefined,
|
|
653
659
|
});
|
|
654
660
|
}
|
|
655
661
|
}
|
|
662
|
+
// Enrich channels/groups with description and accurate members count
|
|
663
|
+
for (const chat of chats) {
|
|
664
|
+
if (chat.type === "private")
|
|
665
|
+
continue;
|
|
666
|
+
try {
|
|
667
|
+
const entity = await this.client.getEntity(chat.id);
|
|
668
|
+
if (entity instanceof Api.Channel) {
|
|
669
|
+
const full = await this.client.invoke(new Api.channels.GetFullChannel({ channel: entity }));
|
|
670
|
+
if (full.fullChat instanceof Api.ChannelFull) {
|
|
671
|
+
chat.description = full.fullChat.about || undefined;
|
|
672
|
+
chat.membersCount = full.fullChat.participantsCount ?? chat.membersCount;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
else if (entity instanceof Api.Chat) {
|
|
676
|
+
const full = await this.client.invoke(new Api.messages.GetFullChat({ chatId: entity.id }));
|
|
677
|
+
if (full.fullChat instanceof Api.ChatFull) {
|
|
678
|
+
chat.description = full.fullChat.about || undefined;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
catch {
|
|
683
|
+
// Skip enrichment on error (private channels, etc.)
|
|
684
|
+
}
|
|
685
|
+
}
|
|
656
686
|
return chats;
|
|
657
687
|
}
|
|
688
|
+
async searchGlobal(query, limit = 20, minDate, maxDate) {
|
|
689
|
+
if (!this.client || !this.connected)
|
|
690
|
+
throw new Error("Not connected");
|
|
691
|
+
const result = await this.client.invoke(new Api.messages.SearchGlobal({
|
|
692
|
+
q: query,
|
|
693
|
+
filter: new Api.InputMessagesFilterEmpty(),
|
|
694
|
+
minDate: minDate || 0,
|
|
695
|
+
maxDate: maxDate || 0,
|
|
696
|
+
offsetRate: 0,
|
|
697
|
+
offsetPeer: new Api.InputPeerEmpty(),
|
|
698
|
+
offsetId: 0,
|
|
699
|
+
limit,
|
|
700
|
+
}));
|
|
701
|
+
const chatsMap = new Map();
|
|
702
|
+
if ("chats" in result) {
|
|
703
|
+
for (const chat of result.chats) {
|
|
704
|
+
if (chat instanceof Api.Channel) {
|
|
705
|
+
chatsMap.set(chat.id.toString(), {
|
|
706
|
+
id: chat.id.toString(),
|
|
707
|
+
name: chat.title,
|
|
708
|
+
type: chat.megagroup ? "group" : "channel",
|
|
709
|
+
username: chat.username ?? undefined,
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
else if (chat instanceof Api.Chat) {
|
|
713
|
+
chatsMap.set(chat.id.toString(), {
|
|
714
|
+
id: chat.id.toString(),
|
|
715
|
+
name: chat.title,
|
|
716
|
+
type: "group",
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
if ("users" in result) {
|
|
722
|
+
for (const user of result.users) {
|
|
723
|
+
if (user instanceof Api.User) {
|
|
724
|
+
const parts = [user.firstName, user.lastName].filter(Boolean);
|
|
725
|
+
chatsMap.set(user.id.toString(), {
|
|
726
|
+
id: user.id.toString(),
|
|
727
|
+
name: parts.join(" ") || "Unknown",
|
|
728
|
+
type: "private",
|
|
729
|
+
username: user.username ?? undefined,
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
const rawMessages = "messages" in result ? result.messages : [];
|
|
735
|
+
const messages = rawMessages.filter((m) => m instanceof Api.Message);
|
|
736
|
+
const results = await Promise.all(messages.map(async (m) => {
|
|
737
|
+
const peerId = m.peerId;
|
|
738
|
+
let chatId = "";
|
|
739
|
+
if (peerId instanceof Api.PeerChannel)
|
|
740
|
+
chatId = peerId.channelId.toString();
|
|
741
|
+
else if (peerId instanceof Api.PeerChat)
|
|
742
|
+
chatId = peerId.chatId.toString();
|
|
743
|
+
else if (peerId instanceof Api.PeerUser)
|
|
744
|
+
chatId = peerId.userId.toString();
|
|
745
|
+
return {
|
|
746
|
+
id: m.id,
|
|
747
|
+
text: m.message ?? "",
|
|
748
|
+
sender: await this.resolveSenderName(m.senderId),
|
|
749
|
+
date: new Date((m.date ?? 0) * 1000).toISOString(),
|
|
750
|
+
chat: chatsMap.get(chatId) || { id: chatId, name: "Unknown", type: "unknown" },
|
|
751
|
+
media: this.extractMediaInfo(m.media),
|
|
752
|
+
};
|
|
753
|
+
}));
|
|
754
|
+
return results;
|
|
755
|
+
}
|
|
658
756
|
async searchMessages(chatId, query, limit = 20, minDate, maxDate) {
|
|
659
757
|
if (!this.client || !this.connected)
|
|
660
758
|
throw new Error("Not connected");
|
package/package.json
CHANGED