Invalidate cache and delete bot on invalid token error
Some checks are pending
Build docker image / Build-Docker-Image (push) Waiting to run

This commit is contained in:
2025-07-04 14:40:45 +02:00
parent 86669b66f3
commit a829ba200d
21 changed files with 61 additions and 57 deletions

View File

@@ -31,7 +31,7 @@ impl FromStr for AnnotationCallbackData {
|(annotation_type, id, page)| match annotation_type.as_str() { |(annotation_type, id, page)| match annotation_type.as_str() {
"a" => AnnotationCallbackData::Author { id, page }, "a" => AnnotationCallbackData::Author { id, page },
"b" => AnnotationCallbackData::Book { id, page }, "b" => AnnotationCallbackData::Book { id, page },
_ => panic!("Unknown AnnotationCallbackData type: {}!", annotation_type), _ => panic!("Unknown AnnotationCallbackData type: {annotation_type}!"),
}, },
) )
} }
@@ -40,8 +40,8 @@ impl FromStr for AnnotationCallbackData {
impl Display for AnnotationCallbackData { impl Display for AnnotationCallbackData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
AnnotationCallbackData::Book { id, page } => write!(f, "b_an_{}_{}", id, page), AnnotationCallbackData::Book { id, page } => write!(f, "b_an_{id}_{page}"),
AnnotationCallbackData::Author { id, page } => write!(f, "a_an_{}_{}", id, page), AnnotationCallbackData::Author { id, page } => write!(f, "a_an_{id}_{page}"),
} }
} }
} }

View File

@@ -27,7 +27,7 @@ impl CommandParse<Self> for AnnotationCommand {
.map(|(annotation_type, id)| match annotation_type.as_str() { .map(|(annotation_type, id)| match annotation_type.as_str() {
"a" => Ok(AnnotationCommand::Author { id }), "a" => Ok(AnnotationCommand::Author { id }),
"b" => Ok(AnnotationCommand::Book { id }), "b" => Ok(AnnotationCommand::Book { id }),
_ => panic!("Unknown AnnotationCommand type: {}!", annotation_type), _ => panic!("Unknown AnnotationCommand type: {annotation_type}!"),
})? })?
} }
} }

View File

@@ -10,7 +10,7 @@ pub struct AnnotationFormatError {
impl fmt::Display for AnnotationFormatError { impl fmt::Display for AnnotationFormatError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self) write!(f, "{self:?}")
} }
} }

View File

@@ -33,7 +33,7 @@ impl FromStr for BookCallbackData {
"a" => Ok(BookCallbackData::Author { id, page }), "a" => Ok(BookCallbackData::Author { id, page }),
"t" => Ok(BookCallbackData::Translator { id, page }), "t" => Ok(BookCallbackData::Translator { id, page }),
"s" => Ok(BookCallbackData::Sequence { id, page }), "s" => Ok(BookCallbackData::Sequence { id, page }),
_ => panic!("Unknown BookCallbackData type: {}!", annotation_type), _ => panic!("Unknown BookCallbackData type: {annotation_type}!"),
}, },
)? )?
} }
@@ -42,9 +42,9 @@ impl FromStr for BookCallbackData {
impl Display for BookCallbackData { impl Display for BookCallbackData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
BookCallbackData::Author { id, page } => write!(f, "ba_{}_{}", id, page), BookCallbackData::Author { id, page } => write!(f, "ba_{id}_{page}"),
BookCallbackData::Translator { id, page } => write!(f, "bt_{}_{}", id, page), BookCallbackData::Translator { id, page } => write!(f, "bt_{id}_{page}"),
BookCallbackData::Sequence { id, page } => write!(f, "bs_{}_{}", id, page), BookCallbackData::Sequence { id, page } => write!(f, "bs_{id}_{page}"),
} }
} }
} }

View File

@@ -22,7 +22,7 @@ impl CommandParse<Self> for BookCommand {
"a" => Ok(BookCommand::Author { id }), "a" => Ok(BookCommand::Author { id }),
"t" => Ok(BookCommand::Translator { id }), "t" => Ok(BookCommand::Translator { id }),
"s" => Ok(BookCommand::Sequence { id }), "s" => Ok(BookCommand::Sequence { id }),
_ => panic!("Unknown BookCommand type: {}!", annotation_type), _ => panic!("Unknown BookCommand type: {annotation_type}!"),
})? })?
} }
} }

View File

@@ -146,7 +146,7 @@ where
.await .await
{ {
Ok(_) => (), Ok(_) => (),
Err(err) => log::error!("{:?}", err), Err(err) => log::error!("{err:?}"),
} }
return Err(err); return Err(err);
} }

View File

