Skip to content

Rebuild bot on raw Discord API with quotas and resilience#5

Draft
SyntaxGhost404 wants to merge 13 commits into
experimentalfrom
agent/raw-discord-rebuild
Draft

Rebuild bot on raw Discord API with quotas and resilience#5
SyntaxGhost404 wants to merge 13 commits into
experimentalfrom
agent/raw-discord-rebuild

Conversation

@SyntaxGhost404

@SyntaxGhost404 SyntaxGhost404 commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • rebuild the bot around raw Discord HTTP API v10 and Gateway v10 without discord.js or another high-level client
  • preserve all 36 legacy NSFW command/provider mappings and add /cosplay plus /premium [user], bringing the public registry to 41 commands plus one hidden component handler
  • automatically refresh application commands before connecting the Gateway
  • keep the byte-for-byte legacy source archive while making llms-full.txt a local-only, Git-ignored reference
  • retain Chalk terminal styling and requester-only media footers
  • centralize every command, UI, custom Discord, navigation, and terminal emoji in src/config/emojis.js

Global quotas and Premium

  • coordinate quotas by Discord user ID across DMs, group DMs, and every guild
  • apply a two-second utility cooldown to Free users and no utility cooldown to Premium users
  • enforce 60 successful media displays per rolling minute and 1,000 per UTC day for Free users
  • remove the Premium minute ceiling while enforcing the authoritative 5,000-per-day cap
  • reserve media capacity before provider work and commit only after Discord accepts the displayed media
  • atomically persist successful quota state under the ignored .runtime/ directory
  • render Dank Memer-style cooldown embeds and expose current quotas under Usage Limits
  • pair Subscribe/Manage with an emoji-only refresh control that edits the existing Premium message

Provider and Discord resilience

  • open provider-specific circuits after consecutive failures for 30–120 seconds and permit one real half-open recovery probe
  • never race, prefetch, or issue speculative redundant provider requests
  • keep provider timeouts active through body consumption and make DNS, Fetch, direct HTTPS, and shutdown cancellation coordinated
  • use at-most-once delivery for Discord POSTs after ambiguous failures while still honoring explicit 429 rejections
  • fingerprint interaction/webhook tokens in routing keys and redact sensitive routes and values from pretty, JSON, live-supervisor, and persisted logs
  • coordinate learned Discord bucket hashes across routes and major resources

Cosplay feed command

  • add the age-restricted /cosplay command with the established Refresh and direct Link controls
  • always try Hentai-cosplay-xxx.com first and contact Ahottie only after a real primary failure
  • dynamically read each feed's pagination ceiling, use fresh cryptographic page/item selection on every command and Refresh, and de-duplicate cleaned candidates
  • extract media directly from feed/index HTML without opening gallery or album pages
  • strip Hentai-cosplay compression path wrappers and promote Imgbox thumbnails to direct originals
  • bound HTML and media bodies, enforce exact HTTPS host policy, reject anti-bot HTML and insecure redirects, and re-upload verified image bytes for reliable Discord rendering
  • avoid browsers, background crawling, prefetching, speculative requests, and new runtime dependencies

Buttplug Anime/Real sources

  • add the established optional style choice to /buttplug: Anime uses only ABD Osaka, while Real uses only PornPics
  • preserve the same unselected-style flattened shuffle and fallback behavior used by /ass and /anal
  • discover PornPics' current P_MAX * 10 item range and select a fresh cryptographic offset on every command and Refresh
  • reuse main-feed gallery covers for offsets below 20; otherwise read only the first item from the exact ?offset={offset} JSON response
  • never open g_url or individual galleries, and never issue speculative, background, or parallel media requests
  • accept only exact HTTPS cdni.pornpics.com image URLs and promote /300/ or /460/ covers to /1280/
  • download the selected /1280/ cover into bounded memory, retry that exact URL once only after a genuine network transport failure, require a supported image MIME type, and re-upload it as a native Discord attachment
  • retain the validated raw /1280/ URL in the Link button, reject HTTP 200 HTML block pages and unsafe redirects, and avoid proxying or WAF/TLS circumvention

ABD Osaka-only routing

  • read only the ABD response's url_japan field and intentionally ignore every other mirror field
  • make exactly one bounded media download to the exact n-sfw.ap-osaka-1.s3.ink hostname, with no mirror iteration or fallback loop
  • enforce HTTPS, standard port 443, an exact host allowlist, a five-second timeout ceiling, attachment byte limits, and shutdown cancellation
  • tolerate only CERT_HAS_EXPIRED after a separate certificate hostname check; reject self-signed, untrusted-chain, hostname-mismatch, plaintext, substituted-host, redirect, and all other TLS failures
  • re-upload successful ABD bytes as native Discord attachments so embeds never depend on upstream certificate validity
  • expose the validated url_japan value through ABD's Link button while keeping the embed itself attachment-backed
  • render Refresh and Link on every successful NSFW response, falling back from an invalid or absent provider watch URL to the validated media URL

