Telegram网页端控制台JS标记消息已读的技术求助
Telegram网页端控制台JS标记消息已读的技术求助
兄弟我太懂你这个痛点了!之前做类似的Telegram网页端消息抓取工具时,也被这个“未读消息锁死滚动+不加载新DOM”的坑折腾过好一阵。
先给你理清楚核心问题:Telegram网页端的逻辑是只要聊天里存在未读消息,它就会强制把视图拉回未读消息的位置,而且不会加载更旧的历史消息——你的滚动函数只是单纯把列表滚到底,但完全没触发Telegram内部的“标记消息为已读”的逻辑,所以系统一直认为还有未读消息,自然不会给你加载新的DOM元素。
下面给你几个亲测有效的解决方案,直接在控制台里就能用:
方案1:模拟用户操作触发已读标记(最稳定,不易失效)
这个方法是模拟用户点击未读标记、触发滚动事件的真实操作,Telegram的前端会识别这个行为并标记消息为已读。
先写一个标记已读的辅助函数,再和你的滚动逻辑结合:
// 标记所有未读消息为已读 function markAllMessagesAsRead() { // 匹配Telegram网页端未读消息的标记元素(类名可能随版本微调,可自行在控制台用document.querySelectorAll验证) const unreadElements = document.querySelectorAll('.Message.unread, .UnreadBadge, .MessageList-unreadMarker'); unreadElements.forEach(el => { // 模拟鼠标点击事件,触发Telegram的已读逻辑 el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true })); // 额外触发focus事件,确保Telegram捕捉到状态变化 el.dispatchEvent(new FocusEvent('focus', { bubbles: true })); }); // 给聊天容器再触发一次scroll事件,让系统确认所有消息已可见 const chatContainer = document.querySelector('.ChatContainer'); if (chatContainer) { chatContainer.dispatchEvent(new Event('scroll', { bubbles: true })); } } // 滚动到底部并标记已读的组合函数 function scrollToBottomAndMarkRead() { const messageList = document.querySelector('.MessageList'); if (!messageList) return; // 先滚动到底部 messageList.scrollTop = messageList.scrollHeight; // 标记已读 markAllMessagesAsRead(); // 延迟500ms再滚一次,等待Telegram加载新的历史消息(DOM更新是异步的) setTimeout(() => { messageList.scrollTop = messageList.scrollHeight; }, 500); }
你只需要在控制台里运行scrollToBottomAndMarkRead(),代替原来的scrollChatToBottom()就行。如果发现类名不对,直接用控制台的元素选择器工具,找未读消息对应的类名替换就行。
方案2:调用Telegram内部的已读方法(更直接,但可能随版本失效)
Telegram网页端是基于React开发的,内部有状态管理的store,里面有直接标记已读的方法。你可以尝试在控制台里调用这个内部方法:
// 尝试找到并调用Telegram内部的标记已读方法 function callInternalMarkAsRead() { // 遍历React DevTools暴露的内部store,找到带markAsRead方法的实例 if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) { const renderers = window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers; if (renderers.length > 0) { const stores = Object.values(renderers[0].internalStore); for (const store of stores) { if (typeof store.markAsRead === 'function') { store.markAsRead(); console.log('已调用内部方法标记为已读'); break; } } } } }
这个方法更直接,但要注意:Telegram的前端版本更新后,内部store的结构可能会变,导致这个方法失效,所以优先用方案1。
额外提醒
- 如果滚动后还是没加载新消息,可以把
setTimeout的延迟时间调长一点(比如1000ms),给Telegram的DOM更新留足时间 - 不要太频繁调用这个函数,避免触发Telegram的反爬限制(毕竟是网页端,太频繁的自动化操作可能会被临时限制)
备注:内容来源于stack exchange,提问作者struggleendlessly