@@ -16,7 +16,7 @@ impl Display for DownloadQueryData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
DownloadQueryData::DownloadData { book_id, file_type } => { DownloadQueryData::DownloadData { book_id, file_type } => {
write!(f, "d_{}_{}", book_id, file_type) write!(f, "d_{book_id}_{file_type}")
} }
} }
} }
@@ -51,13 +51,13 @@ impl Display for DownloadArchiveQueryData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
DownloadArchiveQueryData::Sequence { id, file_type } => { DownloadArchiveQueryData::Sequence { id, file_type } => {
write!(f, "da_s_{}_{}", id, file_type) write!(f, "da_s_{id}_{file_type}")
} }
DownloadArchiveQueryData::Author { id, file_type } => { DownloadArchiveQueryData::Author { id, file_type } => {
write!(f, "da_a_{}_{}", id, file_type) write!(f, "da_a_{id}_{file_type}")
} }
DownloadArchiveQueryData::Translator { id, file_type } => { DownloadArchiveQueryData::Translator { id, file_type } => {
write!(f, "da_t_{}_{}", id, file_type) write!(f, "da_t_{id}_{file_type}")
} }
} }
} }
@@ -82,7 +82,7 @@ impl FromStr for DownloadArchiveQueryData {
"s" => DownloadArchiveQueryData::Sequence { id, file_type }, "s" => DownloadArchiveQueryData::Sequence { id, file_type },
"a" => DownloadArchiveQueryData::Author { id, file_type }, "a" => DownloadArchiveQueryData::Author { id, file_type },
"t" => DownloadArchiveQueryData::Translator { id, file_type }, "t" => DownloadArchiveQueryData::Translator { id, file_type },
_ => panic!("Unknown DownloadArchiveQueryData type: {}!", obj_type), _ => panic!("Unknown DownloadArchiveQueryData type: {obj_type}!"),
}) })
} }
} }

View File

@@ -47,9 +47,9 @@ pub enum DownloadArchiveCommand {
impl Display for DownloadArchiveCommand { impl Display for DownloadArchiveCommand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
DownloadArchiveCommand::Sequence { id } => write!(f, "/da_s_{}", id), DownloadArchiveCommand::Sequence { id } => write!(f, "/da_s_{id}"),
DownloadArchiveCommand::Author { id } => write!(f, "/da_a_{}", id), DownloadArchiveCommand::Author { id } => write!(f, "/da_a_{id}"),
DownloadArchiveCommand::Translator { id } => write!(f, "/da_t_{}", id), DownloadArchiveCommand::Translator { id } => write!(f, "/da_t_{id}"),
} }
} }
} }

View File

@@ -104,7 +104,7 @@ async fn send_cached_message(
match send_donation_notification(bot.clone(), message).await { match send_donation_notification(bot.clone(), message).await {
Ok(_) => (), Ok(_) => (),
Err(err) => log::error!("{:?}", err), Err(err) => log::error!("{err:?}"),
} }
return Ok(()); return Ok(());
@@ -144,14 +144,14 @@ async fn _send_downloaded_file(
{ {
Ok(_) => (), Ok(_) => (),
Err(err) => { Err(err) => {
log::error!("Download error: {:?} | {:?}", filename, err); log::error!("Download error: {filename:?} | {err:?}");
return Err(err.into()); return Err(err.into());
} }
} }
match send_donation_notification(bot, message.clone()).await { match send_donation_notification(bot, message.clone()).await {
Ok(_) => (), Ok(_) => (),
Err(err) => log::error!("{:?}", err), Err(err) => log::error!("{err:?}"),
}; };
Ok(()) Ok(())
@@ -333,8 +333,7 @@ async fn send_archive_link(
message.id, message.id,
format!( format!(
"Файл не может быть загружен в чат! \n \ "Файл не может быть загружен в чат! \n \
Вы можете скачать его <a href=\"{}\">по ссылке</a> (работает 3 часа)", Вы можете скачать его <a href=\"{link}\">по ссылке</a> (работает 3 часа)"
link
), ),
) )
.parse_mode(ParseMode::Html) .parse_mode(ParseMode::Html)
@@ -368,7 +367,7 @@ async fn wait_archive(
Ok(v) => v, Ok(v) => v,
Err(err) => { Err(err) => {
send_error_message(bot, message.chat.id, message.id).await; send_error_message(bot, message.chat.id, message.id).await;
log::error!("{:?}", err); log::error!("{err:?}");
return Err(err); return Err(err);
} }
}; };
@@ -421,7 +420,7 @@ async fn wait_archive(
}, },
Err(err) => { Err(err) => {
send_error_message(bot, message.chat.id, message.id).await; send_error_message(bot, message.chat.id, message.id).await;
log::error!("{:?}", err); log::error!("{err:?}");
return Err(err); return Err(err);
} }
}; };
@@ -436,7 +435,7 @@ async fn wait_archive(
Ok(_) => (), Ok(_) => (),
Err(err) => { Err(err) => {
send_archive_link(bot.clone(), message.clone(), task).await?; send_archive_link(bot.clone(), message.clone(), task).await?;
log::error!("{:?}", err); log::error!("{err:?}");
} }
} }
@@ -478,7 +477,7 @@ async fn download_archive(
Ok(v) => v, Ok(v) => v,
Err(err) => { Err(err) => {
send_error_message(bot, message.chat().id, message.id()).await; send_error_message(bot, message.chat().id, message.id()).await;
log::error!("{:?}", err); log::error!("{err:?}");
return Err(err); return Err(err);
} }
}; };

