如何让WTelegramClient跨频道同步消息时显示原生回复样式
实现WTelegramClient原生引用回复同步频道消息
我正在使用WTelegramClient监听某频道更新并同步消息至另一频道。目前通过拼接原消息与回复消息的方式处理回复,但希望实现Telegram原生的带引用回复预览样式。原频道原生回复样式如图所示,目标频道当前显示效果不符合预期,以下是当前使用的代码片段:
private async Task<Task> DisplayMessage(MessageBase messageBase, bool edit = false) { if (edit) Console.Write("(Edit): "); switch (messageBase) { case TL.Message m: if (m.Peer.ID == from.ID) { string message = $"{m.message}"; Console.WriteLine(message); if (messageBase.ReplyTo != null) { var chats = await Client.Messages_GetAllChats(); InputPeer peer = chats.chats[from.ID]; Messages_MessagesBase repMessage = await Client.Messages_GetHistory(peer); TL.Message repliee = (TL.Message)repMessage.Messages[0]; if (repMessage.Messages.Length > 0) { foreach (var msg in repMessage.Messages) { if (msg.ID == m.reply_to.reply_to_msg_id) { repliee = (TL.Message)msg; } } } TargetLog(repliee.message + Environment.NewLine + Environment.NewLine + "UPDATE:" + Environment.NewLine + message); } else { await Client.Messages_ForwardMessages(from, new[] { messageBase.ID }, new[] { WTelegram.Helpers.RandomLong() }, to, drop_author: true); } } } } private async Task TargetLog(string txt) { await Client.SendMessageAsync(to, txt); }
修改方案
要实现原生引用回复,不能直接拼接文本,需利用Telegram API的reply_to_msg_id参数指定目标频道中被引用消息的ID。以下是修改后的代码:
// 缓存原频道消息ID与目标频道消息ID的映射,避免重复转发 private readonly Dictionary<int, long> _sourceToTargetMsgMap = new Dictionary<int, long>(); private async Task DisplayMessage(MessageBase messageBase, bool edit = false) { if (edit) Console.Write("(Edit): "); switch (messageBase) { case TL.Message m: if (m.Peer.ID == from.ID) { string message = m.message; Console.WriteLine(message); if (m.ReplyTo != null) { // 直接获取指定ID的被引用消息,替代遍历历史的低效方式 var referencedMsgResult = await Client.Messages_GetMessages( new[] { new InputMessageID { id = m.reply_to.reply_to_msg_id } }); if (referencedMsgResult.Messages.Length == 0) break; var referencedMsg = (TL.Message)referencedMsgResult.Messages[0]; long targetReferencedMsgId; // 检查是否已同步过该被引用消息到目标频道 if (!_sourceToTargetMsgMap.TryGetValue(referencedMsg.ID, out targetReferencedMsgId)) { // 未同步则先转发,获取目标频道的消息ID var forwardResult = await Client.Messages_ForwardMessages( from, new[] { referencedMsg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to, drop_author: true); if (forwardResult is Messages_AffectedMessages affected) targetReferencedMsgId = affected.id[0]; else { // 转发失败时 fallback 直接发送文本消息 var sentMsg = await Client.SendMessageAsync(to, referencedMsg.message); targetReferencedMsgId = sentMsg.ID; } // 缓存映射关系 _sourceToTargetMsgMap[referencedMsg.ID] = targetReferencedMsgId; } // 发送当前消息,并指定引用目标频道的对应消息 await Client.SendMessageAsync(to, message, reply_to_msg_id: targetReferencedMsgId); } else { // 非回复消息直接转发,并缓存ID映射 var forwardResult = await Client.Messages_ForwardMessages( from, new[] { m.ID }, new[] { WTelegram.Helpers.RandomLong() }, to, drop_author: true); if (forwardResult is Messages_AffectedMessages affected) _sourceToTargetMsgMap[m.ID] = affected.id[0]; } } break; } }
关键说明
- 高效获取被引用消息:用
Messages_GetMessages直接按ID获取消息,替代原代码遍历历史的低效操作。 - ID映射缓存:通过字典记录原频道消息到目标频道消息的ID对应关系,避免重复转发同一消息。
- 原生引用实现:调用
SendMessageAsync时传入reply_to_msg_id参数,指定目标频道中被引用消息的ID,即可触发Telegram原生引用样式。 - 容错处理:针对转发失败的情况,增加了直接发送文本消息的 fallback 逻辑,确保同步流程不中断。
内容的提问来源于stack exchange,提问作者Rjoy
相关产品推荐
相关产品推荐

