import { MarkdownConfigSchema } from "openclaw/plugin-sdk/channel-config-primitives" ;
import { z } from "openclaw/plugin-sdk/zod" ;
/**
* Twitch user roles that can be allowed to interact with the bot
*/
const TwitchRoleSchema = z.enum (["moderator" , "owner" , "vip" , "subscriber" , "all" ]);
/**
* Twitch account configuration schema
*/
const TwitchAccountSchema = z.object({
/** Twitch username */
username: z.string(),
/** Twitch OAuth access token (requires chat:read and chat:write scopes) */
accessToken: z.string(),
/** Twitch client ID (from Twitch Developer Portal or twitchtokengenerator.com) */
clientId: z.string().optional(),
/** Channel name to join */
channel: z.string().min(1 ),
/** Enable this account */
enabled: z.boolean ().optional(),
/** Allowlist of Twitch user IDs who can interact with the bot (use IDs for safety, not usernames) */
allowFrom: z.array(z.string()).optional(),
/** Roles allowed to interact with the bot (e.g., ["moderator", "vip", "subscriber"]) */
allowedRoles: z.array(TwitchRoleSchema).optional(),
/** Require @mention to trigger bot responses */
requireMention: z.boolean ().optional(),
/** Outbound response prefix override for this channel/account. */
responsePrefix: z.string().optional(),
/** Twitch client secret (required for token refresh via RefreshingAuthProvider) */
clientSecret: z.string().optional(),
/** Refresh token (required for automatic token refresh) */
refreshToken: z.string().optional(),
/** Token expiry time in seconds (optional, for token refresh tracking) */
expiresIn: z.number().nullable().optional(),
/** Timestamp when token was obtained (optional, for token refresh tracking) */
obtainmentTimestamp: z.number().optional(),
});
/**
* Base configuration properties shared by both single and multi - account modes
*/
const TwitchConfigBaseSchema = z.object({
name: z.string().optional(),
enabled: z.boolean ().optional(),
markdown: MarkdownConfigSchema.optional(),
});
/**
* Simplified single - account configuration schema
*
* Use this for single - account setups . Properties are at the top level ,
* creating an implicit " default " account .
*/
const SimplifiedSchema = z.intersection(TwitchConfigBaseSchema, TwitchAccountSchema);
/**
* Multi - account configuration schema
*
* Use this for multi - account setups . Each key is an account ID ( e . g . , " default " , " secondary " ) .
*/
const MultiAccountSchema = z.intersection(
TwitchConfigBaseSchema,
z
.object({
/** Per-account configuration (for multi-account setups) */
accounts: z.record(z.string(), TwitchAccountSchema),
})
.refine((val) => Object.keys(val.accounts || {}).length > 0 , {
message: "accounts must contain at least one entry" ,
}),
);
/**
* Twitch plugin configuration schema
*
* Supports two mutually exclusive patterns :
* 1 . Simplified single - account : username , accessToken , clientId , channel at top level
* 2 . Multi - account : accounts object with named account configs
*
* The union ensures clear discrimination between the two modes .
*/
export const TwitchConfigSchema = z.union([SimplifiedSchema, MultiAccountSchema]);
Messung V0.5 in Prozent C=78 H=100 G=89
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-09-27)
¤
*© Formatika GbR, Deutschland