使用WTelegramClient调用Users_GetFullUser遇USER_ID_INVALID错误
问题分析与解决思路
首先明确:这不是Telegram的限制,大概率是你对消息发送者的类型判断或access_hash处理有误,以下是常见原因和解决方法:
常见问题点
- 发送者不是普通用户:群组里的消息可能来自频道、匿名账号或机器人,这类对象的ID格式和普通用户不同,用
InputUser构造会触发ID无效错误。比如频道消息转发到群组时,message.From指向的是频道而非用户,这时候需要用InputUserFromChannel而非InputUser。 - access_hash过期/不正确:
Users字典里的用户对象可能是缓存的旧数据,access_hash已经失效;或者你根本没正确获取到该发送者的access_hash(比如Users.TryGetValue返回false,但你没做判断就直接用u.access_hash)。 - 匿名消息特殊处理:部分群组支持匿名发送消息,这类消息的
From.ID是Telegram预留的特殊ID,无法通过Users_GetFullUser获取信息,需要提前判断跳过。
修复代码示例
先添加类型判断和空值检查,再针对性处理:
// 先检查发送者是否存在于本地缓存 if (!Users.TryGetValue(unm.message.From.ID, out var u)) { // 缓存里没有,先调用Users_GetUsers获取最新信息 var users = await Client.Users_GetUsers(new[] { new InputUser(unm.message.From.ID, 0) }); u = users.FirstOrDefault(); if (u == null) { // 无法获取用户信息,可能是匿名/频道,直接跳过 return; } // 更新本地缓存 Users[unm.message.From.ID] = u; } // 判断发送者类型,选择正确的Input参数 InputUserBase inputUser; if (u is Channel channel) { inputUser = new InputUserFromChannel(new InputChannel(channel.ID, channel.access_hash)); } else { inputUser = new InputUser(u.ID, u.access_hash); } // 调用获取完整用户信息 try { var usr = await Client.Users_GetFullUser(inputUser); // 处理用户信息 } catch (Exception ex) { // 捕获异常,比如匿名消息的情况 Console.WriteLine($"获取用户信息失败: {ex.Message}"); }
额外建议
- 每次处理新消息前,先确认
message.From的实际类型(通过is关键字判断),不同类型对应不同的Input构造方式。 - 不要依赖本地缓存的
Users字典,遇到缓存缺失时主动调用Users_GetUsers拉取最新数据,确保access_hash有效。
内容的提问来源于stack exchange,提问作者Nigrimmist
相关产品推荐
相关产品推荐