View File

@@ -16,10 +16,10 @@ pub enum SearchCallbackData {
impl Display for SearchCallbackData { impl Display for SearchCallbackData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
SearchCallbackData::Book { page } => write!(f, "sb_{}", page), SearchCallbackData::Book { page } => write!(f, "sb_{page}"),
SearchCallbackData::Authors { page } => write!(f, "sa_{}", page), SearchCallbackData::Authors { page } => write!(f, "sa_{page}"),
SearchCallbackData::Sequences { page } => write!(f, "ss_{}", page), SearchCallbackData::Sequences { page } => write!(f, "ss_{page}"),
SearchCallbackData::Translators { page } => write!(f, "st_{}", page), SearchCallbackData::Translators { page } => write!(f, "st_{page}"),
} }
} }
} }

View File

@@ -41,8 +41,8 @@ impl Display for SettingsCallbackData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
SettingsCallbackData::Settings => write!(f, "lang_settings"), SettingsCallbackData::Settings => write!(f, "lang_settings"),
SettingsCallbackData::On { code } => write!(f, "lang_on_{}", code), SettingsCallbackData::On { code } => write!(f, "lang_on_{code}"),
SettingsCallbackData::Off { code } => write!(f, "lang_off_{}", code), SettingsCallbackData::Off { code } => write!(f, "lang_off_{code}"),
} }
} }
} }

View File

@@ -44,7 +44,7 @@ impl Display for UpdateLogCallbackData {
let to = self.to.format(date_format); let to = self.to.format(date_format);
let page = self.page; let page = self.page;
write!(f, "update_log_{}_{}_{}", from, to, page) write!(f, "update_log_{from}_{to}_{page}")
} }
} }

View File

@@ -5,7 +5,7 @@ pub struct CallbackQueryParseError;
impl fmt::Display for CallbackQueryParseError { impl fmt::Display for CallbackQueryParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self) write!(f, "{self:?}")
} }
} }
@@ -16,7 +16,7 @@ pub struct CommandParseError;
impl fmt::Display for CommandParseError { impl fmt::Display for CommandParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self) write!(f, "{self:?}")
} }
} }

View File

@@ -38,7 +38,7 @@ where
match response.json::<T>().await { match response.json::<T>().await {
Ok(v) => Ok(v), Ok(v) => Ok(v),
Err(err) => { Err(err) => {
log::error!("Failed serialization: url={:?} err={:?}", url, err); log::error!("Failed serialization: url={url:?} err={err:?}");
Err(err.into()) Err(err.into())
} }
} }

View File

@@ -66,7 +66,7 @@ pub async fn get_user_or_default_lang_codes(user_id: UserId) -> SmallVec<[SmartS
langs langs
} }
Err(err) => { Err(err) => {
log::error!("{:?}", err); log::error!("{err:?}");
default_lang_codes default_lang_codes
} }
} }

View File

