Bug fixes
This commit is contained in:
@@ -124,8 +124,28 @@ struct BotContext {
|
||||
sem: Arc<tokio::sync::Semaphore>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
fn main() {
|
||||
// Windows default thread stack is 1MB; teloxide futures + large Telegram types
|
||||
// (CallbackQuery/Message ~5KB each) can exhaust this during dptree dispatch.
|
||||
// Spawn the tokio runtime on a thread with an 8MB stack.
|
||||
let stack_size = 8 * 1024 * 1024;
|
||||
std::thread::Builder::new()
|
||||
.name("cgcx-bot-main".into())
|
||||
.stack_size(stack_size)
|
||||
.spawn(|| {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.worker_threads(4)
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("tokio runtime")
|
||||
.block_on(run_bot());
|
||||
})
|
||||
.expect("spawn main thread")
|
||||
.join()
|
||||
.expect("main thread panicked");
|
||||
}
|
||||
|
||||
async fn run_bot() {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let config = Arc::new(Config::load().expect("Failed to load config"));
|
||||
@@ -175,6 +195,7 @@ async fn main() {
|
||||
.await;
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
async fn handle_message(
|
||||
bot: Bot,
|
||||
msg: Message,
|
||||
@@ -285,27 +306,33 @@ async fn handle_message(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
async fn handle_callback(
|
||||
bot: Bot,
|
||||
q: CallbackQuery,
|
||||
storage: Arc<InMemStorage<BotState>>,
|
||||
ctx: BotContext,
|
||||
) -> HandlerResult {
|
||||
let data = q.data.as_deref().unwrap_or("");
|
||||
let user = q.from;
|
||||
let user_id = user.id.0 as i64;
|
||||
// CallbackQuery (and the Message it may contain) are very large structs.
|
||||
// Extract only the fields we need and drop q before the first .await so
|
||||
// the compiler can keep the async state machine small.
|
||||
let callback_id = q.id.clone();
|
||||
let data = q.data.as_deref().unwrap_or("").to_string();
|
||||
let user_id = q.from.id.0 as i64;
|
||||
let chat_id = q.message.as_ref().map(|m| m.chat().id).unwrap_or(ChatId(user_id));
|
||||
let message_id = q.message.as_ref().map(|m| m.id());
|
||||
drop(q);
|
||||
|
||||
if !ctx.moderation.is_allowed(user_id).await {
|
||||
bot.answer_callback_query(&q.id).text("Not allowed").await?;
|
||||
bot.answer_callback_query(&callback_id).text("Not allowed").await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let chat_id = q.message.as_ref().map(|m| m.chat().id).unwrap_or(ChatId(user_id));
|
||||
let dialogue = BotDialogue { chat_id, storage };
|
||||
|
||||
let parts: Vec<&str> = data.split(':').collect();
|
||||
if parts.len() < 3 || parts[0] != "v1" {
|
||||
bot.answer_callback_query(&q.id).await?;
|
||||
bot.answer_callback_query(&callback_id).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -314,14 +341,14 @@ async fn handle_callback(
|
||||
"accept" => {
|
||||
let user_repo = UserRepo::new(ctx.db.conn());
|
||||
user_repo.set_accepted_terms(user_id).await?;
|
||||
if let Some(msg) = &q.message {
|
||||
bot.delete_message(chat_id, msg.id()).await.ok();
|
||||
if let Some(mid) = message_id {
|
||||
bot.delete_message(chat_id, mid).await.ok();
|
||||
}
|
||||
send_main_menu(&bot, chat_id, &dialogue).await?;
|
||||
}
|
||||
"reject" => {
|
||||
if let Some(msg) = &q.message {
|
||||
bot.delete_message(chat_id, msg.id()).await.ok();
|
||||
if let Some(mid) = message_id {
|
||||
bot.delete_message(chat_id, mid).await.ok();
|
||||
}
|
||||
dialogue.reset().await?;
|
||||
}
|
||||
@@ -358,7 +385,7 @@ async fn handle_callback(
|
||||
let state = dialogue.get_or_default().await?;
|
||||
if let BotState::UploadStaging { items, .. } = state {
|
||||
if items.is_empty() {
|
||||
bot.answer_callback_query(&q.id).text("No items to upload.").await?;
|
||||
bot.answer_callback_query(&callback_id).text("No items to upload.").await?;
|
||||
} else {
|
||||
let options = UploadOptions {
|
||||
allow_download: true,
|
||||
@@ -370,8 +397,8 @@ async fn handle_callback(
|
||||
}
|
||||
}
|
||||
"cancel" => {
|
||||
if let Some(msg) = &q.message {
|
||||
bot.edit_message_text(chat_id, msg.id(), "Upload cancelled.").await.ok();
|
||||
if let Some(mid) = message_id {
|
||||
bot.edit_message_text(chat_id, mid, "Upload cancelled.").await.ok();
|
||||
}
|
||||
dialogue.update(BotState::MainMenu).await?;
|
||||
}
|
||||
@@ -429,7 +456,7 @@ async fn handle_callback(
|
||||
_ => {}
|
||||
}
|
||||
|
||||
bot.answer_callback_query(&q.id).await?;
|
||||
bot.answer_callback_query(&callback_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -491,6 +518,7 @@ async fn send_staging_message(bot: &Bot, chat_id: ChatId, items: &[StagedItem],
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
async fn handle_staging_message(
|
||||
bot: &Bot,
|
||||
msg: Message,
|
||||
@@ -504,6 +532,8 @@ async fn handle_staging_message(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let chat_id = msg.chat.id;
|
||||
let caption = msg.caption().map(|s| s.to_string());
|
||||
let mut new_item = None;
|
||||
|
||||
match upload_type {
|
||||
@@ -516,7 +546,7 @@ async fn handle_staging_message(
|
||||
file_name: format!("photo_{}.jpg", items.len()),
|
||||
mime_type: "image/jpeg".to_string(),
|
||||
size: p.file.size as u64,
|
||||
caption: msg.caption().map(|s| s.to_string()),
|
||||
caption: caption.clone(),
|
||||
});
|
||||
}
|
||||
} else if let Some(video) = msg.video() {
|
||||
@@ -525,7 +555,7 @@ async fn handle_staging_message(
|
||||
file_name: video.file_name.clone().unwrap_or_else(|| format!("video_{}.mp4", items.len())),
|
||||
mime_type: "video/mp4".to_string(),
|
||||
size: video.file.size as u64,
|
||||
caption: msg.caption().map(|s| s.to_string()),
|
||||
caption: caption.clone(),
|
||||
});
|
||||
} else if let Some(audio) = msg.audio() {
|
||||
new_item = Some(StagedItem {
|
||||
@@ -533,7 +563,7 @@ async fn handle_staging_message(
|
||||
file_name: audio.file_name.clone().unwrap_or_else(|| format!("audio_{}.mp3", items.len())),
|
||||
mime_type: "audio/mpeg".to_string(),
|
||||
size: audio.file.size as u64,
|
||||
caption: msg.caption().map(|s| s.to_string()),
|
||||
caption: caption.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -544,7 +574,7 @@ async fn handle_staging_message(
|
||||
file_name: doc.file_name.clone().unwrap_or_else(|| format!("file_{}", items.len())),
|
||||
mime_type: doc.mime_type.clone().map(|m| m.to_string()).unwrap_or_else(|| "application/octet-stream".to_string()),
|
||||
size: doc.file.size as u64,
|
||||
caption: msg.caption().map(|s| s.to_string()),
|
||||
caption: caption.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -563,10 +593,12 @@ async fn handle_staging_message(
|
||||
}
|
||||
}
|
||||
|
||||
drop(msg);
|
||||
|
||||
if let Some(item) = new_item {
|
||||
items.push(item);
|
||||
dialogue.update(BotState::UploadStaging { items: items.clone(), upload_type }).await?;
|
||||
send_staging_message(bot, msg.chat.id, &items, upload_type).await?;
|
||||
send_staging_message(bot, chat_id, &items, upload_type).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user