使用WTelegramClient转发媒体消息触发MEDIA_EMPTY异常求助
问题
修改WTelegramClient的Program_ListenUpdates示例实现消息转发功能,纯文本消息转发正常,但带媒体(如图片)的消息会触发400 MEDIA_EMPTY异常,所有带媒体消息均存在此问题。Peer初始化正常,直接调用client.Messages_SendMedia也报错。打印媒体信息显示:d.flags为has_photo、d.photo.ID为5949672085112603217、d.ttl_seconds为0、m.flags为has_from_id, has_media, has_replies。尝试保存媒体到磁盘时还触发FILE_REFERENCE_EXPIRED异常,公群和私聊测试结果一致。
代码如下:
public MessageMedia MediaMSG=null; .... Manager = client.WithUpdateManager(Client_OnUpdate/*, "Updates.state"*/); var dialogs = client.Messages_GetAllDialogs(); // dialogs = groups/channels/users dialogs.Wait(); dialogs.Result.CollectUsersChats(Manager.Users, Manager.Chats); /***/ private async Task Client_OnUpdate(Update update) { switch (update) { case UpdateNewMessage unm: await HandleMessage(unm.message); break; } } /***/ private Task HandleMessage(MessageBase messageBase, bool edit = false) { switch (messageBase) { case TL.Message m: InputPeer peer = null; //set peer a value for example user or chat //peer =..... Task<TL.Message> PostResult = null; CancellationTokenSource cancellationSource = new CancellationTokenSource(); CancellationToken cancellation = cancellationSource.Token; MediaMSG = m.media; MessageMediaPhoto d = null; if (MediaMSG.GetType() == typeof(MessageMediaPhoto)) { d=new MessageMediaPhoto(); d.flags = ((MessageMediaPhoto)MediaMSG).flags; d.photo = ((MessageMediaPhoto)MediaMSG).photo; d.ttl_seconds= ((MessageMediaPhoto)MediaMSG).ttl_seconds; MessageBox.Show(d.flags.ToString() + ":" + d.photo.ID + " :" + d.ttl_seconds+":"+ m.flags.ToString()); File.WriteAllText("a.txt", d.flags.ToString() + ":" + d.photo.ID + " :" + d.ttl_seconds + ":" + m.flags.ToString()); } PostResult = client.SendMessageAsync(peer, m.message, d?.ToInputMedia()); PostResult.Wait(cancellation); break; case MessageService ms: /*Console.WriteLine($"{Peer(ms.from_id)} in {Peer(ms.peer_id)} [{ms.action.GetType().Name[13..]}]");*/ break; } return Task.CompletedTask; }
解决方案
1. 优先使用官方转发API
Telegram提供了专门的消息转发方法,无需手动构造媒体对象,从根源避免媒体无效问题。替换原SendMessageAsync调用为ForwardMessagesAsync:
// 替换原PostResult相关代码 await client.ForwardMessagesAsync( peer, // 目标聊天/用户对象 new[] { m.ID }, // 要转发的消息ID数组 m.peer_id.ToInputPeer() // 原消息所在的聊天/用户 );
2. 手动复用媒体时补全文件引用
若必须手动构造媒体对象,原Photo可能缺少有效file_reference导致异常,需先获取完整媒体信息:
if (m.media is MessageMediaPhoto mediaPhoto) { // 获取包含有效file_reference的完整Photo对象 await client.GetFileAsync(mediaPhoto.photo, default, 1); // 构造合法的InputMedia var inputMedia = new InputMediaPhoto { id = mediaPhoto.photo.ToInputPhoto() }; await client.SendMessageAsync(peer, m.message, inputMedia); }
3. 修正异步任务处理方式
原代码用PostResult.Wait(cancellation)易引发死锁,改用await处理异步操作,同时修正方法签名:
private async Task HandleMessage(MessageBase messageBase, bool edit = false) { switch (messageBase) { case TL.Message m: InputPeer peer = null; // 初始化目标peer... if (m.media != null) { await client.ForwardMessagesAsync(peer, new[] { m.ID }, m.peer_id.ToInputPeer()); } else { await client.SendMessageAsync(peer, m.message); } break; case MessageService ms: break; } }
4. 确保用户/聊天信息缓存完整
初始化时正确收集用户和聊天数据,避免Peer解析错误:
var dialogs = await client.Messages_GetAllDialogs(); dialogs.CollectUsersChats(client.Users, client.Chats);
内容的提问来源于stack exchange,提问作者Fath Bakri
相关产品推荐
相关产品推荐

