From be54d8058b8943d7ca5ba13318acf30152d66423 Mon Sep 17 00:00:00 2001 From: Pahud Hsieh Date: Sun, 26 Apr 2026 16:26:55 -0400 Subject: [PATCH] fix(discord): use parent channel_id in SenderContext when in thread (#581) When a message is received inside a Discord thread, the agent now gets the parent channel ID as channel_id and the thread's channel ID as thread_id. Previously, channel_id contained the thread ID since Discord treats threads as separate channels. Closes #581 --- src/adapter.rs | 2 +- src/discord.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/adapter.rs b/src/adapter.rs index 0b5b2c1a..f76d319a 100644 --- a/src/adapter.rs +++ b/src/adapter.rs @@ -41,7 +41,7 @@ pub struct SenderContext { pub channel: String, pub channel_id: String, /// Thread identifier, if the message is inside a thread. - /// Slack: thread_ts. Discord: None (threads are separate channels). + /// Slack: thread_ts. Discord: thread channel ID (channel_id holds the parent). #[serde(skip_serializing_if = "Option::is_none")] pub thread_id: Option, pub is_bot: bool, diff --git a/src/discord.rs b/src/discord.rs index 50adab74..780350f8 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -384,8 +384,9 @@ impl EventHandler for Handler { // Thread detection: single to_channel() call for both allowed and // non-allowed channels. Uses thread_metadata (not parent_id) to // identify threads — see detect_thread() doc comments for rationale. - let (in_thread, bot_owns_thread) = match msg.channel_id.to_channel(&ctx.http).await { + let (in_thread, bot_owns_thread, thread_parent_id) = match msg.channel_id.to_channel(&ctx.http).await { Ok(serenity::model::channel::Channel::Guild(gc)) => { + let parent = gc.parent_id.map(|id| id.get().to_string()); let result = detect_thread( gc.thread_metadata.is_some(), gc.parent_id.map(|id| id.get()), @@ -404,15 +405,15 @@ impl EventHandler for Handler { bot_owns = ?result.1, "thread check" ); - (result.0, result.1.unwrap_or(false)) + (result.0, result.1.unwrap_or(false), if result.0 { parent } else { None }) } Ok(other) => { tracing::debug!(channel_id = %msg.channel_id, kind = ?other, "not a guild thread"); - (false, false) + (false, false, None) } Err(e) => { tracing::debug!(channel_id = %msg.channel_id, error = %e, "to_channel failed"); - (false, false) + (false, false, None) } }; @@ -495,8 +496,8 @@ impl EventHandler for Handler { sender_name: msg.author.name.clone(), display_name: display_name.to_string(), channel: "discord".into(), - channel_id: msg.channel_id.to_string(), - thread_id: None, + channel_id: thread_parent_id.clone().unwrap_or_else(|| msg.channel_id.to_string()), + thread_id: if thread_parent_id.is_some() { Some(msg.channel_id.to_string()) } else { None }, is_bot: msg.author.bot, };