Relay command

This commit is contained in:
Keroosha 2023-02-07 21:55:46 +03:00
parent 0663a2b94e
commit 1ebcfa9788
4 changed files with 93 additions and 25 deletions

View File

@ -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<BotConfig>
let public CreateConfig (name: string) =
match Environment.GetEnvironmentVariable(name) with
| null -> raise <| ApplicationException("Missing config path env")
| path -> ReadConfig <| path

View File

@ -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) = $"<a href=\"{url}\"> Прислал </a> {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

View File

@ -1,43 +1,23 @@
// For more information see https://aka.ms/fsharp-console-apps // For more information see https://aka.ms/fsharp-console-apps
open System open System
open System.IO
open System.Net.Http open System.Net.Http
open System.Threading open System.Threading
open System.Threading.Tasks open System.Threading.Tasks
open Microsoft.FSharp.Control open PublishHelperBot.Handlers
open Newtonsoft.Json open PublishHelperBot.Environment
open Telegram.Bot open Telegram.Bot
open Telegram.Bot.Polling open Telegram.Bot.Polling
open Telegram.Bot.Types open Telegram.Bot.Types
open Telegram.Bot.Types.Enums open Telegram.Bot.Types.Enums
type BotConfig = { let CreateBot (config: BotConfig, http: HttpClient) = TelegramBotClient(config.token, http)
token: string
chanelId: int64
adminChatId: int64
}
let ReadConfig =
File.ReadAllText >> JsonConvert.DeserializeObject<BotConfig>
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 config = CreateConfig <| "SBPB_CONFIG_PATH"; let config = CreateConfig <| "SBPB_CONFIG_PATH";
let botClient = CreateBot <| (config, new HttpClient()) 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 = let updateHandle (bc: ITelegramBotClient) (u: Update) (ct: CancellationToken): Task =
match u with 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 | _ -> Task.CompletedTask
let handlePollingError (bc: ITelegramBotClient) (e: Exception) (t: CancellationToken) = let handlePollingError (bc: ITelegramBotClient) (e: Exception) (t: CancellationToken) =

View File

@ -10,8 +10,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Environment.fs" />
<Compile Include="Handlers.fs" />
<Compile Include="Program.fs" /> <Compile Include="Program.fs" />
<Content Include="config.dev.json" />
<Content Include="config.example.json" /> <Content Include="config.example.json" />
</ItemGroup> </ItemGroup>