Merge branch 'pr-730-merge'
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
- Docs: add gog calendar event color IDs from `gog calendar colors`. (#715) — thanks @mjrussell.
|
- Docs: add gog calendar event color IDs from `gog calendar colors`. (#715) — thanks @mjrussell.
|
||||||
- Cron/CLI: trim model overrides on cron edits and document main-session guidance. (#711) — thanks @mjrussell.
|
- Cron/CLI: trim model overrides on cron edits and document main-session guidance. (#711) — thanks @mjrussell.
|
||||||
- Skills: bundle `skill-creator` to guide creating and packaging skills.
|
- Skills: bundle `skill-creator` to guide creating and packaging skills.
|
||||||
|
- Discord: expose channel/category management actions in the message tool. (#730) — thanks @NicholasSpisak
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Doctor: surface plugin diagnostics in the report.
|
- Doctor: surface plugin diagnostics in the report.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: discord
|
name: discord
|
||||||
description: Use when you need to control Discord from Clawdbot via the discord tool: send messages, react, post or upload stickers, upload emojis, run polls, manage threads/pins/search, fetch permissions or member/role/channel info, or handle moderation actions in Discord DMs or channels.
|
description: Use when you need to control Discord from Clawdbot via the discord tool: send messages, react, post or upload stickers, upload emojis, run polls, manage threads/pins/search, create/edit/delete channels and categories, fetch permissions or member/role/channel info, or handle moderation actions in Discord DMs or channels.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Discord Actions
|
# Discord Actions
|
||||||
@@ -135,6 +135,7 @@ Use `discord.actions.*` to disable action groups:
|
|||||||
- `emojiUploads`, `stickerUploads`
|
- `emojiUploads`, `stickerUploads`
|
||||||
- `memberInfo`, `roleInfo`, `channelInfo`, `voiceStatus`, `events`
|
- `memberInfo`, `roleInfo`, `channelInfo`, `voiceStatus`, `events`
|
||||||
- `roles` (role add/remove, default `false`)
|
- `roles` (role add/remove, default `false`)
|
||||||
|
- `channels` (channel/category create/edit/delete/move, default `false`)
|
||||||
- `moderation` (timeout/kick/ban, default `false`)
|
- `moderation` (timeout/kick/ban, default `false`)
|
||||||
### Read recent messages
|
### Read recent messages
|
||||||
|
|
||||||
@@ -314,6 +315,90 @@ Use `discord.actions.*` to disable action groups:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Channel management (disabled by default)
|
||||||
|
|
||||||
|
Create, edit, delete, and move channels and categories. Enable via `discord.actions.channels: true`.
|
||||||
|
|
||||||
|
**Create a text channel:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "channelCreate",
|
||||||
|
"guildId": "999",
|
||||||
|
"name": "general-chat",
|
||||||
|
"type": 0,
|
||||||
|
"parentId": "888",
|
||||||
|
"topic": "General discussion"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `type`: Discord channel type integer (0 = text, 2 = voice, 4 = category; other values supported)
|
||||||
|
- `parentId`: category ID to nest under (optional)
|
||||||
|
- `topic`, `position`, `nsfw`: optional
|
||||||
|
|
||||||
|
**Create a category:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "categoryCreate",
|
||||||
|
"guildId": "999",
|
||||||
|
"name": "Projects"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Edit a channel:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "channelEdit",
|
||||||
|
"channelId": "123",
|
||||||
|
"name": "new-name",
|
||||||
|
"topic": "Updated topic"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Supports `name`, `topic`, `position`, `parentId` (null to remove from category), `nsfw`, `rateLimitPerUser`
|
||||||
|
|
||||||
|
**Move a channel:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "channelMove",
|
||||||
|
"guildId": "999",
|
||||||
|
"channelId": "123",
|
||||||
|
"parentId": "888",
|
||||||
|
"position": 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `parentId`: target category (null to move to top level)
|
||||||
|
|
||||||
|
**Delete a channel:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "channelDelete",
|
||||||
|
"channelId": "123"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Edit/delete a category:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "categoryEdit",
|
||||||
|
"categoryId": "888",
|
||||||
|
"name": "Renamed Category"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "categoryDelete",
|
||||||
|
"categoryId": "888"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Voice status
|
### Voice status
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ const AllMessageActions = [
|
|||||||
"role-remove",
|
"role-remove",
|
||||||
"channel-info",
|
"channel-info",
|
||||||
"channel-list",
|
"channel-list",
|
||||||
|
"channel-create",
|
||||||
|
"channel-edit",
|
||||||
|
"channel-delete",
|
||||||
|
"channel-move",
|
||||||
|
"category-create",
|
||||||
|
"category-edit",
|
||||||
|
"category-delete",
|
||||||
"voice-status",
|
"voice-status",
|
||||||
"event-list",
|
"event-list",
|
||||||
"event-create",
|
"event-create",
|
||||||
@@ -130,6 +137,14 @@ const MessageToolCommonSchema = {
|
|||||||
gatewayUrl: Type.Optional(Type.String()),
|
gatewayUrl: Type.Optional(Type.String()),
|
||||||
gatewayToken: Type.Optional(Type.String()),
|
gatewayToken: Type.Optional(Type.String()),
|
||||||
timeoutMs: Type.Optional(Type.Number()),
|
timeoutMs: Type.Optional(Type.Number()),
|
||||||
|
name: Type.Optional(Type.String()),
|
||||||
|
type: Type.Optional(Type.Number()),
|
||||||
|
parentId: Type.Optional(Type.Union([Type.String(), Type.Null()])),
|
||||||
|
topic: Type.Optional(Type.String()),
|
||||||
|
position: Type.Optional(Type.Number()),
|
||||||
|
nsfw: Type.Optional(Type.Boolean()),
|
||||||
|
rateLimitPerUser: Type.Optional(Type.Number()),
|
||||||
|
categoryId: Type.Optional(Type.String()),
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildMessageToolSchemaFromActions(
|
function buildMessageToolSchemaFromActions(
|
||||||
|
|||||||
@@ -57,6 +57,15 @@ export const discordMessageActions: ProviderMessageActionAdapter = {
|
|||||||
actions.add("channel-info");
|
actions.add("channel-info");
|
||||||
actions.add("channel-list");
|
actions.add("channel-list");
|
||||||
}
|
}
|
||||||
|
if (gate("channels", false)) {
|
||||||
|
actions.add("channel-create");
|
||||||
|
actions.add("channel-edit");
|
||||||
|
actions.add("channel-delete");
|
||||||
|
actions.add("channel-move");
|
||||||
|
actions.add("category-create");
|
||||||
|
actions.add("category-edit");
|
||||||
|
actions.add("category-delete");
|
||||||
|
}
|
||||||
if (gate("voiceStatus")) actions.add("voice-status");
|
if (gate("voiceStatus")) actions.add("voice-status");
|
||||||
if (gate("events")) {
|
if (gate("events")) {
|
||||||
actions.add("event-list");
|
actions.add("event-list");
|
||||||
@@ -449,6 +458,136 @@ export const discordMessageActions: ProviderMessageActionAdapter = {
|
|||||||
return await handleDiscordAction({ action: "channelList", guildId }, cfg);
|
return await handleDiscordAction({ action: "channelList", guildId }, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action === "channel-create") {
|
||||||
|
const guildId = readStringParam(params, "guildId", { required: true });
|
||||||
|
const name = readStringParam(params, "name", { required: true });
|
||||||
|
const type = readNumberParam(params, "type", { integer: true });
|
||||||
|
const parentId =
|
||||||
|
params.parentId === null
|
||||||
|
? null
|
||||||
|
: readStringParam(params, "parentId");
|
||||||
|
const topic = readStringParam(params, "topic");
|
||||||
|
const position = readNumberParam(params, "position", { integer: true });
|
||||||
|
const nsfw = typeof params.nsfw === "boolean" ? params.nsfw : undefined;
|
||||||
|
return await handleDiscordAction(
|
||||||
|
{
|
||||||
|
action: "channelCreate",
|
||||||
|
guildId,
|
||||||
|
name,
|
||||||
|
type: type ?? undefined,
|
||||||
|
parentId: parentId ?? undefined,
|
||||||
|
topic: topic ?? undefined,
|
||||||
|
position: position ?? undefined,
|
||||||
|
nsfw,
|
||||||
|
},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "channel-edit") {
|
||||||
|
const channelId = readStringParam(params, "channelId", {
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
const name = readStringParam(params, "name");
|
||||||
|
const topic = readStringParam(params, "topic");
|
||||||
|
const position = readNumberParam(params, "position", { integer: true });
|
||||||
|
const parentId =
|
||||||
|
params.parentId === null
|
||||||
|
? null
|
||||||
|
: readStringParam(params, "parentId");
|
||||||
|
const nsfw = typeof params.nsfw === "boolean" ? params.nsfw : undefined;
|
||||||
|
const rateLimitPerUser = readNumberParam(params, "rateLimitPerUser", {
|
||||||
|
integer: true,
|
||||||
|
});
|
||||||
|
return await handleDiscordAction(
|
||||||
|
{
|
||||||
|
action: "channelEdit",
|
||||||
|
channelId,
|
||||||
|
name: name ?? undefined,
|
||||||
|
topic: topic ?? undefined,
|
||||||
|
position: position ?? undefined,
|
||||||
|
parentId: parentId === undefined ? undefined : parentId,
|
||||||
|
nsfw,
|
||||||
|
rateLimitPerUser: rateLimitPerUser ?? undefined,
|
||||||
|
},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "channel-delete") {
|
||||||
|
const channelId = readStringParam(params, "channelId", {
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
return await handleDiscordAction(
|
||||||
|
{ action: "channelDelete", channelId },
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "channel-move") {
|
||||||
|
const guildId = readStringParam(params, "guildId", { required: true });
|
||||||
|
const channelId = readStringParam(params, "channelId", {
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
const parentId =
|
||||||
|
params.parentId === null
|
||||||
|
? null
|
||||||
|
: readStringParam(params, "parentId");
|
||||||
|
const position = readNumberParam(params, "position", { integer: true });
|
||||||
|
return await handleDiscordAction(
|
||||||
|
{
|
||||||
|
action: "channelMove",
|
||||||
|
guildId,
|
||||||
|
channelId,
|
||||||
|
parentId: parentId === undefined ? undefined : parentId,
|
||||||
|
position: position ?? undefined,
|
||||||
|
},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "category-create") {
|
||||||
|
const guildId = readStringParam(params, "guildId", { required: true });
|
||||||
|
const name = readStringParam(params, "name", { required: true });
|
||||||
|
const position = readNumberParam(params, "position", { integer: true });
|
||||||
|
return await handleDiscordAction(
|
||||||
|
{
|
||||||
|
action: "categoryCreate",
|
||||||
|
guildId,
|
||||||
|
name,
|
||||||
|
position: position ?? undefined,
|
||||||
|
},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "category-edit") {
|
||||||
|
const categoryId = readStringParam(params, "categoryId", {
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
const name = readStringParam(params, "name");
|
||||||
|
const position = readNumberParam(params, "position", { integer: true });
|
||||||
|
return await handleDiscordAction(
|
||||||
|
{
|
||||||
|
action: "categoryEdit",
|
||||||
|
categoryId,
|
||||||
|
name: name ?? undefined,
|
||||||
|
position: position ?? undefined,
|
||||||
|
},
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "category-delete") {
|
||||||
|
const categoryId = readStringParam(params, "categoryId", {
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
return await handleDiscordAction(
|
||||||
|
{ action: "categoryDelete", categoryId },
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (action === "voice-status") {
|
if (action === "voice-status") {
|
||||||
const guildId = readStringParam(params, "guildId", {
|
const guildId = readStringParam(params, "guildId", {
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user