module PublishHelperBot.Handlers open System.Threading.Tasks open PublishHelperBot.Environment open Telegram.Bot open Telegram.Bot.Types open Telegram.Bot.Types.Enums type BaseHandlerArgs = Update * BotConfig type HandlerArgs = Update * BotConfig * ITelegramBotClient type HandlerRequirements = BaseHandlerArgs -> bool type Handler = HandlerArgs -> Task // Utils let UpdateIsAMessage (x: Update) = x.Type = UpdateType.Message let FromAdminChat (x: Message, c: BotConfig) = x.Chat.Id = c.adminChatId let HasReply (x: Message) = not(isNull x.ReplyToMessage) let ExtractPhotoFromMessage (x: Message) = Array.map (fun (p: PhotoSize) -> p.FileId) x.Photo let UrlsAsAlbumInputMedia (urls: string[]): IAlbumInputMedia[] = Array.map (fun (x: string) -> InputMediaPhoto(x)) urls // Post (Relay) command type RelayCaptionMode = WithAuthor | Anonymous | Unknown let RelaySupportedContent (x: Message) = match x.Type with | MessageType.Text -> true | MessageType.Photo -> true | MessageType.Video -> true | _ -> false let RelayCaptionType (command: string) = match command with | _ when command.StartsWith "\\post anon" -> Anonymous | _ when command.StartsWith "\\post" -> WithAuthor | _ -> Unknown let RelayCaption (name: string, url: string) = $"Прислал {name}" let RelayParseMode = ParseMode.Html; let RelayResolveCaption (mode: RelayCaptionMode, username: string, linkUrl: string) = match mode with | WithAuthor -> RelayCaption(username, linkUrl) | _ -> null let public RelayMatch: HandlerRequirements = fun (u, c) -> UpdateIsAMessage u && FromAdminChat <| (u.Message, c) && HasReply u.Message && RelaySupportedContent u.Message.ReplyToMessage && not (RelayCaptionType u.Message.Text = RelayCaptionMode.Unknown) let public RelayHandler: Handler = fun (u, c, tg) -> let reply = u.Message.ReplyToMessage let channelId = c.chanelId let author = $"{reply.From.FirstName} {reply.From.LastName}" let captionMode = RelayCaptionType u.Message.Text let photoMedia = lazy Array.get (ExtractPhotoFromMessage reply) 0 let caption = lazy RelayResolveCaption(captionMode, author, c.relayUrl) match reply.Type with | MessageType.Text -> tg.ForwardMessageAsync(channelId, reply.Chat.Id, reply.MessageId) | MessageType.Photo -> tg.SendPhotoAsync(channelId, photoMedia.Value, caption = caption.Value, parseMode = RelayParseMode) | MessageType.Video -> tg.SendVideoAsync(channelId, reply.Video.FileId, caption = caption.Value, parseMode = RelayParseMode) | _ -> Task.CompletedTask // Youtube repost let public YoutubeRepostMatch: HandlerRequirements = fun (u, c) -> UpdateIsAMessage u && FromAdminChat <| (u.Message, c) && u.Message.Text.StartsWith("\\yt") && u.Message.Text.Split(' ').Length = 2