mirror of https://github.com/openclaw/openclaw.git
feat(discord): add autoArchiveDuration config option (#35065)
* feat(discord): add autoArchiveDuration config option
Add config option to control auto-archive duration for auto-created threads:
- autoArchiveDuration: 60 (default), 1440, 4320, or 10080
- Sets archive duration in minutes (1hr/1day/3days/1week)
- Accepts both string and numeric values
- Discord's default was 60 minutes (hardcoded)
Example config:
```yaml
channels:
discord:
guilds:
GUILD_ID:
channels:
CHANNEL_ID:
autoThread: true
autoArchiveDuration: 10080 # 1 week
```
* feat(discord): add autoArchiveDuration changelog entry (#35065) (thanks @davidguttman)
---------
Co-authored-by: Onur <onur@textcortex.com>
This commit is contained in:
parent
a76e810193
commit
b517dc089a
|
|
@ -12,6 +12,7 @@ Docs: https://docs.openclaw.ai
|
|||
- Exec/child commands: mark child command environments with `OPENCLAW_CLI` so subprocesses can detect when they were launched from the OpenClaw CLI. (#41411) Thanks @vincentkoc.
|
||||
- iOS/Home canvas: add a bundled welcome screen with a live agent overview that refreshes on connect, reconnect, and foreground return, and move the compact connection pill off the top-left canvas overlay. (#42456) Thanks @ngutman.
|
||||
- iOS/Home canvas: replace floating controls with a docked toolbar, make the bundled home scaffold adapt to smaller phones, and open chat in the resolved main session instead of a synthetic `ios` session. (#42456) Thanks @ngutman.
|
||||
- Discord/auto threads: add `autoArchiveDuration` channel config for auto-created threads so Discord thread archiving can stay at 1 hour, 1 day, 3 days, or 1 week instead of always using the 1-hour default. (#35065) Thanks @davidguttman.
|
||||
|
||||
### Breaking
|
||||
|
||||
|
|
|
|||
|
|
@ -384,6 +384,16 @@ export const DiscordGuildChannelSchema = z
|
|||
systemPrompt: z.string().optional(),
|
||||
includeThreadStarter: z.boolean().optional(),
|
||||
autoThread: z.boolean().optional(),
|
||||
/** Archive duration for auto-created threads in minutes. Discord supports 60, 1440 (1 day), 4320 (3 days), 10080 (1 week). Default: 60. */
|
||||
autoArchiveDuration: z
|
||||
.union([
|
||||
z.enum(["60", "1440", "4320", "10080"]),
|
||||
z.literal(60),
|
||||
z.literal(1440),
|
||||
z.literal(4320),
|
||||
z.literal(10080),
|
||||
])
|
||||
.optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export type DiscordGuildEntryResolved = {
|
|||
systemPrompt?: string;
|
||||
includeThreadStarter?: boolean;
|
||||
autoThread?: boolean;
|
||||
autoArchiveDuration?: "60" | "1440" | "4320" | "10080" | 60 | 1440 | 4320 | 10080;
|
||||
}
|
||||
>;
|
||||
};
|
||||
|
|
@ -55,6 +56,7 @@ export type DiscordChannelConfigResolved = {
|
|||
systemPrompt?: string;
|
||||
includeThreadStarter?: boolean;
|
||||
autoThread?: boolean;
|
||||
autoArchiveDuration?: "60" | "1440" | "4320" | "10080" | 60 | 1440 | 4320 | 10080;
|
||||
matchKey?: string;
|
||||
matchSource?: ChannelMatchSource;
|
||||
};
|
||||
|
|
@ -401,6 +403,7 @@ function resolveDiscordChannelConfigEntry(
|
|||
systemPrompt: entry.systemPrompt,
|
||||
includeThreadStarter: entry.includeThreadStarter,
|
||||
autoThread: entry.autoThread,
|
||||
autoArchiveDuration: entry.autoArchiveDuration,
|
||||
};
|
||||
return resolved;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { ChannelType } from "@buape/carbon";
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import { maybeCreateDiscordAutoThread } from "./threading.js";
|
||||
|
||||
describe("maybeCreateDiscordAutoThread", () => {
|
||||
|
|
@ -89,3 +89,74 @@ describe("maybeCreateDiscordAutoThread", () => {
|
|||
expect(postMock).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("maybeCreateDiscordAutoThread autoArchiveDuration", () => {
|
||||
const postMock = vi.fn();
|
||||
const getMock = vi.fn();
|
||||
const mockClient = {
|
||||
rest: { post: postMock, get: getMock },
|
||||
} as unknown as Parameters<typeof maybeCreateDiscordAutoThread>[0]["client"];
|
||||
const mockMessage = {
|
||||
id: "msg1",
|
||||
timestamp: "123",
|
||||
} as unknown as Parameters<typeof maybeCreateDiscordAutoThread>[0]["message"];
|
||||
|
||||
beforeEach(() => {
|
||||
postMock.mockReset();
|
||||
getMock.mockReset();
|
||||
});
|
||||
|
||||
it("uses configured autoArchiveDuration", async () => {
|
||||
postMock.mockResolvedValueOnce({ id: "thread1" });
|
||||
await maybeCreateDiscordAutoThread({
|
||||
client: mockClient,
|
||||
message: mockMessage,
|
||||
messageChannelId: "text1",
|
||||
isGuildMessage: true,
|
||||
channelConfig: { allowed: true, autoThread: true, autoArchiveDuration: "10080" },
|
||||
channelType: ChannelType.GuildText,
|
||||
baseText: "test",
|
||||
combinedBody: "test",
|
||||
});
|
||||
expect(postMock).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.objectContaining({ body: expect.objectContaining({ auto_archive_duration: 10080 }) }),
|
||||
);
|
||||
});
|
||||
|
||||
it("accepts numeric autoArchiveDuration", async () => {
|
||||
postMock.mockResolvedValueOnce({ id: "thread1" });
|
||||
await maybeCreateDiscordAutoThread({
|
||||
client: mockClient,
|
||||
message: mockMessage,
|
||||
messageChannelId: "text1",
|
||||
isGuildMessage: true,
|
||||
channelConfig: { allowed: true, autoThread: true, autoArchiveDuration: 4320 },
|
||||
channelType: ChannelType.GuildText,
|
||||
baseText: "test",
|
||||
combinedBody: "test",
|
||||
});
|
||||
expect(postMock).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.objectContaining({ body: expect.objectContaining({ auto_archive_duration: 4320 }) }),
|
||||
);
|
||||
});
|
||||
|
||||
it("defaults to 60 when autoArchiveDuration not set", async () => {
|
||||
postMock.mockResolvedValueOnce({ id: "thread1" });
|
||||
await maybeCreateDiscordAutoThread({
|
||||
client: mockClient,
|
||||
message: mockMessage,
|
||||
messageChannelId: "text1",
|
||||
isGuildMessage: true,
|
||||
channelConfig: { allowed: true, autoThread: true },
|
||||
channelType: ChannelType.GuildText,
|
||||
baseText: "test",
|
||||
combinedBody: "test",
|
||||
});
|
||||
expect(postMock).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.objectContaining({ body: expect.objectContaining({ auto_archive_duration: 60 }) }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -397,12 +397,18 @@ export async function maybeCreateDiscordAutoThread(params: {
|
|||
params.baseText || params.combinedBody || "Thread",
|
||||
params.message.id,
|
||||
);
|
||||
|
||||
// Parse archive duration from config, default to 60 minutes
|
||||
const archiveDuration = params.channelConfig?.autoArchiveDuration
|
||||
? Number(params.channelConfig.autoArchiveDuration)
|
||||
: 60;
|
||||
|
||||
const created = (await params.client.rest.post(
|
||||
`${Routes.channelMessage(messageChannelId, params.message.id)}/threads`,
|
||||
{
|
||||
body: {
|
||||
name: threadName,
|
||||
auto_archive_duration: 60,
|
||||
auto_archive_duration: archiveDuration,
|
||||
},
|
||||
},
|
||||
)) as { id?: string };
|
||||
|
|
|
|||
Loading…
Reference in New Issue