diff --git a/CURRENT.md b/CURRENT.md index dbc062e..a254e58 100644 --- a/CURRENT.md +++ b/CURRENT.md @@ -33,7 +33,9 @@ mobile draft at 390px. - [x] C7a storage limits, retention, warning/confirm flow, storage and clean API - [x] C7b Settings group: limit field with info hover, usage bar, clean modal - [ ] C8 MCP service hooks - - [ ] C9 live verification, tuning, docs + - [~] C9 live verification: slopbot login works (Slopbot#5775), but the bot is in 0 guilds, so + the test channel fetch fails with Missing Access. Waiting on the owner to invite the bot to + guild `177931418704281600`. Live check: `pnpm test:slopbot:live`. - Flextalk voice profile, end to end. The profile window is a movable panel that recenters on each open; it carries the character sliders with engine defaults and +/-2 snapping, five named presets, radio-kit effects (high-pass 40-400 Hz, echo 0-100, word mode with a gap in ms), and @@ -300,6 +302,9 @@ mobile draft at 390px. ## Blocked / needs input +- Slopbot live test needs the bot invited to the test guild with View Channels + Read Message + History: . + The token lives at `/tmp/opencode/slopbot.json` (mode 600, outside the repo) for this session. - The original repo `zib/Veskslop` has a broken server-side git setup. Fetches and clones fail with `bad pack header` because a script (`/home/git/.sys_health_s3`) runs on the Veskslop read path. The admin must fix it. Use `zib/Veskslop-t` (remote `veskslop-t`) until then. That remote has no diff --git a/docs/slopbot.md b/docs/slopbot.md index 73a2806..e05b073 100644 --- a/docs/slopbot.md +++ b/docs/slopbot.md @@ -60,6 +60,18 @@ channels. - The Bot tab shows connection state, the guilds slopbot is in, the active scrape, and the queue. It also renders the invite URL from the client ID. +## Live check + +```sh +cd poc +VESKSLOP_SLOPBOT_ENABLED=1 VESKSLOP_SLOPBOT_STATE=/path/to/slopbot.json \ + pnpm test:slopbot:live [guildId] +``` + +The check logs in, prints the bot user and guild count, then fetches one history page and maps it. +The token is read from the state file or the environment and is never printed. The bot must be +invited to the guild first (View Channels + Read Message History). + ## Rate limits discord.js handles per-route buckets and retries `429` and `5xx` internally. The scrape engine adds diff --git a/docs/testing.md b/docs/testing.md index aac6605..28e767e 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -177,6 +177,17 @@ Notes: locally and point `LD_LIBRARY_PATH` at it. - The live start was verified on 2026-09-13 through the web UI route. +## Slopbot live check + +The bot core needs a real token and an invite to the test guild. The check logs in, lists guilds, +and fetches one history page without printing the token: + +```sh +cd poc +VESKSLOP_SLOPBOT_ENABLED=1 VESKSLOP_SLOPBOT_STATE=/path/to/slopbot.json \ + pnpm test:slopbot:live [guildId] +``` + ## Sanctioned live target The only permitted live-send target is user **zzib** (`177117296140091393`). Send a test message diff --git a/media-scrape/test/live-slopbot.ts b/media-scrape/test/live-slopbot.ts new file mode 100644 index 0000000..a1e8461 --- /dev/null +++ b/media-scrape/test/live-slopbot.ts @@ -0,0 +1,65 @@ +/* + * Live slopbot check: login, guild presence, and one history page. + * + * Usage (from poc/): + * VESKSLOP_SLOPBOT_ENABLED=1 VESKSLOP_SLOPBOT_STATE=/path/to/slopbot.json \ + * tsx ../media-scrape/test/live-slopbot.ts [guildId] + * + * Or set VESKSLOP_TEST_CHANNEL / VESKSLOP_TEST_GUILD. The token is read from the + * environment or the state file and is never printed. + */ + +import { extractMedia } from "../src/extract.js"; +import { + loadSlopbotConfig, + slopbotFetcher, + slopbotStatus, + SlopbotBackend, + startSlopbot, + stopSlopbot +} from "../slopbot/index.js"; + +async function main() { + const channelId = process.argv[2] ?? process.env.VESKSLOP_TEST_CHANNEL; + const guildId = process.argv[3] ?? process.env.VESKSLOP_TEST_GUILD; + + if (!channelId) { + console.error("usage: live-slopbot.ts [guildId]"); + process.exit(1); + } + + const config = loadSlopbotConfig(); + if (!config.enabled) { + console.error("slopbot disabled: set VESKSLOP_SLOPBOT_ENABLED=1 and a token"); + process.exit(1); + } + + const client = await startSlopbot(config); + try { + const status = slopbotStatus(client); + console.log(`logged in as ${status.user}`); + console.log(`guilds: ${status.guilds.length}`); + if (guildId) console.log(`target guild present: ${client.guilds.cache.has(guildId)}`); + + const backend = new SlopbotBackend(slopbotFetcher(client)); + const startedAt = Date.now(); + const page = await backend.fetchPage(channelId, null, 25); + console.log(`fetched ${page.messages.length} messages in ${Date.now() - startedAt} ms`); + + const withContent = page.messages.filter(message => message.content.length > 0).length; + const attachments = page.messages.reduce((sum, message) => sum + message.attachments.length, 0); + const media = page.messages.flatMap(message => extractMedia(message)); + const kinds = media.reduce>((acc, item) => { + acc[item.kind] = (acc[item.kind] ?? 0) + 1; + return acc; + }, {}); + + console.log(`content present: ${withContent}/${page.messages.length}`); + console.log(`attachments: ${attachments}`); + console.log(`media: ${JSON.stringify(kinds)}`); + } finally { + await stopSlopbot(client); + } +} + +void main(); diff --git a/poc/package.json b/poc/package.json index 2b4e132..3f92ab4 100644 --- a/poc/package.json +++ b/poc/package.json @@ -17,6 +17,7 @@ "test:cache": "tsx src/test-cache.ts", "test:audio": "tsx src/test-audio.ts", "test:media": "tsx ../media-scrape/test/run.ts && tsx ../media-scrape/test/slopbot.ts", + "test:slopbot:live": "tsx ../media-scrape/test/live-slopbot.ts", "audio:doctor": "bash scripts/audio-doctor.sh" }, "dependencies": {