如何判断WTelegramClient发送的Telegram消息已被对方查看?
用WTelegramClient确认消息已读的正确方式
问题分析
你发送就诊提醒后想要确认消息已读,尝试通过has_views标记实现但失败,核心问题在于对消息对象的类型处理和flags枚举的判断方式有误。
常见错误点
- 类型丢失:发送消息时用
object接收返回值,无法直接访问Message的属性和flags。 - 错误的flags判断:
dialogs.messages[0].flag.has_views的写法不正确,flags是枚举值,需要通过位运算判断是否包含目标标记,且需先将消息转换为Message类型。 - 消息定位错误:
dialogs.messages[0]不一定是你发送的那条消息,直接取第一条无法准确判断目标消息的状态。
正确实现方式
方式一:轮询检查消息状态
发送消息后定期获取对话历史,定位目标消息并判断已读状态:
using var client = new WTelegram.Client(Config); var user = await client.LoginUserIfNeeded(); var contact = await client.Contacts_ImportContacts(new[] { new InputPhoneContact { phone = phoneNumber } }); var targetUser = contact.users.Values.First(); // 发送消息并获取具体的Message对象 var sentMessage = await client.SendMessageAsync(targetUser, patientMessage) as Message; if (sentMessage == null) { Console.WriteLine("消息发送失败"); return; } // 轮询检查消息是否被读取 while (true) { // 获取目标用户的对话历史 var history = await client.Messages_GetHistory(new InputPeerUser(targetUser.id, targetUser.access_hash), limit: 10); // 定位发送的那条消息 var targetMessage = history.messages.OfType<Message>().FirstOrDefault(m => m.id == sentMessage.id); if (targetMessage != null) { // 方式1:通过flags判断是否已被查看(HasViews标记表示消息已被打开) if ((targetMessage.Flags & MessageFlags.HasViews) != 0) { Console.WriteLine("消息已被患者读取"); break; } // 方式2:通过views字段判断,views>0表示有用户查看过消息 if (targetMessage.views > 0) { Console.WriteLine("消息已被患者读取"); break; } } await Task.Delay(5000); // 每隔5秒检查一次 }
方式二:监听更新事件(推荐)
通过客户端的更新监听机制,实时接收消息已读的通知,无需轮询:
using var client = new WTelegram.Client(Config); var user = await client.LoginUserIfNeeded(); var contact = await client.Contacts_ImportContacts(new[] { new InputPhoneContact { phone = phoneNumber } }); var targetUser = contact.users.Values.First(); var sentMessage = await client.SendMessageAsync(targetUser, patientMessage) as Message; if (sentMessage == null) { Console.WriteLine("消息发送失败"); return; } // 注册更新监听事件 client.OnUpdate += async update => { // 处理消息查看次数更新 if (update is UpdateMessageViews updateViews) { if (updateViews.id == sentMessage.id && updateViews.views > 0) { Console.WriteLine("消息已被患者读取"); // 停止监听(可选) client.OnUpdate -= update; } } // 处理对话已读标记更新 else if (update is UpdateReadHistoryInbox updateRead) { if (updateRead.peer is PeerUser peerUser && peerUser.user_id == targetUser.id) { // 若对话已读的最大消息ID大于等于发送的消息ID,说明消息已被读取 if (updateRead.max_id >= sentMessage.id) { Console.WriteLine("消息已被患者读取"); client.OnUpdate -= update; } } } return Task.CompletedTask; }; // 保持客户端运行以接收更新 await Task.Delay(-1);
内容的提问来源于stack exchange,提问作者Boomkok
相关产品推荐
相关产品推荐

