Keroosha.SilencerBot/Keroosha.SilencerBot/Telegram.fs
2023-04-13 20:21:54 +03:00

114 lines
4.0 KiB
Forth
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module Keroosha.SilencerBot.Telegram
open System
open System.IO
open System.Text.Json
open Funogram.Telegram
open Funogram.Telegram.Bot
open Funogram.Telegram.Types
open Keroosha.SilencerBot.Env
open LinqToDB
open Keroosha.SilencerBot.Database
open Microsoft.FSharp.Control
module TgClient = Funogram.Tools.Api
type VoiceRemoveArgs = {
fileId: string
filename: string
chatId: int64
}
type StartArgs = {
id: int64
chatId: int64
name: String
}
type Features =
| VoiceRemove of VoiceRemoveArgs
| Start of StartArgs
| Skip
let runDate = DateTime.UtcNow
let greetingText = "Привет, отправь мне вавку и я попробую убрать из нее голос"
let jobCreatedText = "Запустил задачу, обрабатываю"
let unknownUserText = "Прости, но мы с тобой не знакомы, отправь мне в ЛС /start"
let isVoiceRemoveAction(update: Update) =
update.Message.IsSome &&
update.Message.Value.Audio.IsSome &&
update.Message.Value.From.IsSome &&
update.Message.Value.Audio.Value.FileName.IsSome
let isStartCommand (update: Update) =
update.Message.IsSome &&
update.Message.Value.Text.IsSome &&
update.Message.Value.From.IsSome &&
update.Message.Value.Text.Value.StartsWith "/start"
let resolveUpdate (ctx: UpdateContext) =
match ctx.Update with
| x when x.Message.IsSome && x.Message.Value.Date < runDate -> Skip
| x when isVoiceRemoveAction x ->
VoiceRemove {
fileId = x.Message.Value.Audio.Value.FileId
chatId = x.Message.Value.From.Value.Id
filename = x.Message.Value.Audio.Value.FileName.Value
}
| x when isStartCommand x ->
Start {
id = x.Message.Value.From.Value.Id
chatId = x.Message.Value.Chat.Id
name = x.Message.Value.From.Value.FirstName
}
| _ -> Skip
let createBotInbox (cfg: BotConfig, botCfg: Funogram.Types.BotConfig, dbFactory: unit -> DbContext) = MailboxProcessor.Start(fun (inbox) ->
let rec loop () =
async {
try
match! inbox.Receive() with
| VoiceRemove x ->
let db = dbFactory()
use! trx = db.BeginTransactionAsync() |> Async.AwaitTask
let! user = db.Users.FirstOrDefaultAsync(fun u -> u.TgId = x.chatId) |> Async.AwaitTask
match box user with
| null ->
do! TgClient.makeRequestAsync botCfg <| Api.sendMessage x.chatId unknownUserText |> Async.Ignore
()
| _ ->
let jobContext: JsonJobContext = {
stderr = ""
stdout = ""
chatId = x.chatId
fileId = x.fileId
savePath = Path.Combine(cfg.tempSavePath, x.filename)
}
let job: UserJob = { Id = Guid.NewGuid()
State = JobState.New
UserId = user.Id
Context = JsonSerializer.Serialize(jobContext)
WorkerId = Nullable()
}
do! db.InsertAsync(job) |> Async.AwaitTask |> Async.Ignore
do! trx.CommitAsync() |> Async.AwaitTask
do! TgClient.makeRequestAsync botCfg <| Api.sendMessage x.chatId jobCreatedText |> Async.Ignore
()
| Start x ->
let db = dbFactory()
use! trx = Async.AwaitTask <| db.BeginTransactionAsync()
match! db.Users.AnyAsync(fun u -> u.TgId = x.id) |> Async.AwaitTask with
| true -> ()
| false ->
let user: User = { Id = Guid.NewGuid(); Name = x.name; TgId = x.id; ChatId = x.chatId }
do! db.InsertAsync(user) |> Async.AwaitTask |> Async.Ignore
do! trx.CommitAsync() |> Async.AwaitTask
do! TgClient.makeRequestAsync botCfg <| Api.sendMessage x.chatId greetingText |> Async.Ignore
| Skip -> ()
with
| ex -> Logging.logger.Error $"\n{ex.Message}\n{ex.StackTrace}"
return! loop ()
}
loop ()
)