You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:08:20