Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 2x 2x 2x 2x 2x 2x 3x | import { resolveTwitchOperatorEnv } from "@workspace/env/twitch"
import { createLogger, serializeLogError } from "@workspace/logger"
import { TwitchApiService } from "../services/TwitchApiService"
import { authorizeBot } from "../auth/authorization"
import { GrantStore } from "../auth/grantStore"
export async function main(): Promise<void> {
const logger = createLogger("twitch-bot-authorization")
try {
const config = resolveTwitchOperatorEnv()
if (!process.stdout.isTTY)
throw new Error(
"Bot authorization requires an interactive operator terminal."
)
await authorizeBot(config, {
api: new TwitchApiService(config),
store: new GrantStore(config.TWITCH_BOT_GRANT_PATH),
showUrl: (url) => {
process.stdout.write(
`Open this URL while signed in as the dedicated Cleo bot:\n${url}\n`
)
},
})
logger.info(
"Verified bot grant saved privately. Transfer it through your secure operator channel; tokens are not printed."
)
} catch (error) {
logger.error(
"Bot authorization failed. Check the expected account, scopes, redirect URI and private output directory. Existing grants are never overwritten.",
{ error: serializeLogError(error) }
)
process.exitCode = 1
}
}
|