RepoPilotOpen in app →

Tyrrrz/DiscordChatExporter

Saves Discord chat logs to a file

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 6d ago
  • 6 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 64% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/tyrrrz/discordchatexporter)](https://repopilot.app/r/tyrrrz/discordchatexporter)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/tyrrrz/discordchatexporter on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: Tyrrrz/DiscordChatExporter

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Tyrrrz/DiscordChatExporter shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 6d ago
  • 6 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 64% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live Tyrrrz/DiscordChatExporter repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/Tyrrrz/DiscordChatExporter.

What it runs against: a local clone of Tyrrrz/DiscordChatExporter — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in Tyrrrz/DiscordChatExporter | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch prime exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 36 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>Tyrrrz/DiscordChatExporter</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Tyrrrz/DiscordChatExporter. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/Tyrrrz/DiscordChatExporter.git
#   cd DiscordChatExporter
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of Tyrrrz/DiscordChatExporter and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Tyrrrz/DiscordChatExporter(\\.git)?\\b" \\
  && ok "origin remote is Tyrrrz/DiscordChatExporter" \\
  || miss "origin remote is not Tyrrrz/DiscordChatExporter (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify prime >/dev/null 2>&1 \\
  && ok "default branch prime exists" \\
  || miss "default branch prime no longer exists"

# 4. Critical files exist
test -f "DiscordChatExporter.Cli/Program.cs" \\
  && ok "DiscordChatExporter.Cli/Program.cs" \\
  || miss "missing critical file: DiscordChatExporter.Cli/Program.cs"
test -f "DiscordChatExporter.Core/Discord/Data/Message.cs" \\
  && ok "DiscordChatExporter.Core/Discord/Data/Message.cs" \\
  || miss "missing critical file: DiscordChatExporter.Core/Discord/Data/Message.cs"
test -f "DiscordChatExporter.Core/Discord/Data/Channel.cs" \\
  && ok "DiscordChatExporter.Core/Discord/Data/Channel.cs" \\
  || miss "missing critical file: DiscordChatExporter.Core/Discord/Data/Channel.cs"
test -f "DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs" \\
  && ok "DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs" \\
  || miss "missing critical file: DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs"
test -f "DiscordChatExporter.Cli/Commands/Shared/ThreadInclusionMode.cs" \\
  && ok "DiscordChatExporter.Cli/Commands/Shared/ThreadInclusionMode.cs" \\
  || miss "missing critical file: DiscordChatExporter.Cli/Commands/Shared/ThreadInclusionMode.cs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 36 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~6d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Tyrrrz/DiscordChatExporter"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

DiscordChatExporter is a C# application that exports Discord channel message history to multiple formats (HTML, JSON, CSV, plaintext). It uses the Discord API to fetch messages from any channel (DMs, groups, or servers) the authenticated user has access to, preserving markdown formatting, embeds, attachments, reactions, and other rich media features. Monolithic C# project structure: DiscordChatExporter.Core handles message fetching and model serialization; DiscordChatExporter.Cli provides command-line interface with export wrapper logic; DiscordChatExporter.Cli.Tests contains 20+ spec test suites organized by format (HtmlContentSpecs, JsonContentSpecs, etc.) and feature (ForwardSpecs, MentionSpecs, StickerSpecs). Docker containerization available via Dockerfile.

👥Who it's for

Discord server administrators and archivists who need to preserve chat logs; researchers analyzing Discord communities; compliance teams exporting conversation records; users wanting portable backups of conversations with markdown/media support.

🌱Maturity & risk

Production-ready and actively maintained. The project shows comprehensive test coverage with 50+ spec files in DiscordChatExporter.Cli.Tests/, active GitHub Actions CI/CD pipeline (main.yml, docker.yml), and maintenance-status badge indicating ongoing support. The codebase is mature with 900k+ lines of C# and Docker support.

Low risk for typical usage, but single-maintainer project (Tyrrrz). Primary risk is Discord API contract changes—if Discord's API changes significantly, exports may break. The project is in maintenance mode (not active feature development), so response time to breaking changes may vary. Dependency updates are automated via Dependabot, which mitigates supply-chain risk.

Active areas of work

Project is in maintenance mode with ongoing dependency updates via Dependabot (visible in .github/dependabot.yml). Recent activity focuses on test coverage expansion—note the extensive test suite in DiscordChatExporter.Cli.Tests covering edge cases like forwarded messages, embeds, stickers, and markdown rendering. Docker workflow is active for release distribution.

🚀Get running

Clone the repository: git clone https://github.com/Tyrrrz/DiscordChatExporter.git && cd DiscordChatExporter. Build with .NET: dotnet build. The project uses Directory.Build.props and Directory.Packages.props for centralized dependency management. Run tests: dotnet test DiscordChatExporter.Cli.Tests.

Daily commands: For CLI: dotnet run --project DiscordChatExporter.Cli -- [options] (see docs/Using-the-CLI.md for full options). For GUI (if available): build and run the WPF/GUI project. For Docker: docker pull tyrrrz/discordchatexporter and see .docs/Docker.md. Tests: dotnet test.

🗺️Map of the codebase

  • DiscordChatExporter.Cli/Program.cs — Entry point for CLI application; orchestrates command routing and dependency setup for all export operations.
  • DiscordChatExporter.Core/Discord/Data/Message.cs — Core data model representing Discord messages; all message processing, filtering, and export logic depends on this structure.
  • DiscordChatExporter.Core/Discord/Data/Channel.cs — Core data model for Discord channels; essential for channel identification, metadata, and export targeting.
  • DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs — Abstract base class for all export commands; defines shared logic for authentication, channel resolution, and export execution.
  • DiscordChatExporter.Cli/Commands/Shared/ThreadInclusionMode.cs — Shared enum controlling thread export behavior; critical for message filtering and export scope decisions across all commands.
  • DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs — Data model for Discord embeds with multiple projection types; complex nested structure affecting formatting and content export.
  • Directory.Build.props — Central NuGet package and build configuration; manages versions and dependencies across all projects.

🛠️How to make changes

Add a new export format (e.g., XML, Markdown)

  1. Create a new formatter class implementing IMessageExportFormat in DiscordChatExporter.Core/Exporting (DiscordChatExporter.Core/Exporting/ExportFormat.cs)
  2. Implement message rendering logic, handling embeds, attachments, mentions, and markdown (DiscordChatExporter.Core/Exporting/Formatters/YourFormatFormatter.cs)
  3. Register the new format in the ExportService or ExportCommandBase format selection logic (DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs)
  4. Add integration tests validating output for content, embeds, attachments, and special formatting (DiscordChatExporter.Cli.Tests/Specs/YourFormatContentSpecs.cs)

Add a new CLI command (e.g., export by date, bulk export)

  1. Create a new command class inheriting from ExportCommandBase with command name and option definitions (DiscordChatExporter.Cli/Commands/YourNewCommand.cs)
  2. Override ExecuteAsync to implement custom export logic (channel resolution, filtering, iteration) (DiscordChatExporter.Cli/Commands/YourNewCommand.cs)
  3. Register the command in Program.cs using the CliFx command router (DiscordChatExporter.Cli/Program.cs)
  4. Add unit/integration tests for your command's channel selection and filtering behavior (DiscordChatExporter.Cli.Tests/Specs/YourCommandSpecs.cs)

Extend message filtering capabilities

  1. Add new filter parameters to ExportCommandBase (e.g., minLength, maxLength, containsLink) (DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs)
  2. Create or update filter logic in ExportService to apply the new criteria before formatting (DiscordChatExporter.Core/Exporting/ExportService.cs)
  3. Add test specs validating filter correctness with various message types and edge cases (DiscordChatExporter.Cli.Tests/Specs/FilterSpecs.cs)

🔧Why these technologies

  • C# / .NET — Cross-platform CLI and desktop compatibility; strong type safety for Discord API serialization; mature async/await patterns for HTTP concurrency.
  • CliFx — Lightweight, declarative CLI framework; automatic command routing, help generation, and input validation without heavy dependencies.
  • Discord.Net (inferred API client) — Community-standard .NET Discord API wrapper; handles authentication, rate limiting, and object deserialization from REST endpoints.
  • HTML/JSON/CSV/PlainText exporters — Multiple output formats support different use cases: HTML for readability, JSON for tooling, CSV for spreadsheets, PlainText for archival.
  • xUnit + integration tests — Test live exports against real Discord test channels; validate output format correctness and message filtering logic end-to-end.

⚖️Trade-offs already made

  • Live integration tests requiring real Discord test channels

    • Why: Validates actual API behavior and output format correctness; catches Discord API changes early.
    • Consequence: Tests are slower, require valid Discord token, and depend on external Discord infrastructure; cannot run in isolated CI without secrets.
  • Paginated message fetching with rate limiting

    • Why: Discord API enforces strict rate limits; pagination avoids timeouts and respects platform constraints.
    • Consequence: Large exports take longer; users see slower export times for high-volume channels; requires progress feedback.
  • Thread inclusion as opt-in mode (AllThreads/ActiveThreads/None)

    • Why: Threads are hierarchical; including
    • Consequence: undefined

🪤Traps & gotchas

Discord API authentication requires valid user/bot token (see docs/Token-and-IDs.md for setup); tests access real Discord servers via ChannelIds.cs (requires test environment configuration in Secrets.cs). Export partitioning by file size requires understanding message order—see PartitioningSpecs.cs. HTML exports embed CSS inline and may require JavaScript context for full rendering. The project targets .NET with platform-specific scheduling docs (Windows/macOS/Linux) in .docs/—deployment differs by OS.

🏗️Architecture

💡Concepts to learn

  • Discord API Message Pagination — Exporting large channels requires fetching messages in batches using Discord's limit/after pagination; understanding rate limits and cursor-based traversal is critical for correct export
  • Message Format Rendering (Markdown to HTML/PlainText) — Discord uses a custom markdown dialect; the exporter must parse and convert @mentions, #channels, spoilers, code blocks to target formats—core export complexity
  • Snowflake IDs — Discord uses 64-bit Snowflake IDs for messages, channels, users; extracting embedded timestamps from IDs is necessary for sorting and filtering without API calls
  • HTML Self-Contained Exports — The SelfContainedSpecs.cs test indicates exports embed all CSS/images inline to create portable single-file archives; requires understanding of HTML inlining and base64 encoding
  • Message Partitioning by Size — Large exports split across multiple files; PartitioningSpecs.cs shows how to avoid oversized output files while preserving message continuity and metadata
  • Rate Limiting and Exponential Backoff — Discord API enforces strict rate limits; the exporter must implement backoff to respect limits without losing messages or failing exports
  • Multiformat Serialization (HTML, JSON, CSV, PlainText) — Single message model exported to 4 formats requires abstraction and strategy pattern; each format has different escaping, nesting, and metadata handling rules
  • Tyrrrz/CliFx — CLI framework that DiscordChatExporter likely uses for command-line argument parsing and help text generation
  • Tyrrrz/DSharpPlus — Alternative Discord library for C#; directly relevant if considering a bot-based export approach vs. user account automation
  • chee/discord-exporter — JavaScript/Node.js alternative exporter for Discord; useful comparison for feature parity and format compatibility
  • Discord/discord-interactions — Official Discord interactions library; reference for API contract if maintaining exporter against Discord API changes
  • Tyrrrz/Persistence — Likely internal utility library used by DiscordChatExporter for data serialization and caching

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for ThreadInclusionMode converter and enum handling

The file DiscordChatExporter.Cli/Commands/Converters/ThreadInclusionModeInputConverter.cs exists but there's no corresponding test spec in DiscordChatExporter.Cli.Tests/Specs. Given the extensive test coverage pattern (HtmlContentSpecs, JsonContentSpecs, etc.), this converter deserves dedicated tests. This is especially important since thread handling is a critical feature and the converter handles user input validation.

  • [ ] Create DiscordChatExporter.Cli.Tests/Specs/ThreadInclusionModeSpecs.cs
  • [ ] Add test cases for valid thread inclusion modes (All, Archive, Active, None)
  • [ ] Add test cases for invalid input handling and error messages
  • [ ] Verify integration with ExportCommandBase that uses this converter
  • [ ] Run existing test suite to ensure no regressions

Add missing documentation for message filtering and thread inclusion features

While .docs/Message-filters.md exists and .docs/Using-the-CLI.md is present, there's no dedicated documentation for the ThreadInclusionMode feature found in DiscordChatExporter.Cli/Commands/Shared/ThreadInclusionMode.cs. Given that the repo has comprehensive docs for Token-and-IDs.md and Troubleshooting.md, thread handling deserves similar coverage to help users understand this non-obvious feature.

  • [ ] Create .docs/Thread-Inclusion.md documenting all ThreadInclusionMode options
  • [ ] Add CLI examples showing --thread-inclusion usage in .docs/Using-the-CLI.md
  • [ ] Document thread behavior differences between export formats in .docs/Message-filters.md
  • [ ] Add troubleshooting section for common thread-related issues in .docs/Troubleshooting.md

Add test specs for TruthyBooleanInputConverter edge cases and documentation

The DiscordChatExporter.Cli/Commands/Converters/TruthyBooleanInputConverter.cs handles user input for boolean flags, but there's no corresponding TruthyBooleanSpecs.cs test file. This converter is critical for CLI usability and should have explicit test coverage for edge cases (empty strings, whitespace, case sensitivity, non-boolean values) to prevent user confusion.

  • [ ] Create DiscordChatExporter.Cli.Tests/Specs/TruthyBooleanInputConverterSpecs.cs
  • [ ] Add tests for truthy values (true, yes, 1, on, etc.)
  • [ ] Add tests for falsy values (false, no, 0, off, etc.)
  • [ ] Add tests for edge cases (null, empty string, whitespace, mixed case)
  • [ ] Add tests for invalid input with appropriate error messages
  • [ ] Document supported boolean formats in .docs/Using-the-CLI.md

🌿Good first issues

  • Add test coverage for edge case in CsvContentSpecs.cs—CSV export currently may lack tests for fields with commas or quotes; add spec test and implement escaping if missing
  • Improve error messages in plaintext export (PlainTextContentSpecs.cs)—currently no validation that plaintext preserves all message metadata; add assertion and fix if needed
  • Expand .docs/Troubleshooting.md with specific Discord API error codes and recovery steps—currently thin; add real error scenarios from GitHub issues

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 6258394 — Remove lang version from build props (Tyrrrz)
  • e647254 — Refactor fetching Avalonia TopLevel (Tyrrrz)
  • ee163d6 — Bump actions/upload-artifact from 7.0.0 to 7.0.1 in the actions group (#1528) (dependabot[bot])
  • 5838c05 — Update for Avalonia 12 (Tyrrrz)
  • 07a0277 — Bump the nuget group with 15 updates (#1529) (dependabot[bot])
  • 0a623b2 — Refactor GUI spacing (Tyrrrz)
  • da4f5ea — Use PowerKit's Uri.TryGetFilaName() (Tyrrrz)
  • 34b5ccc — Remove BOM (Tyrrrz)
  • 7456f0f — Add PowerKit and replace custom utility extensions (#1525) (Copilot)
  • 757daa7 — Forward slashes (Tyrrrz)

🔒Security observations

DiscordChatExporter demonstrates reasonable security practices with some areas of concern. The project has GitHub Actions CI/CD configured and uses Dependabot for dependency management, which are positive indicators. However, potential XSS vulnerabilities in HTML export functionality, inadequate secrets management in tests, and risks around Discord token handling are notable concerns. The maintenance status of the project should be monitored for timely security updates. Critical recommendations include implementing strict input sanitization for HTML exports, removing test secrets from version control, and enforcing secure token handling practices throughout the codebase.

  • Medium · Test Secrets File Exposed — DiscordChatExporter.Cli.Tests/Infra/Secrets.cs. The file 'DiscordChatExporter.Cli.Tests/Infra/Secrets.cs' suggests hardcoded or test credentials may be present in the codebase. Even test secrets should not be committed to version control as they can be reused or leak sensitive information. Fix: Move all secrets to environment variables or secure secret management systems. Never commit test credentials to version control. Use .gitignore to exclude secrets files and implement pre-commit hooks to prevent accidental commits.
  • Medium · Potential Sensitive Channel/Guild IDs in Tests — DiscordChatExporter.Cli.Tests/Infra/ChannelIds.cs. Test files reference 'ChannelIds.cs' which may contain real Discord channel and guild identifiers. These IDs can be used to identify specific Discord servers and channels, potentially revealing organizational structure or private communities. Fix: Use placeholder or mock IDs for testing instead of real Discord identifiers. Document that test data should never reference production Discord servers or user communities.
  • Medium · HTML Output May Be Vulnerable to XSS — DiscordChatExporter.Core (HTML export functionality). The codebase exports chat messages to HTML format (evidenced by HtmlContentSpecs.cs, HtmlMentionSpecs.cs, etc.). If user-generated content from Discord messages is not properly sanitized before rendering to HTML, this could enable stored XSS attacks. Fix: Ensure all Discord message content is properly HTML-escaped before rendering. Use a vetted HTML sanitization library (HtmlSanitizer, AngleSharp) to strip potentially malicious content while preserving intended formatting.
  • Medium · Discord Token Handling Risk — DiscordChatExporter.Cli, DiscordChatExporter.Core. The application accepts Discord authentication tokens (documented in .docs/Token-and-IDs.md). Improper handling of tokens in memory, logs, or error messages could leak credentials. Fix: Implement secure token storage using credential managers or secure string classes. Never log tokens, even in debug mode. Clear tokens from memory after use. Implement token rotation and expiration mechanisms.
  • Low · Docker Image Security Baseline Not Visible — DiscordChatExporter.Cli.dockerfile, .github/workflows/docker.yml. The project includes a Docker configuration (DiscordChatExporter.Cli.dockerfile), but without visibility into the base image and dependency versions, potential supply chain vulnerabilities cannot be assessed. Fix: Use specific versioned base images (not 'latest'). Implement regular image scanning with tools like Trivy. Keep all dependencies updated. Consider using minimal base images (alpine, distroless).
  • Low · Missing Dependency Manifest for Analysis — Directory.Packages.props, *.csproj files. The dependency/package file content was not provided in the analysis context. This prevents assessment of vulnerable dependencies, outdated libraries, or supply chain risks. Fix: Regularly audit dependencies using 'dotnet list package --vulnerable'. Enable automated dependency updates via Dependabot (already configured). Run security scanners like NuGet Audit and SonarQube.
  • Low · Potential Information Disclosure via Error Messages — DiscordChatExporter.Cli/Program.cs. CLI application may expose stack traces or internal system information through error messages, potentially revealing implementation details useful to attackers. Fix: Implement comprehensive error handling that logs full details internally but returns user-friendly messages to clients. Never expose stack traces or sensitive paths in user-facing output.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · Tyrrrz/DiscordChatExporter — RepoPilot