如何用GramJS处理Telegram频道消息合并与避免重复监听?
解决GramJS监听Telegram频道消息的合并与兼容问题
方案一:单一NewMessage监听器+手动合并相册消息
利用Telegram消息自带的groupedId字段,同相册的所有消息会共享同一个groupedId。我们可以通过缓存暂存未完成的相册消息,等待同组消息全部抵达后统一处理,同时直接处理无groupedId的单图/纯文本消息。
示例代码:
// 缓存待合并的相册消息,key为groupedId,value为消息数组 const pendingAlbums = new Map(); // 超时时间(同相册消息基本会在1秒内全部到达) const ALBUM_TIMEOUT = 1000; client.addEventHandler(async (event) => { const message = event.message; // 处理单图/纯文本等非相册消息 if (!message.groupedId) { handleSingleMessage(message); return; } // 处理相册消息:加入缓存 if (!pendingAlbums.has(message.groupedId)) { pendingAlbums.set(message.groupedId, []); // 设置超时,避免因消息丢失导致缓存一直存在 setTimeout(() => { if (pendingAlbums.has(message.groupedId)) { const albumMessages = pendingAlbums.get(message.groupedId); handleAlbumMessage(albumMessages); pendingAlbums.delete(message.groupedId); } }, ALBUM_TIMEOUT); } pendingAlbums.get(message.groupedId).push(message); }, new NewMessage({chats: [someId]})); // 处理单条消息的逻辑 function handleSingleMessage(message) { console.log('处理单条消息:', message.text || '无文本'); // 你的业务逻辑 } // 处理合并后的相册消息逻辑 function handleAlbumMessage(albumMessages) { console.log('处理相册消息,共', albumMessages.length, '条'); // 可以提取第一条消息的描述,加上所有图片 const description = albumMessages[0].text || ''; const mediaList = albumMessages.map(msg => msg.media); // 你的业务逻辑 }
方案二:同时使用Album和NewMessage监听器,过滤重复消息
保留Album监听器处理多图相册,同时用NewMessage处理单图/纯文本消息,通过记录已处理的消息ID避免重复触发。
示例代码:
// 记录已被Album监听器处理的消息ID,定期清理避免内存溢出 const processedMessageIds = new Set(); const CLEANUP_INTERVAL = 5 * 60 * 1000; // 5分钟清理一次 // 启动定时清理 setInterval(() => { processedMessageIds.clear(); }, CLEANUP_INTERVAL); // Album监听器:处理多图相册 client.addEventHandler((event) => { const albumMessages = event.messages; console.log('处理相册消息,共', albumMessages.length, '条'); // 记录所有消息ID,避免NewMessage重复处理 albumMessages.forEach(msg => processedMessageIds.add(msg.id)); // 你的相册业务逻辑 }, new Album({chats: [someId]})); // NewMessage监听器:处理单图/纯文本,跳过已被Album处理的消息 client.addEventHandler((event) => { const message = event.message; if (processedMessageIds.has(message.id)) { return; // 跳过已处理的相册消息 } console.log('处理单条消息:', message.text || '无文本'); // 你的单条消息业务逻辑 }, new NewMessage({chats: [someId]}));
补充:通过API主动获取完整帖文
如果上述监听器方案不满足需求,也可以在收到消息后,调用client.getMessages主动拉取完整的关联消息。比如当收到一条带groupedId的消息时,请求频道内同groupedId的所有消息:
client.addEventHandler(async (event) => { const message = event.message; if (message.groupedId) { // 拉取同groupedId的所有消息 const albumMessages = await client.getMessages(someId, { filter: { _: 'inputMessagesFilterPhotos' }, groupedId: message.groupedId }); handleAlbumMessage(albumMessages); } else { handleSingleMessage(message); } }, new NewMessage({chats: [someId]}));
这种方式不需要依赖缓存,但需要额外的API请求,适合对实时性要求不高的场景。
内容的提问来源于stack exchange,提问作者Andrey Kuzmin
相关产品推荐
相关产品推荐

