module PublishHelperBot.Handlers open System.Threading.Tasks open Microsoft.FSharp.Core open PublishHelperBot.Environment open PublishHelperBot.YoutubeDl 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 type Handler<'deps> = 'deps * 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 HasText (x: Message) = not(isNull x.Text) 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 (update, config, tg) -> let reply = update.Message.ReplyToMessage let channelId = config.chanelId let author = $"{reply.From.FirstName} {reply.From.LastName}" let captionMode = RelayCaptionType update.Message.Text let photoMedia = lazy Array.get (ExtractPhotoFromMessage reply) 0 let caption = lazy RelayResolveCaption(captionMode, author, config.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 // YoutubeDL repost let YoutubeRepostMatchCmd = "\\ytdl" let public YoutubeRepostMatch: HandlerRequirements = fun (u, c) -> UpdateIsAMessage u && FromAdminChat <| (u.Message, c) && HasText <| u.Message && u.Message.Text.StartsWith YoutubeRepostMatchCmd && u.Message.Text.Split(' ').Length = 2 let public YoutubeRepostHandler: Handler = fun (yt, (u, c, tg)) -> task { let trim (x: string) = x.Trim() let! id = YoutubeRepostMatchCmd |> u.Message.Text.Split |> Array.last |> trim |> yt.AddJob do! tg.SendTextMessageAsync(c.adminChatId, id.ToString()) |> Async.AwaitTask |> Async.Ignore }