Slack: refine scopes and onboarding

This commit is contained in:
Shadow
2026-01-03 23:12:11 -06:00
committed by Peter Steinberger
parent bf3d120f8c
commit 0085b2e0a9
17 changed files with 2484 additions and 1 deletions

View File

@@ -40,6 +40,7 @@ const GROUP_LABELS: Record<string, string> = {
talk: "Talk",
telegram: "Telegram",
discord: "Discord",
slack: "Slack",
signal: "Signal",
imessage: "iMessage",
whatsapp: "WhatsApp",
@@ -65,6 +66,7 @@ const GROUP_ORDER: Record<string, number> = {
talk: 130,
telegram: 140,
discord: 150,
slack: 155,
signal: 160,
imessage: 170,
whatsapp: 180,
@@ -92,6 +94,8 @@ const FIELD_LABELS: Record<string, string> = {
"talk.apiKey": "Talk API Key",
"telegram.botToken": "Telegram Bot Token",
"discord.token": "Discord Bot Token",
"slack.botToken": "Slack Bot Token",
"slack.appToken": "Slack App Token",
"signal.account": "Signal Account",
"imessage.cliPath": "iMessage CLI Path",
};

View File

@@ -144,6 +144,7 @@ export type HookMappingConfig = {
| "whatsapp"
| "telegram"
| "discord"
| "slack"
| "signal"
| "imessage";
to?: string;
@@ -290,6 +291,64 @@ export type DiscordConfig = {
guilds?: Record<string, DiscordGuildEntry>;
};
export type SlackDmConfig = {
/** If false, ignore all incoming Slack DMs. Default: true. */
enabled?: boolean;
/** Allowlist for DM senders (ids). */
allowFrom?: Array<string | number>;
/** If true, allow group DMs (default: false). */
groupEnabled?: boolean;
/** Optional allowlist for group DM channels (ids or slugs). */
groupChannels?: Array<string | number>;
};
export type SlackChannelConfig = {
allow?: boolean;
requireMention?: boolean;
};
export type SlackReactionNotificationMode = "off" | "own" | "all" | "allowlist";
export type SlackActionConfig = {
reactions?: boolean;
messages?: boolean;
pins?: boolean;
search?: boolean;
permissions?: boolean;
memberInfo?: boolean;
channelInfo?: boolean;
emojiList?: boolean;
};
export type SlackSlashCommandConfig = {
/** Enable handling for the configured slash command (default: false). */
enabled?: boolean;
/** Slash command name (default: "clawd"). */
name?: string;
/** Session key prefix for slash commands (default: "slack:slash"). */
sessionPrefix?: string;
/** Reply ephemerally (default: true). */
ephemeral?: boolean;
};
export type SlackConfig = {
/** If false, do not start the Slack provider. Default: true. */
enabled?: boolean;
botToken?: string;
appToken?: string;
textChunkLimit?: number;
replyToMode?: ReplyToMode;
mediaMaxMb?: number;
/** Reaction notification mode (off|own|all|allowlist). Default: own. */
reactionNotifications?: SlackReactionNotificationMode;
/** Allowlist for reaction notifications when mode is allowlist. */
reactionAllowlist?: Array<string | number>;
actions?: SlackActionConfig;
slashCommand?: SlackSlashCommandConfig;
dm?: SlackDmConfig;
channels?: Record<string, SlackChannelConfig>;
};
export type SignalConfig = {
/** If false, do not start the Signal provider. Default: true. */
enabled?: boolean;
@@ -356,6 +415,7 @@ export type QueueModeBySurface = {
whatsapp?: QueueMode;
telegram?: QueueMode;
discord?: QueueMode;
slack?: QueueMode;
signal?: QueueMode;
imessage?: QueueMode;
webchat?: QueueMode;
@@ -642,6 +702,7 @@ export type ClawdisConfig = {
| "whatsapp"
| "telegram"
| "discord"
| "slack"
| "signal"
| "imessage"
| "none";
@@ -731,6 +792,7 @@ export type ClawdisConfig = {
whatsapp?: WhatsAppConfig;
telegram?: TelegramConfig;
discord?: DiscordConfig;
slack?: SlackConfig;
signal?: SignalConfig;
imessage?: IMessageConfig;
cron?: CronConfig;

View File

@@ -86,6 +86,7 @@ const QueueModeBySurfaceSchema = z
whatsapp: QueueModeSchema.optional(),
telegram: QueueModeSchema.optional(),
discord: QueueModeSchema.optional(),
slack: QueueModeSchema.optional(),
signal: QueueModeSchema.optional(),
imessage: QueueModeSchema.optional(),
webchat: QueueModeSchema.optional(),
@@ -163,6 +164,7 @@ const HeartbeatSchema = z
z.literal("whatsapp"),
z.literal("telegram"),
z.literal("discord"),
z.literal("slack"),
z.literal("signal"),
z.literal("imessage"),
z.literal("none"),
@@ -225,6 +227,7 @@ const HookMappingSchema = z
z.literal("whatsapp"),
z.literal("telegram"),
z.literal("discord"),
z.literal("slack"),
z.literal("signal"),
z.literal("imessage"),
])
@@ -619,6 +622,59 @@ export const ClawdisSchema = z.object({
.optional(),
})
.optional(),
slack: z
.object({
enabled: z.boolean().optional(),
botToken: z.string().optional(),
appToken: z.string().optional(),
textChunkLimit: z.number().int().positive().optional(),
replyToMode: ReplyToModeSchema.optional(),
mediaMaxMb: z.number().positive().optional(),
reactionNotifications: z
.enum(["off", "own", "all", "allowlist"])
.optional(),
reactionAllowlist: z.array(z.union([z.string(), z.number()])).optional(),
actions: z
.object({
reactions: z.boolean().optional(),
messages: z.boolean().optional(),
pins: z.boolean().optional(),
search: z.boolean().optional(),
permissions: z.boolean().optional(),
memberInfo: z.boolean().optional(),
channelInfo: z.boolean().optional(),
emojiList: z.boolean().optional(),
})
.optional(),
slashCommand: z
.object({
enabled: z.boolean().optional(),
name: z.string().optional(),
sessionPrefix: z.string().optional(),
ephemeral: z.boolean().optional(),
})
.optional(),
dm: z
.object({
enabled: z.boolean().optional(),
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
groupEnabled: z.boolean().optional(),
groupChannels: z.array(z.union([z.string(), z.number()])).optional(),
})
.optional(),
channels: z
.record(
z.string(),
z
.object({
allow: z.boolean().optional(),
requireMention: z.boolean().optional(),
})
.optional(),
)
.optional(),
})
.optional(),
signal: z
.object({
enabled: z.boolean().optional(),