thread-catch
v1.1.2
Published
A plug-and-play bug-report widget that creates tagged Discord Forum posts.
Downloads
36
Maintainers
Readme
ThreadCatch
Send web app bug reports to a Discord Forum channel.
Discord bot token is never shown in the browser.
Quick start
Install the package, then run the one setup command from your Next.js project:
npm install thread-catch
npx thread-catch init --token "$DISCORD_BOT_TOKEN"init discovers the Discord server your bot belongs to, creates or reuses a bug-reports Forum channel, adds Open, Low, Medium, High, and Critical tags, writes .env.local, and creates app/api/bug-report/route.ts. No Discord IDs are copied by hand. If the bot belongs to more than one server, the CLI asks you to choose one.
Add the widget once in a Client Component:
"use client";
import { BugReportWidget } from "thread-catch";
export function AppShell() {
return <BugReportWidget />;
}Your bot must already be installed in the target server with:
- Manage Channels
- Create Public Threads
- Send Messages
- Manage Threads
- Read Message History (needed to scan archived posts for the next report number)
The CLI only needs the bot token; it uses Discord's Gateway to discover the server rather than asking for a guild ID.
Options
npx thread-catch init --token "$DISCORD_BOT_TOKEN" --forum customer-bugs --route /api/report-bugUse --dir path/to/next-app when invoked outside the Next.js project. --guild <id> is available for unattended multi-server installs.
The widget defaults to POST /api/bug-report; override it with <BugReportWidget endpoint="/api/report-bug" />.
Security model
- The public package entry exports only the client widget. Discord REST code is an unexported internal module.
- The Next.js entry is
thread-catch/next, importsserver-only, and fails Next builds when imported from a Client Component. - The generated route reads the bot token only from
process.env.DISCORD_BOT_TOKEN. The widget has no token prop. .env.localis added to.gitignore; the CLI does not print the token.- The server validates input, disables Discord mentions, limits report bodies, and has a conservative in-memory per-IP rate limit (5 reports per 10 minutes by default).
- Every forum post is numbered from the largest existing number in the forum (
#0001 - Crash on login,#9999 - …,#10000 - …), so each bug keeps a stable reference for tracking. Numbers are read from the start, end, or middle of existing post names, across active and archived posts. - Reports are screened against an explicit-content wordlist before they reach Discord; extra terms can be added with
extraBlockedTermson the handler. The filter is a heuristic, not a substitute for moderating the channel.
The in-memory limit is intentionally dependency-free. For multi-instance deployments, place a platform rate limiter in front of the generated route.
Framework-agnostic handler
For another server framework, use the standards-based handler from the server-only export:
import { createDiscordBugReportHandler } from "thread-catch/server";
const report = createDiscordBugReportHandler({
token: process.env.DISCORD_BOT_TOKEN!,
forumChannelId: process.env.DISCORD_BUG_REPORT_FORUM_ID!,
tags: process.env.DISCORD_BUG_REPORT_TAGS
});
// Adapt `report(request)` to your framework's Request/Response bridge.Do not import thread-catch/server from browser code.
