diff --git a/src/channels/dingtalk.rs b/src/channels/dingtalk.rs index 1cb985d..4b60b55 100644 --- a/src/channels/dingtalk.rs +++ b/src/channels/dingtalk.rs @@ -64,6 +64,18 @@ impl DingTalkChannel { let gw: GatewayResponse = resp.json().await?; Ok(gw) } + + fn resolve_reply_target( + sender_id: &str, + conversation_type: &str, + conversation_id: Option<&str>, + ) -> String { + if conversation_type == "1" { + sender_id.to_string() + } else { + conversation_id.unwrap_or(sender_id).to_string() + } + } } #[async_trait] @@ -193,14 +205,11 @@ impl Channel for DingTalkChannel { .unwrap_or("1"); // Private chat uses sender ID, group chat uses conversation ID - let chat_id = if conversation_type == "1" { - sender_id.to_string() - } else { - data.get("conversationId") - .and_then(|c| c.as_str()) - .unwrap_or(sender_id) - .to_string() - }; + let chat_id = Self::resolve_reply_target( + sender_id, + conversation_type, + data.get("conversationId").and_then(|c| c.as_str()), + ); // Store session webhook for later replies if let Some(webhook) = data.get("sessionWebhook").and_then(|w| w.as_str()) { @@ -229,7 +238,7 @@ impl Channel for DingTalkChannel { let channel_msg = ChannelMessage { id: Uuid::new_v4().to_string(), sender: sender_id.to_string(), - reply_to: sender_id.to_string(), + reply_to: chat_id, content: content.to_string(), channel: "dingtalk".to_string(), timestamp: std::time::SystemTime::now() @@ -306,4 +315,22 @@ client_secret = "secret" let config: crate::config::schema::DingTalkConfig = toml::from_str(toml_str).unwrap(); assert!(config.allowed_users.is_empty()); } + + #[test] + fn test_resolve_reply_target_private_chat_uses_sender_id() { + let target = DingTalkChannel::resolve_reply_target("staff_1", "1", Some("conv_1")); + assert_eq!(target, "staff_1"); + } + + #[test] + fn test_resolve_reply_target_group_chat_uses_conversation_id() { + let target = DingTalkChannel::resolve_reply_target("staff_1", "2", Some("conv_1")); + assert_eq!(target, "conv_1"); + } + + #[test] + fn test_resolve_reply_target_group_chat_falls_back_to_sender_id() { + let target = DingTalkChannel::resolve_reply_target("staff_1", "2", None); + assert_eq!(target, "staff_1"); + } } diff --git a/src/channels/matrix.rs b/src/channels/matrix.rs index dceb2ee..0462bbe 100644 --- a/src/channels/matrix.rs +++ b/src/channels/matrix.rs @@ -230,7 +230,7 @@ impl Channel for MatrixChannel { let msg = ChannelMessage { id: format!("mx_{}", chrono::Utc::now().timestamp_millis()), sender: event.sender.clone(), - reply_to: event.sender.clone(), + reply_to: self.room_id.clone(), content: body.clone(), channel: "matrix".to_string(), timestamp: std::time::SystemTime::now()