← Back

Discord Stock Bot

A long-lived Node.js Discord bot that generates fundamentals-based 'Quality Snapshots' for stock tickers, responding with rich embeds or attached Markdown reports.

Node.jsTypeScriptdiscord.jsKubernetesHelmDockerGitHub Actions
Visit project
Discord Stock Bot screenshot

Highlights

  • Discord slash command interface with real market data via Finnhub and SEC EDGAR
  • Sector-aware scoring with configurable rules and 0–100 quality tiers
  • Multi-arch container images and Helm chart for Kubernetes deployment

A long-lived Node.js Discord bot that accepts /report <TICKER> slash commands and responds with rich Discord embeds or attached Markdown reports. It combines real market data from Finnhub and SEC EDGAR with sector-aware scoring to produce a fundamentals-based quality snapshot.

What it demonstrates

  • Discord slash command integration with deferred replies and concurrency limiting
  • Pluggable data adapters with deterministic mocks for development and demos
  • Sector-aware scoring with configurable rules and threshold buckets
  • Production-ready containerisation with multi-arch images and Helm deployment
  • CI/CD with secret scanning, dependency auditing, and automated image builds

Architecture overview

The service runs as a long-lived process combining a Discord client and a small HTTP health server. The entry point orchestrates bot lifecycle and graceful shutdown on SIGTERM/SIGINT.

  • Health server: /healthz (liveness) and /readyz (readiness when bot connected)
  • Discord bot: connects via discord.js, registers /report command, uses a semaphore for concurrency
  • Report pipeline: validates ticker, checks in-memory cache, fetches data, scores, and renders
  • Adapters: Finnhub for market data, SEC EDGAR for filing signals, with mock fallbacks
  • Renderers: EmbedBuilder for Discord replies, plain Markdown for CLI or attachments

Tech stack

  • Runtime: Node.js 20, TypeScript (ESM)
  • Bot: discord.js v14
  • Data: Finnhub API, SEC EDGAR, undici
  • Validation: Zod
  • Logging: Pino (JSON)
  • Testing: Vitest
  • Container: Docker (multi-stage, multi-arch via Buildx)
  • Orchestration: Kubernetes, Helm 3
  • CI/CD: GitHub Actions, GHCR
  • Security: Gitleaks, pnpm audit, Dependabot

Scoring and rendering

The scoring module applies metric rules with thresholds, weights, and sector-specific buckets to produce a 0–100 score and a tier (Excellent, Good, Fair, or Poor). Renderers then format the result as a Discord embed or plain Markdown.

Deployment

The Dockerfile uses a multi-stage build: a builder stage installs dependencies and compiles TypeScript, and a runtime stage copies the dist and node_modules, running as a non-root user. The Helm chart supports existingSecret for credentials and image.pullSecrets for private registries.

CI / CD

  • CI workflow: Gitleaks scan, lint, test, build, push multi-arch image to GHCR
  • Deploy workflow: creates secrets and runs helm upgrade
  • Security features: secret scanning on every build, pnpm audit, Dependabot

Why I built it

I wanted a practical way to surface stock fundamentals in a community Discord server. The project gave me an opportunity to build a production-grade bot with real data integrations, structured scoring, and a full CI/CD pipeline including multi-arch container builds and Helm-based deployment.