Fix Discord autoThread thread-only replies (#807)
Co-authored-by: Shadow <shadow@clawd.bot>
This commit is contained in:
@@ -56,6 +56,7 @@
|
||||
- Auto-reply: elevated/reasoning toggles now enqueue system events so the model sees the mode change immediately.
|
||||
- Tools: keep `image` available in sandbox and fail over when image models return empty output (fixes “(no text returned)”).
|
||||
- Discord: add per-channel `autoThread` to auto-create threads for top-level messages. (#800) — thanks @davidguttman.
|
||||
- Discord: fix autoThread routing so replies stay in the created thread and avoid reply references. (#807) — thanks @davidguttman.
|
||||
- Onboarding: TUI defaults to `deliver: false` to avoid cross-provider auto-delivery leaks; onboarding spawns the TUI with explicit `deliver: false`. (#791 — thanks @roshanasingh4)
|
||||
|
||||
## 2026.1.11
|
||||
|
||||
@@ -1179,23 +1179,26 @@ export function createDiscordMessageHandler(params: {
|
||||
OriginatingChannel: "discord" as const,
|
||||
OriginatingTo: discordTo,
|
||||
};
|
||||
const replyTarget = ctxPayload.To ?? undefined;
|
||||
let replyTarget = ctxPayload.To ?? undefined;
|
||||
if (!replyTarget) {
|
||||
runtime.error?.(danger("discord: missing reply target"));
|
||||
return;
|
||||
}
|
||||
|
||||
const originalReplyTarget = replyTarget;
|
||||
|
||||
let deliverTarget = replyTarget;
|
||||
if (isGuildMessage && channelConfig?.autoThread && !threadChannel) {
|
||||
try {
|
||||
const base = truncateUtf16Safe(
|
||||
(baseText || combinedBody || "Thread").replace(/\s+/g, " ").trim(),
|
||||
80,
|
||||
);
|
||||
const authorLabel = author.username ?? author.id;
|
||||
const threadName =
|
||||
truncateUtf16Safe(`${authorLabel}: ${base}`.trim(), 100) ||
|
||||
`Thread ${message.id}`;
|
||||
const rawName = baseText || combinedBody || "Thread";
|
||||
const cleanedName = rawName
|
||||
.replace(/<@!?\d+>/g, "") // user mentions
|
||||
.replace(/<@&\d+>/g, "") // role mentions
|
||||
.replace(/<#\d+>/g, "") // channel mentions
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
const base = truncateUtf16Safe(cleanedName || "Thread", 80);
|
||||
const threadName = truncateUtf16Safe(base, 100) || `Thread ${message.id}`;
|
||||
|
||||
const created = (await client.rest.post(
|
||||
`${Routes.channelMessage(message.channelId, message.id)}/threads`,
|
||||
@@ -1210,6 +1213,8 @@ export function createDiscordMessageHandler(params: {
|
||||
const createdId = created?.id ? String(created.id) : "";
|
||||
if (createdId) {
|
||||
deliverTarget = `channel:${createdId}`;
|
||||
// When autoThread is enabled, *always* reply in the created thread.
|
||||
replyTarget = deliverTarget;
|
||||
}
|
||||
} catch (err) {
|
||||
logVerbose(
|
||||
@@ -1251,12 +1256,15 @@ export function createDiscordMessageHandler(params: {
|
||||
deliver: async (payload) => {
|
||||
await deliverDiscordReply({
|
||||
replies: [payload],
|
||||
target: deliverTarget,
|
||||
target: replyTarget,
|
||||
token,
|
||||
accountId,
|
||||
rest: client.rest,
|
||||
runtime,
|
||||
replyToMode: deliverTarget !== replyTarget ? "off" : replyToMode,
|
||||
// The original message is in the parent channel; never try to reply-reference it
|
||||
// when posting inside the newly-created thread.
|
||||
replyToMode:
|
||||
deliverTarget !== originalReplyTarget ? "off" : replyToMode,
|
||||
textLimit,
|
||||
maxLinesPerMessage: discordConfig?.maxLinesPerMessage,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user