private void _onMediaGroupMessage(object sender, TgMediaGroupSettler.MediaGroupEventArgs e) { var oldMessage = e.Message; var message = new Message(oldMessage.OriginConversation, oldMessage.OriginSender, oldMessage.Body, oldMessage.ForwardedMessages, e.Attachments); OnMessageReceived(new MessageEventArgs(message)); }
private async Task <Message> _extractMessage(Telegram.Bot.Types.Message tgMessage) { Logger.LogTrace("Message received"); var conversation = _extractConversation(tgMessage.Chat); var person = _extractPerson(tgMessage.From); var attachments = new List <Attachment>(); var at = await _extractAttachment(tgMessage); if (at != null) { attachments.Add(at); } if (tgMessage.Entities != null) { attachments.AddRange(from entity in tgMessage.Entities where entity.Type == MessageEntityType.TextLink select new LinkAttachment(entity.Url)); } // Just forwarded message if (tgMessage.ForwardFrom != null) { var fwdPerson = _extractPerson(tgMessage.ForwardFrom); var fwdMessage = new Message(conversation, fwdPerson, tgMessage.Text, attachments: attachments); return(new Message(conversation, person, forwardedMessages: new[] { fwdMessage })); } // Reply to Message[] forwarded = null; if (tgMessage.ReplyToMessage != null) { forwarded = new[] { await _extractMessage(tgMessage.ReplyToMessage) }; } var text = tgMessage.Text ?? tgMessage.Caption; // Remove bot name from command if (!string.IsNullOrEmpty(text) && text.StartsWith("/") && !string.IsNullOrEmpty(BotUserName)) { text = text.Split($"@{BotUserName}", 2)[0]; } return(new Message(conversation, person, text, forwarded, attachments)); }
private InputOnlineFile _getInputFile(Message message, Attachment attachment) { if (message.OriginSender != null && message.OriginSender.Provider.Equals(this)) { if (attachment.Meta is Audio audio) { return(audio.FileId); } if (attachment.Meta is Document document) { return(document.FileId); } if (attachment.Meta is Animation animation) { return(animation.FileId); } if (attachment.Meta is PhotoSize photo) { return(photo.FileId); } if (attachment.Meta is Sticker sticker) { return(sticker.FileId); } if (attachment.Meta is Video video) { return(video.FileId); } if (attachment.Meta is Voice voice) { return(voice.FileId); } if (attachment.Meta is VideoNote videoNote) { return(videoNote.FileId); } } return(new InputOnlineFile(attachment.Url)); }
public override async Task SendMessage(Conversation conversation, Message message) { Logger.LogTrace("Send message to conversation {0}", conversation.OriginId); var peerId = Convert.ToInt32(conversation.OriginId); #region Get forwarded and attachments var fwd = FlattenForwardedMessages(message); var attachments = GetAllAttachments(message, fwd); #endregion #region Send message var sender = ""; if (message.OriginSender != null) { sender = FormatSender(message.OriginSender) + "\n"; } var body = FormatMessageBody(message, fwd); if (body.Length > 0) { await ApiClient.Messages.SendAsync(new MessagesSendParams { GroupId = _groupId, PeerId = peerId, Message = $"{sender}{body}", RandomId = random.Next() }); } #endregion if (attachments.Any()) { Logger.LogTrace("Sending message with attachments"); try { #region Get upload server urls UploadServerInfo photoUploadServer = null; UploadServerInfo docsUploadServer = null; UploadServerInfo voiceUploadServer = null; await Task.WhenAll(Task.Run(async() => { if (attachments.Any(at => (at is PhotoAttachment || at is StickerAttachment))) { photoUploadServer = await ApiClient.Photo.GetMessagesUploadServerAsync(peerId); } }), Task.Run(async() => { if (attachments.Any(at => !(at is VoiceAttachment || at is PhotoAttachment))) { docsUploadServer = await ApiClient.Docs.GetMessagesUploadServerAsync(peerId, DocMessageType.Doc); } }), Task.Run(async() => { if (attachments.Any(at => at is VoiceAttachment)) { voiceUploadServer = await ApiClient.Docs.GetMessagesUploadServerAsync(peerId, DocMessageType.AudioMessage); } })); #endregion #region Get vk attachments var groupableAttachments = attachments.Where(at => !(at is IVkSpecialAttachment)); Func <Attachment, Task <MediaAttachment> > GroupableAttachmentSelector() { return(async at => { switch (at) { case AnimationAttachment animation: return await _uploadDocument(animation, docsUploadServer); case StickerAttachment sticker: return await _uploadPhoto(sticker, photoUploadServer); case PhotoAttachment albumPhoto: return await _uploadPhoto(albumPhoto, photoUploadServer); case VideoAttachment albumVideo: return await _uploadDocument(albumVideo, docsUploadServer); case VoiceAttachment voice: return await _uploadDocument(voice, voiceUploadServer); case AudioAttachment audio: return await _uploadDocument(audio, docsUploadServer, $"{audio.ToString()}.mp3.txt", "audio/mp3"); case FileAttachment file: return await _uploadDocument(file, docsUploadServer); default: return null; } }); } #endregion #region Send vk attachments by chunks var chunks = groupableAttachments .Select((val, i) => (val, i)) .GroupBy(tuple => tuple.i / 10); foreach (var chunk in chunks) { var vkAttachments = await Task.WhenAll(chunk.Select(x => x.val) .Select(GroupableAttachmentSelector())); await ApiClient.Messages.SendAsync(new MessagesSendParams { GroupId = _groupId, PeerId = peerId, Attachments = vkAttachments.Where(a => a != null), RandomId = random.Next(), Message = $"{sender}{string.Join(" ", vkAttachments.Where(a => a == null).Select(a => "[Unsupported attachment]").ToArray())}" }); } #endregion #region Send special attachments (contacts/urls/places) foreach (var at in attachments) { switch (at) { case ContactAttachment contact: await ApiClient.Messages.SendAsync(new MessagesSendParams { GroupId = _groupId, PeerId = peerId, Attachments = new[] { await _uploadDocument(contact, docsUploadServer) }, Message = $"{sender}{contact.ToString()}", RandomId = random.Next() }); break; case LinkAttachment link: await ApiClient.Messages.SendAsync(new MessagesSendParams { GroupId = _groupId, PeerId = peerId, Message = $"{sender}{link.ToString()}", RandomId = random.Next() }); break; case PlaceAttachment place: await ApiClient.Messages.SendAsync(new MessagesSendParams { GroupId = _groupId, PeerId = peerId, Lat = place.Latitude, Longitude = place.Longitude, // typo in lib Message = $"{sender}{place.ToString()}", RandomId = random.Next() }); break; } } #endregion } catch (Exception e) { Logger.LogError("Attachments upload failed {0}", e); } } }
public override async Task SendMessage(Conversation conversation, Message message) { Logger.LogTrace("Send message to conversation {0}", conversation.OriginId); var chat = new ChatId(Convert.ToInt64(conversation.OriginId)); #region Get forwarded and attachments var fwd = FlattenForwardedMessages(message); var attachments = GetAllAttachments(message, fwd); #endregion #region Send message var sender = ""; if (message.OriginSender != null) { sender = FormatSender(message.OriginSender) + "\n"; } var body = FormatMessageBody(message, fwd); if (body.Length > 0) { await BotClient.SendTextMessageAsync(new ChatId(conversation.OriginId), $"{sender}{body}", ParseMode.Html, true); } #endregion #region Send attachments if (attachments.Any()) { Logger.LogTrace("Sending message with attachments"); var groupableAttachments = attachments.OfType <ITgGroupableAttachment>(); Func <ITgGroupableAttachment, IAlbumInputMedia> AlbumAttachmentSelector() { return(media => { switch (media) { case PhotoAttachment albumPhoto: { if (albumPhoto.Meta is PhotoSize photo) { return new InputMediaPhoto(new InputMedia(photo.FileId)); } var tgPhoto = new InputMediaPhoto(new InputMedia(albumPhoto.Url)) { Caption = message?.OriginSender?.DisplayName != null ? $"[{message.OriginSender.DisplayName}] {albumPhoto.Caption ?? ""}" : albumPhoto.Caption }; return tgPhoto; } case VideoAttachment albumVideo: { if (albumVideo.Meta is Video video) { return new InputMediaPhoto(new InputMedia(video.FileId)); } var tgVideo = new InputMediaVideo(albumVideo.Url) { Caption = message?.OriginSender?.DisplayName != null ? $"[{message.OriginSender.DisplayName}] {albumVideo.Caption ?? ""}" : albumVideo.Caption, Duration = (int)(albumVideo.Duration ?? 0), Width = albumVideo.Width, Height = albumVideo.Height }; return tgVideo; } default: return null; } }); } var chunks = groupableAttachments .Select((val, i) => (val, i)) .GroupBy(tuple => tuple.i / 10); foreach (var chunk in chunks) { await BotClient.SendMediaGroupAsync( chunk.Select(x => x.val).Select(AlbumAttachmentSelector()), chat); } var restAttachments = attachments.Where(at => !(at is ITgGroupableAttachment)); foreach (var at in restAttachments) { if (at is AnimationAttachment animation) { await BotClient.SendAnimationAsync(chat, _getInputFile(message, animation), (int)(animation.Duration ?? 0), animation.Width, animation.Height, caption : animation.Caption); } else if (at is VoiceAttachment voice) { var req = (HttpWebRequest)WebRequest.Create(voice.Url); req.Timeout = 15000; var resp = (HttpWebResponse)req.GetResponse(); await BotClient.SendVoiceAsync(chat, new InputOnlineFile(resp.GetResponseStream(), voice.FileName), voice.Caption); } else if (at is AudioAttachment audio) { await BotClient.SendAudioAsync(chat, _getInputFile(message, audio), audio.Caption, duration : (int)(audio.Duration ?? 0), performer : audio.Performer, title : audio.Title); } else if (at is ContactAttachment contact) { await BotClient.SendContactAsync(chat, contact.Phone, contact.FirstName, contact.LastName, vCard : contact.VCard); } else if (at is LinkAttachment link) { await BotClient.SendTextMessageAsync(chat, $"{sender}{link.Url}", ParseMode.Html); } else if (at is StickerAttachment sticker) { var inputFile = _getInputFile(message, sticker); if (sticker.MimeType == "image/webp") { await BotClient.SendStickerAsync(chat, inputFile); } else { Logger.LogTrace("Converting sticker to webp format"); var req = (HttpWebRequest)WebRequest.Create(inputFile.Url); req.Timeout = 15000; var resp = (HttpWebResponse)req.GetResponse(); var image = SKImage.FromBitmap(SKBitmap.Decode(resp.GetResponseStream())); using (var p = image.Encode(SKEncodedImageFormat.Webp, 100)) { await BotClient.SendStickerAsync(chat, new InputMedia(p.AsStream(), "sticker.webp")); } } } else if (at is PlaceAttachment place) { if (place.Name != null && place.Address != null) { await BotClient.SendVenueAsync(chat, (float)place.Latitude, (float)place.Longitude, place.Name, place.Address); } else { await BotClient.SendLocationAsync(chat, (float)place.Latitude, (float)place.Longitude); } } else if (at is FileAttachment file) { if (file.MimeType == "image/gif" || file.MimeType == "application/pdf" || file.MimeType == "application/zip") { await BotClient.SendDocumentAsync(chat, _getInputFile(message, file), file.Caption); } else { var req = (HttpWebRequest)WebRequest.Create(file.Url); req.Timeout = 15000; var resp = (HttpWebResponse)req.GetResponse(); await BotClient.SendDocumentAsync(chat, new InputOnlineFile(resp.GetResponseStream(), file.FileName), file.Caption); } } } } #endregion }