use std::sync::Arc;
use tracing::{debug, warn};
use crate::ilink::types::WeixinMessage;
use super::super::*;
use super::hub_ext::{build_hub_ext_for_vctx, resolve_vctx_for_message};
use super::queue::push_to_queue;
pub(super) async fn handle_at_mention(
state: Arc<HubState>,
mut msg: WeixinMessage,
backend_name: String,
vtoken: String,
payload: String,
) {
let real_ctx = match msg.context_token.clone() {
Some(ctx) if !ctx.is_empty() => ctx,
_ => {
warn!("@mention message has no context_token, skipping dispatch");
return;
}
};
let peer_user_id = msg.from_user_id.clone().unwrap_or_default();
let group_id = msg.group_id.clone();
let vctx =
resolve_vctx_for_message(&state, &real_ctx, &peer_user_id, group_id.as_deref(), None).await;
let session_name = format!("at-{}", chrono::Local::now().format("%Y%m%d-%H%M%S%3f"));
if let Err(e) = state
.store
.set_backend_session(&vctx, &vtoken, &session_name, "")
.await
{
warn!(error = %e, vctx = %vctx, session = %session_name, "failed to pre-create @mention session slot");
}
debug!(
backend = %backend_name,
vtoken = %crate::redact_token(&vtoken),
session = %session_name,
"routing @mention to new session"
);
let hub_ext =
build_hub_ext_for_vctx(&state.store, &vctx, &vtoken, Some(session_name.clone())).await;
set_first_text_item(&mut msg, payload);
msg.context_token = Some(vctx);
msg.ilink_hub_ext = hub_ext;
push_to_queue(&state.clients.queue, &state.metrics, &vtoken, msg).await;
}
pub(super) fn set_first_text_item(msg: &mut WeixinMessage, text: String) {
let Some(items) = msg.item_list.as_mut() else {
return;
};
let items_mut = std::sync::Arc::make_mut(items);
if let Some(item) = items_mut.iter_mut().find(|i| i.text_item.is_some()) {
if let Some(ti) = item.text_item.as_mut() {
ti.text = Some(text);
}
}
}