Closed hmeleiro closed 7 months ago
I was not able to implement coro::async()
function to telegram.bot
handlers. But I managed to implement the async execution using Telegram API directly. Here is a simple example code:
library(httr)
library(jsonlite)
library(coro)
APIKEY <- ""
getUpdates <- function(){
url <- sprintf("https://api.telegram.org/bot%s/getupdates", APIKEY)
res <- GET(url)
if(res$status_code == 200) {
body <- content(res)
return(body$result)
} else {
return(NULL)
}
}
sendMessage <- async(
function(update) {
chat_id <- update$message$chat$id
msg <- as.numeric(update$message$text)
url <- sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s&text=Sleeping_%s_seconds", APIKEY, chat_id, msg)
GET(url)
await(async_sleep(msg))
url <- sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s&text=Done_%s", APIKEY, chat_id, msg)
GET(url)
}
)
# The bot waits for the seconds you tell it to wait and sends you a message back when it has stopped waiting.
# Send two Telegram messages to the bot, first a high number (like 5) and then a lower one (1).
# Then run this code below
updates <- getUpdates()
for (update in updates) {
sendMessage(update)
}
I've been experimenting with the future package.
I have configured parallel processing of commands, but for some reason it only works once.
In my example, if you run a slow and fast function, the bot will process them in parallel. But when they are called again, the updates do not reach the bot.
How can this be fixed?
library(telegram.bot)
library(promises)
library(future)
future::plan(multisession, workers = 2)
bot_token <- ""
updater <- Updater(token = bot_token )
start <- function(bot, update) {
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton("Button"))
),
resize_keyboard = TRUE,
one_time_keyboard = FALSE
)
bot$sendMessage(update$message$chat_id,
text = "Hello",
reply_markup = RKM)
}
start_hendler <- CommandHandler('start', start)
updater$dispatcher$add_handler(start_hendler)
MessageFilters$button <- BaseFilter(function(message) {
message$text == "Button"
})
ikm_button <- function(bot, update) {
IKM <- InlineKeyboardMarkup(
inline_keyboard = list(
list(
InlineKeyboardButton(text = 'Slow', callback_data = 'slow')),
list(
InlineKeyboardButton(text = 'Fast', callback_data = 'fast'))
)
)
bot$sendMessage(chat_id = update$message$chat_id,
text = "Select function",
reply_markup = IKM)
}
ikm_button_hendler <- MessageHandler(ikm_button, filters = MessageFilters$button)
updater$dispatcher$add_handler(ikm_button_hendler)
flow_fun <- function(bot, update) {
promises::future_promise({
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
bot$sendMessage(chat_id = update$from_chat_id(),
text = "start slow calc...")
Sys.sleep(5)
bot$sendMessage(chat_id = update$from_chat_id(),
text = "slow calc complete...")
})
}
flow_fun_handler <- CallbackQueryHandler(flow_fun, pattern = "slow")
updater$dispatcher$add_handler(flow_fun_handler)
fast_fun <- function(bot, update) {
promises::future_promise({
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
bot$sendMessage(chat_id = update$from_chat_id(),
text = "start fast calc....")
Sys.sleep(1)
bot$sendMessage(chat_id = update$from_chat_id(),
text = "fast calc complete...")
})
}
fast_fun_handler <- CallbackQueryHandler(fast_fun, pattern = "fast")
updater$dispatcher$add_handler(fast_fun_handler)
updater$start_polling(verbose = TRUE, clean = TRUE)
Hi, thanks for the comment, right now this fuctionality is not developed in-package.
I'm wondering if there is a way to write a bot that could handle simultaneous user petitions like in the python version of this library. Or maybe implement from outside with coro package? Would this be possible?
I have a basic understanding of concurrency and async functions, so I would not know where to start, but I'm going to give it a try with coro package and if it is possible write some kind of minimal example.