Cross-host runtime hardening

  • prefer collision-safe DISCORD_BOT_TOKEN and DISCORD_CLIENT_ID server-side secrets while preserving the legacy Replit aliases
  • make Discord-specific names win when generic host variables such as Google OAuth CLIENT_ID also exist
  • fail fast with an actionable message when a placeholder or OAuth client ID is supplied instead of a Discord snowflake
  • preserve nested network causes such as ECONNRESET in provider diagnostics
  • document Google AI Studio Build mode restarts, HTML preview fallbacks, Cloud Run singleton constraints, and the existing Replit workflow
  • retry only the already-selected PornPics media URL after a network reset; never repeat feed discovery, random selection, or blocked/non-image responses

Interaction ownership fix

  • diagnose the supplied sub-second 10062 / 40060 pattern as two live Gateway consumers using the same BOT_TOKEN, not a slow command or provider
  • acquire an atomic, owner-only process lease before registration or Gateway startup
  • heartbeat the lease, validate same-host owners by PID, and reclaim stale leases from replaced containers
  • classify callback failures using responder state, local callback time, and Discord snowflake age
  • treat initial 40060 as definitive competing-consumer evidence; two fresh sub-2.5-second 10062 failures confirm the same condition
  • make the losing process reject new work and enter the existing graceful shutdown path, including Gateway close, quota flush, and lease release
  • keep genuine three-second deadline misses distinct and remove exception-stack spam for known terminal interaction outcomes

Persistent Replit logs

  • make npm start supervise index.js and mirror both stdout and stderr to the colorized terminal
  • append a plain-text, ANSI-free, token-redacted history to logs/discord-bot-console.txt from before bot startup
  • retain run boundaries across restarts instead of rotating away old console history
  • add npm run logs:export for owner-only timestamped snapshots under logs/exports/
  • keep npm run start:direct as an explicit diagnostic path that bypasses capture

Graceful lifecycle

  • reject new work once shutdown begins
  • drain active interactions, cancel remaining provider I/O, and give Discord responses a separate settle window
  • abort REST waits/retries, close Gateway with a bounded graceful close, and force-terminate on timeout
  • flush quotas and release the instance lease before exit
  • use the same idempotent lifecycle for signals, fatal Gateway state, uncaught errors, unhandled rejections, and confirmed duplicate consumers

Verification

  • npm run validate — passed
  • NODE_OPTIONS=--unhandled-rejections=strict npm test — 137/137 tests passed
  • npm audit --omit=dev — 0 vulnerabilities
  • complete archived-command/provider parity suite — passed
  • static text/binary, syntax, wrapper-dependency, and hardcoded-emoji scans — passed
  • Replit stdout/stderr persistence, ANSI stripping, token redaction, and snapshot export tests — passed
  • local and remote validated tree SHA: ae8589bec17bd5e3540d941337a75088df1e8720
  • PornPics attachment behavior is covered by deterministic image, Refresh, invalid-redirect, and HTTP 200 HTML block-page tests; a live diagnostic from this host received the documented upstream text/html datacenter block rather than image bytes

Deployment notes

  • keep exactly one Replit Run, Google AI Studio/Cloud Run instance, or other Deployment active for a given Discord bot token; isolated filesystems cannot share a local lease
  • use DISCORD_BOT_TOKEN and DISCORD_CLIENT_ID in Google AI Studio Settings → Secrets; the legacy Replit aliases remain supported
  • ABD no longer needs ALLOW_INSECURE_MEDIA_TLS; the generic bypass was removed, while the upstream operator should still renew the Osaka certificate
  • the new conflict monitor makes a losing isolated instance yield, but old deployments should still be stopped; rotate the bot token if an unknown consumer cannot be found
  • configure Premium membership with the comma-separated PREMIUM_USER_IDS allowlist until payment integration exists
  • keep RATE_LIMIT_STATE_FILE on durable storage if daily quotas must survive deployment replacement
  • the Subscribe/Manage placeholder intentionally points to https://chatgpt.com
  • live Gateway registration was not exercised because production credentials are unavailable; both cosplay feeds, historical pagination, and sample raw media URLs were verified against their current public layouts on July 11, 2026

@SyntaxGhost404 SyntaxGhost404 changed the title Rebuild bot on raw Discord API Rebuild bot on raw Discord API with quotas and resilience Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant