export const TWITCH_MINIMAL_STREAM_SCOPES = [
'user:read:email',
'user:read:broadcast',
'channel:manage:broadcast',
'chat:read',
'chat:edit',
'user:write:chat',
'moderator:read:chatters',
'channel:moderate',
'moderation:read',
]
export const TWITCH_DEFAULT_SCOPES = [
'analytics:read:extensions',
'analytics:read:games',
'bits:read',
'channel:bot',
'channel:manage:ads',
'channel:read:ads',
'channel:manage:broadcast',
'channel:read:charity',
'channel:manage:clips',
'channel:edit:commercial',
'channel:read:editors',
'channel:manage:extensions',
'channel:read:goals',
'channel:read:guest_star',
'channel:manage:guest_star',
'channel:read:hype_train',
'channel:manage:moderators',
'channel:read:polls',
'channel:manage:polls',
'channel:read:predictions',
'channel:manage:predictions',
'channel:manage:raids',
'channel:read:redemptions',
'channel:manage:redemptions',
'channel:manage:schedule',
'channel:read:stream_key',
'channel:read:subscriptions',
'channel:manage:videos',
'channel:read:vips',
'channel:manage:vips',
'channel:moderate',
'chat:edit',
'chat:read',
'clips:edit',
'editor:manage:clips',
'moderation:read',
'moderator:manage:announcements',
'moderator:manage:automod',
'moderator:read:automod_settings',
'moderator:manage:automod_settings',
'moderator:read:banned_users',
'moderator:manage:banned_users',
'moderator:read:blocked_terms',
'moderator:manage:blocked_terms',
'moderator:read:chat_messages',
'moderator:manage:chat_messages',
'moderator:read:chat_settings',
'moderator:manage:chat_settings',
'moderator:read:chatters',
'moderator:read:followers',
'moderator:read:guest_star',
'moderator:manage:guest_star',
'moderator:read:moderators',
'moderator:read:shield_mode',
'moderator:manage:shield_mode',
'moderator:read:shoutouts',
'moderator:manage:shoutouts',
'moderator:read:suspicious_users',
'moderator:manage:suspicious_users',
'moderator:read:unban_requests',
'moderator:manage:unban_requests',
'moderator:read:vips',
'moderator:read:warnings',
'moderator:manage:warnings',
'user:bot',
'user:edit',
'user:edit:broadcast',
'user:read:blocked_users',
'user:manage:blocked_users',
'user:read:broadcast',
'user:read:chat',
'user:manage:chat_color',
'user:read:email',
'user:read:emotes',
'user:read:follows',
'user:read:moderated_channels',
'user:read:subscriptions',
'user:read:whispers',
'user:manage:whispers',
'user:write:chat',
'whispers:read',
]
/**
* Describe default and minimal Twitch OAuth scope sets for connect flows.
*
* @returns `{ default, minimalStream, notes }` describing recommended OAuth scopes.
*
* @example
* import describeTwitchScopes from 'kody:@kentcdodds/twitch/scopes'
* const scopes = describeTwitchScopes()
* // => { default: [...], minimalStream: [...], notes: [...] }
*/
export function formatTwitchScopes(scopes: string[] = TWITCH_DEFAULT_SCOPES): string {
return [...scopes].join(' ')
}
export type TwitchScopesInfo = {
default: string[]
minimalStream: string[]
notes: string[]
}
/**
* Describe default and minimal Twitch OAuth scope sets for connect flows.
*
* @returns `{ default, minimalStream, notes }` describing recommended OAuth scopes.
*
* @example
* import describeTwitchScopes from 'kody:@kentcdodds/twitch/scopes'
* const scopes = describeTwitchScopes()
* // => { default: [...], minimalStream: [...], notes: [...] }
*/
export default function describeTwitchScopes(): TwitchScopesInfo {
return {
default: TWITCH_DEFAULT_SCOPES,
minimalStream: TWITCH_MINIMAL_STREAM_SCOPES,
notes: [
'The package originally shipped with TWITCH_MINIMAL_STREAM_SCOPES: just enough for get-stream, send-chat-message, update-channel-info, and list-chatters.',
'TWITCH_DEFAULT_SCOPES is now the connect default so Kody can grow into polls, predictions, raids, redemptions, moderation, whispers, analytics, and EventSub without forcing a reconnect.',
"Twitch asks apps not to request unused scopes; this broad set is intentional for Kent's personal broadcaster account where max capability is preferred over least privilege.",
'If Twitch rejects or warns about scope breadth, fall back to TWITCH_MINIMAL_STREAM_SCOPES or a custom subset via getConnectUrl({ scopes }).',
],
}
}