From 1ebcfa97880bdd7a3cd3efcb3e368279fcc838c1 Mon Sep 17 00:00:00 2001 From: Keroosha Date: Tue, 7 Feb 2023 21:55:46 +0300 Subject: [PATCH] Relay command --- PublishHelperBot/Environment.fs | 20 +++++++ PublishHelperBot/Handlers.fs | 67 ++++++++++++++++++++++++ PublishHelperBot/Program.fs | 28 ++-------- PublishHelperBot/PublishHelperBot.fsproj | 3 +- 4 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 PublishHelperBot/Environment.fs create mode 100644 PublishHelperBot/Handlers.fs diff --git a/PublishHelperBot/Environment.fs b/PublishHelperBot/Environment.fs new file mode 100644 index 0000000..44497bb --- /dev/null +++ b/PublishHelperBot/Environment.fs @@ -0,0 +1,20 @@ +module PublishHelperBot.Environment + +open System +open System.IO +open Newtonsoft.Json + +type public BotConfig = { + token: string + relayUrl: string + chanelId: int64 + adminChatId: int64 +} + +let private ReadConfig = + File.ReadAllText >> JsonConvert.DeserializeObject + +let public CreateConfig (name: string) = + match Environment.GetEnvironmentVariable(name) with + | null -> raise <| ApplicationException("Missing config path env") + | path -> ReadConfig <| path \ No newline at end of file diff --git a/PublishHelperBot/Handlers.fs b/PublishHelperBot/Handlers.fs new file mode 100644 index 0000000..ceb93a4 --- /dev/null +++ b/PublishHelperBot/Handlers.fs @@ -0,0 +1,67 @@ +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 + +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 + 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.SendTextMessageAsync(channelId, reply.Text) + | 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 diff --git a/PublishHelperBot/Program.fs b/PublishHelperBot/Program.fs index 8a3fc25..b6507d1 100644 --- a/PublishHelperBot/Program.fs +++ b/PublishHelperBot/Program.fs @@ -1,43 +1,23 @@ // For more information see https://aka.ms/fsharp-console-apps open System -open System.IO open System.Net.Http open System.Threading open System.Threading.Tasks -open Microsoft.FSharp.Control -open Newtonsoft.Json +open PublishHelperBot.Handlers +open PublishHelperBot.Environment open Telegram.Bot open Telegram.Bot.Polling open Telegram.Bot.Types open Telegram.Bot.Types.Enums -type BotConfig = { - token: string - chanelId: int64 - adminChatId: int64 -} - -let ReadConfig = - File.ReadAllText >> JsonConvert.DeserializeObject - -let CreateConfig (name: string) = - match Environment.GetEnvironmentVariable(name) with - | null -> raise <| ApplicationException("Missing config path env") - | path -> ReadConfig <| path - -let CreateBot (config: BotConfig, http: HttpClient) = - TelegramBotClient(config.token, http) - +let CreateBot (config: BotConfig, http: HttpClient) = TelegramBotClient(config.token, http) let config = CreateConfig <| "SBPB_CONFIG_PATH"; let botClient = CreateBot <| (config, new HttpClient()) -let shouldReply (u: Update) = - u.Type = UpdateType.Message && u.Message.Chat.Id = config.adminChatId - let updateHandle (bc: ITelegramBotClient) (u: Update) (ct: CancellationToken): Task = match u with - | _ when shouldReply u -> bc.SendTextMessageAsync(config.chanelId, u.Message.Text, cancellationToken = ct) + | _ when RelayMatch <| (u, config) -> RelayHandler <| (u, config, bc) | _ -> Task.CompletedTask let handlePollingError (bc: ITelegramBotClient) (e: Exception) (t: CancellationToken) = diff --git a/PublishHelperBot/PublishHelperBot.fsproj b/PublishHelperBot/PublishHelperBot.fsproj index 3c3a166..2176efd 100644 --- a/PublishHelperBot/PublishHelperBot.fsproj +++ b/PublishHelperBot/PublishHelperBot.fsproj @@ -10,8 +10,9 @@ + + -