Skip to content

About

Discord Bot of TarkovTracker.org Discord server.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

TarkovTracker logo

TrackerBot

The Discord companion for the TarkovTracker.org community: slash commands, reaction roles, welcome automation, ticket creation, and a public bug-intake portal that forwards reports straight to GitHub.

License: MIT Node.js discord.js PRs Welcome

Overview

TrackerBot runs two services side by side:

Service Entry point Responsibility
Discord bot bot.js Slash commands, reaction roles, welcome automation, and ticket creation.
Bug intake web server webserver.js Serves the public issue forms and forwards submissions to GitHub.

Reporting limits and errors

Both report forms currently create issues in REPO_DEV, configured as tarkovtracker-org/TarkovTracker. The data overlay repository is private, so REPO_DATA_REPORT is no longer required and any existing value is ignored. Data reports retain their category-prefixed title, category, reference and details. Both forms link to the public TarkovTracker issue list for delivery checks and explicitly warn that Discord handles, reference links and report details are public.

POST /data and POST /issue share one reporting policy for each client IP (with the existing IPv6 /56 grouping). The allowance is 20 delivered reports in a rolling 12 hours, with at least 10 minutes between deliveries. A delivery exactly 12 hours old leaves the allowance; a new report is admitted exactly at the 10-minute boundary. IPv4-mapped addresses use the same key as IPv4, including dotted and hexadecimal IPv6 representations. Switching forms does not reset either limit. Users sharing an IP or IPv6 prefix share these limits.

The server reserves a slot before awaiting GitHub, so concurrent requests cannot both pass. Confirmed GitHub issue creation (201) consumes the allowance and starts the cooldown at delivery completion. Validation, origin/parser errors, honeypot submissions and proven delivery rejections do not count as delivered reports. A separate shared five-attempt rolling minute budget runs before body parsing and includes rejected/invalid requests. Denials return the longest active attempt/window/cooldown wait rather than an earlier partial reset.

Timeouts, connection resets, unexpected provider responses and GitHub 5xx responses are unconfirmed delivery, not proof that no issue was created. They conservatively reserve allowance and cooldown. A hash of the same report is held against automatic repetition for 12 hours, bounded by the same retention window; this is not a durable idempotency guarantee. Check the published issue list or contact support before repeating it. Different reports may be sent after the ordinary cooldown if allowance remains. No automatic GitHub retry occurs.

Both forms preserve their entered fields on failure, disable double submission, and display safe typed server errors. Unknown network/proxy/success responses keep the draft and stop automatic repetition in that page. The displayed wait is advisory; every new request is checked by the server. Length limits are visible and enforced without silently truncating evidence: title 200, Discord handle 64, category 64, reference 500, details 8,000 characters; request bodies are capped at 32 KiB. Successful submission resets the form. Drafts remain in the open page, not persistent browser storage; copy them before reloading.

Errors use { error: { code, message }, retryAfterSeconds?, resetAt? }. Admission errors use HTTP 429 (report_cooldown, report_window_limit, attempt_limit, report_in_progress), capacity uses 503, and uncertain repeat delivery uses 409. Wait errors include numeric Retry-After seconds and an ISO resetAt. Validation/parser/origin errors use 400/413/415/403. Proven provider rejections/connectivity failures use 502/503; unconfirmed delivery uses 504. Provider throttling honors full Retry-After and exhausted-primary x-ratelimit-reset waits, taking the longer when both apply. A shared process-local provider hold prevents every client on both routes, including staged uploads, from calling GitHub again before that reset. Local denials include any longer provider wait, while known uncertain-report denials keep their check-before-repeating warning. Secondary throttles without timing headers use GitHub's minimum one-minute guidance. Neither server nor browser truncates a valid provider wait. Known client parser failures, including parameter overflow, excessive nesting and unsupported formats, return retryable typed 4xx errors; they are not uncertain GitHub delivery. See GitHub rate limits and body-parser errors. Provider bodies, tokens, IPs and report descriptions are never included in error output or delivery logs.

Rollout limitation: these controls are process-local memory, not durable or shared across workers/hosts. A restart clears allowances, cooldowns, uncertain-report holds and the shared provider throttle. There is no existing persistent limiter store or hosting manifest in this repository. State is capped at 10,000 clients and stale entries are removed; at capacity, expiry cleanup runs at most once per second. New clients receive a safe busy response when the remaining entries still hold active limits; active attempt budgets are not evicted to make room. Otherwise rotating keys could bypass the five-attempt allowance. Sustained traffic from 10,000 distinct active client keys can still exhaust this bounded table; operator-side abuse protection and the trusted-proxy boundary remain necessary. Strict enforcement across restarts or multiple processes needs an operator-approved persistent/shared store after hosting is established. This change adds no infrastructure or production settings and is not evidence that the deployed topology is ready for strict enforcement.

trust proxy = 1 remains unchanged. Before rollout, operators must verify that the origin is reachable only through the intended trusted proxy and that it overwrites client forwarding headers, and confirm the actual process topology. Otherwise clients may spoof the limiter key or unrelated users may share one. Do not fix that by trusting arbitrary forwarded headers. The deployed form origin must also match the existing ALLOWED_ORIGINS setting. Credential, proxy-trust and production configuration changes require separate approval.