@@ -25,7 +25,7 @@ async fn get_bot_username(token: &str) -> Option<String> {
match Bot::new(token).get_me().send().await { match Bot::new(token).get_me().send().await {
Ok(v) => v.username.clone(), Ok(v) => v.username.clone(),
Err(err) => { Err(err) => {
log::error!("Bot reg (getting username) error: {:?}", err); log::error!("Bot reg (getting username) error: {err:?}");
None None
} }
} }
@@ -72,7 +72,7 @@ pub async fn register(user_id: UserId, message_text: &str) -> RegisterStatus {
let result = match register_request_status { let result = match register_request_status {
Ok(v) => v, Ok(v) => v,
Err(err) => { Err(err) => {
log::error!("Bot reg error: {:?}", err); log::error!("Bot reg error: {err:?}");
return RegisterStatus::RegisterFail; return RegisterStatus::RegisterFail;
} }

View File

@@ -1,8 +1,5 @@
pub fn format_registered_message(username: &str) -> String { pub fn format_registered_message(username: &str) -> String {
format!( format!("@{username} зарегистрирован и через несколько минут будет подключен!")
"@{username} зарегистрирован и через несколько минут будет подключен!",
username = username
)
} }
pub const ALREADY_REGISTERED: &str = "Ошибка! Возможно бот уже зарегистрирован!"; pub const ALREADY_REGISTERED: &str = "Ошибка! Возможно бот уже зарегистрирован!";

View File

@@ -55,7 +55,7 @@ pub async fn start_axum_server(stop_signal: Arc<AtomicBool>) {
match BOTS_ROUTES.get(&token).await { match BOTS_ROUTES.get(&token).await {
None => { None => {
log::error!("Cannot get a bot with token: {}", token); log::error!("Cannot get a bot with token: {token}");
return StatusCode::SERVICE_UNAVAILABLE; return StatusCode::SERVICE_UNAVAILABLE;
} }
Some(v) => v, Some(v) => v,
@@ -83,18 +83,16 @@ pub async fn start_axum_server(stop_signal: Arc<AtomicBool>) {
} }
if let Err(err) = tx.send(Ok(update)) { if let Err(err) = tx.send(Ok(update)) {
log::error!("{:?}", err); log::error!("{err:?}");
BOTS_ROUTES.remove(&token).await; BOTS_ROUTES.remove(&token).await;
return StatusCode::SERVICE_UNAVAILABLE; return StatusCode::SERVICE_UNAVAILABLE;
} }
} }
Err(error) => { Err(error) => {
log::error!( log::error!(
"Cannot parse an update.\nError: {:?}\nValue: {}\n\ "Cannot parse an update.\nError: {error:?}\nValue: {input}\n\
This is a bug in teloxide-core, please open an issue here: \ This is a bug in teloxide-core, please open an issue here: \
https://github.com/teloxide/teloxide/issues.", https://github.com/teloxide/teloxide/issues."
error,
input
); );
} }
}; };

View File

@@ -71,7 +71,7 @@ pub async fn set_webhook(bot_data: &BotData) -> bool {
} }
} }
log::error!("Webhook set error: {}", err); log::error!("Webhook set error: {err}");
false false
} }
} }
@@ -95,7 +95,7 @@ pub async fn start_bot(bot_data: &BotData) {
}; };
match set_command_result { match set_command_result {
Ok(_) => (), Ok(_) => (),
Err(err) => log::error!("{:?}", err), Err(err) => log::error!("{err:?}"),
} }
let mut dispatcher = Dispatcher::builder(bot.clone(), handler) let mut dispatcher = Dispatcher::builder(bot.clone(), handler)

View File

@@ -22,6 +22,8 @@ use teloxide::prelude::*;
use moka::future::Cache; use moka::future::Cache;
use crate::bots_manager::bot_manager_client::delete_bot;
use self::axum_server::start_axum_server; use self::axum_server::start_axum_server;
use self::bot_manager_client::get_bots; use self::bot_manager_client::get_bots;
pub use self::bot_manager_client::{BotCache, BotData}; pub use self::bot_manager_client::{BotCache, BotData};
@@ -67,7 +69,7 @@ pub static BOTS_ROUTES: Lazy<Cache<String, StopTokenWithSender>> = Lazy::new(||
.time_to_idle(Duration::from_secs(60 * 60)) .time_to_idle(Duration::from_secs(60 * 60))
.max_capacity(100) .max_capacity(100)
.eviction_listener(|token, value: StopTokenWithSender, _cause| { .eviction_listener(|token, value: StopTokenWithSender, _cause| {
log::info!("Stop Bot(token={})!", token); log::info!("Stop Bot(token={token})!");
let (stop_token, _stop_flag, mut sender) = value; let (stop_token, _stop_flag, mut sender) = value;
@@ -135,7 +137,7 @@ impl BotsManager {
let bots_data = match bots_data { let bots_data = match bots_data {
Ok(v) => v, Ok(v) => v,
Err(err) => { Err(err) => {
log::info!("{:?}", err); log::info!("{err:?}");
return; return;
} }
}; };
@@ -185,7 +187,15 @@ impl BotsManager {
} }
} }
Err(err) => { Err(err) => {
log::error!("Error getting webhook info: {:?}", err); if err.to_string().contains("Api(InvalidToken)") {
BOTS_DATA.invalidate(token.as_str()).await;
if let Err(d_err) = delete_bot(bot_data.id).await {
log::error!("Error deleting bot {}: {:?}", bot_data.id, d_err);
};
continue;
}
log::error!("Error getting webhook info: {err:?}");
WEBHOOK_CHECK_ERRORS_COUNT WEBHOOK_CHECK_ERRORS_COUNT
.insert(bot_data.id, error_count + 1) .insert(bot_data.id, error_count + 1)

View File

@@ -28,7 +28,7 @@ pub struct Config {
} }
fn get_env(env: &'static str) -> String { fn get_env(env: &'static str) -> String {
std::env::var(env).unwrap_or_else(|_| panic!("Cannot get the {} env variable", env)) std::env::var(env).unwrap_or_else(|_| panic!("Cannot get the {env} env variable"))
} }
impl Config { impl Config {