Files
herolib/lib/ui/telegram/client/client.v
2025-10-12 12:30:19 +03:00

127 lines
3.4 KiB
V

module client
import incubaid.herolib.baobab.client
import incubaid.herolib.core.redisclient
import dariotarantini.vgram
import json
// client for telegram bot
struct TelegramClient {
bot vgram.Bot
baobab Client // Baobab client
waiting_qs map[string]RedisQueue // where string is user_id
}
// factory for telegram client initializes baobab client and redis queues
pub fn new_client(bot_token string, supervisor_key string) !TelegramClient {
baobab := client.new()!
return TelegramClient{
baobab: baobab
bot: vgram.new_bot(bot_token)
flow_supervisor: baobab.redis.queue_get(supervisor_key) //? Why are these necessary?
in_q: baobab.redis.queue_get('client.telegram.in') //? Why are these necessary?
}
}
// listens for incoming messages, relays to flow
pub fn (mut client TelegramClient) execute() {
mut last_offset := client.clear_old_updates()
for {
updates := client.bot.get_updates(offset: last_offset, limit: 100)
for update in updates {
// make sure message is new
if last_offset < update.update_id {
last_offset = update.update_id
if update.message.text.starts_with('/') {
// todo send update to flow supervisor
} else {
// todo send update to uichannel return queue
client.handle_update(update) or { continue } // TODO log a failure
}
}
}
}
}
pub fn (mut client TelegramClient) clear_old_updates() string {
mut last_offset := 0
mut updates := client.bot.get_updates(
timeout: 0
allowed_updates: json.encode([
'message',
])
offset: last_offset
limit: 100
)
for update in updates {
if last_offset < update.update_id {
last_offset = update.update_id
}
}
return last_offset
}
// forwards update to telegramui for handling
// todo: implement separate handlers for separate message types
fn (mut client TelegramClient) handle_update(update vgram.Update) {
// todo check for an exit code
// todo user_id in
// [params]
// pub struct JobNewArgs {
// pub mut:
// twinid u32
// action string
// args Params
// actionsource string
// }
job_args := JobNewArgs{
action: 'ui.telegram.forward'
}
// creates job in jobs db and pushes to processor's incoming queue
client.baobab.job_new_schedule()!
user_id := update.message.from.id.str()
text := update.message.text
// // Infinite loop to deal with incoming and outgoing messages
// for {
// select {
// output := <- ui.to_user {
// ui.send(output.message, output.user_id)
// ui.waiting_qs[output.user_id] = output.response_channel
// }
// else {
// updates := ui.bot.get_updates(timeout: 0, allowed_updates: json.encode(["message"]), offset: last_offset, limit: 100)
// for update in updates {
// if last_offset < update.update_id {
// last_offset = update.update_id
// ui.handle_update(update) // ? Should this line be in the if statement?
// }
// }
// }
// }
// }
}
fn (mut ui UITelegram) handle_update(update vgram.Update) {
user_id := update.message.from.id.str()
text := update.message.text
if user_id in ui.waiting_qs.keys() && text[0].ascii_str() != '/' {
ui.waiting_qs[user_id].response_channel <- update.message.text
} else {
match text.trim_string_left('/').split(' ')[0] {
'register' {}
'order' {}
}
}
}
fn (ui UITelegram) send(msg string, user_id string) {
_ := ui.bot.send_message(
chat_id: user_id
text: msg
parse_mode: 'MarkdownV2'
)
}