Requires Node.js 18.17+.

Features

  • Ticket creation flow with private support channels
  • Reaction-role assignment and a put-member-role bulk role command
  • Automated welcome messages and auto-roles for new members
  • Quick announcement helpers (/message, /faq1, /utd)
  • One-command channel archiving (/archive)
  • Honeypot anti-spam channel that auto-bans anyone who posts in it
  • Public web forms that open GitHub issues for bug and data reports

Getting started

1. Install dependencies

npm ci
npm run build

This project has no bundle or generated build output. npm run build syntax-checks all JavaScript files without starting either service. CI runs the same command, the tests, and npm run audit:prod; production dependency advisories fail CI.

2. Configure environment variables

Copy .env.example to .env and fill in every value:

  • Discord bot basics: DISCORD_TOKEN, ADMIN_ROLE_ID (comma-separated Discord role IDs granting admin-only commands such as /wipe)
  • GitHub issue routing: GITHUB_TOKEN, REPO_DEV=tarkovtracker-org/TarkovTracker for both forms. Legacy REPO_DATA_REPORT is ignored.
  • Channel IDs for automated posts: WELCOME_CHANNEL_ID; optional HONEYPOT_CHANNEL_ID (a hidden channel — anyone who posts in it is banned on sight, with a kick fallback; messages older than 16h are swept hourly)
  • Role IDs: PANEL_ADMIN_ROLE_ID, AUTO_ROLE_ID_1–AUTO_ROLE_ID_4 (auto-roles for new members); optional ALLOWED_COMMAND_ROLE_IDS (comma-separated role IDs allowed to use member commands, falls back to a built-in default)
  • Web server: PORT, ALLOWED_ORIGINS (comma-separated origins, exact match)

The deployed GITHUB_TOKEN needs issue-write access to tarkovtracker-org/TarkovTracker. Prefer a fine-grained PAT with Issues: write on that repository only. Redirecting data reports removes the private-overlay dependency, but does not grant permissions to a token that cannot create website issues.

Production rollout checklist

  • Use npm ci, npm run build, and npm start in the hosting configuration. npm start launches one bot and one web process per invocation; its launcher is a runtime dependency, so npm ci --omit=dev is also supported. Verify the actual replica count and deployment overlap rather than inferring it from the command.
  • Set REPO_DEV=tarkovtracker-org/TarkovTracker. Verify the deployed token's issue-write access without sharing credentials. Both report routes use that destination.
  • Correct the operator's origin-list typos (https// is not https://). A valid list for the reported domains is: https://tarkovtracker.org,https://www.tarkovtracker.org,https://trackerbot.nivmizz7.dev,https://www.trackerbot.nivmizz7.dev. A preview hostname must be added separately if its forms are tested. Do not disable origin checking just to make a preview pass.
  • Verify that Node is not directly Internet-accessible, that the trusted proxy overwrites forwarding headers, and that distinct visitors retain distinct limiter keys. Leave trust proxy = 1 unchanged until the real proxy path is established.
  • Confirm a single serving web process, including during deployments, and explicitly accept that restarts clear limits, uncertain-delivery holds and provider throttles. If strict limits across replicas or restarts are required, approve a shared/persistent store before rollout.
  • A successful /health response only proves the HTTP process is running, not GitHub delivery or correct proxy isolation. Coolify configuration and production credentials cannot be verified from repository tests.

3. Run the services locally

Start everything at once:

npm start

This launches the bot and issue intake web server in parallel. Logs for each service are prefixed with bot or web.

Or run a single service:

npm run start:bot   # Discord bot
npm run start:web   # Public issue forms (http://localhost:3000)
  • Bot login success is logged as soon as Discord authenticates the token.
  • webserver.js serves http://localhost:3000 (issue portal), plus http://localhost:3000/issue and http://localhost:3000/data (forms).

Slash commands

Command Description
/message Send a message as the bot (Discord Admin only).
/faq1 Post the FAQ notice about site stability.
/utd Post the update-in-progress notice.
/archive Archive the current channel and move it to the Archive category.
/put-member-role Add the member auto-role to everyone missing it (Admin only).
/wipe Confirmed bulk-delete of recent messages in the current channel (Admin only, 14-day Discord API limit).
/nuke Clone the current channel with all permissions/settings and delete the old one (Admin only, confirm with warning).

Project structure

trackerbot/
├── bot.js              # Discord bot entry point
├── webserver.js        # Public bug/data intake server
├── src/
│   ├── client/         # Discord client setup
│   ├── commands/       # Slash command registration
│   ├── config/         # Env validation and constants
│   ├── handlers/       # Interaction and member event handlers
│   ├── interactions/   # Slash and button handlers
│   └── utils/          # Shared helpers (e.g. card embeds)
└── web/                # Static issue/data report forms

Contributing

Issues and pull requests are welcome. Please open an issue to discuss substantial changes before submitting a PR.

License

Released under the MIT License.

About

Discord Bot of TarkovTracker.org Discord server.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages