Tyrrrz/DiscordChatExporter
48.0
Weak · 23 September 2026
18.4k
lines of production code
C#
primary language
5
measurements over time
What this system is
DiscordChatExporter is a desktop and command-line application designed to export chat history from Discord servers into structured formats such as HTML, JSON, and CSV. It provides granular control over the export process, allowing users to filter messages by content, author, or metadata, and to include or exclude specific elements like threads, polls, and embedded media. The system supports both user and bot accounts, handling authentication securely and managing rate limits to ensure reliable data retrieval from the Discord API.
How it got here
2017–2020 — Avalonia GUI migration and .NET 10 upgrade
10 changes.
The project modernized its desktop interface by migrating from WPF to Avalonia UI and upgraded the runtime to .NET 10. This period also involved restructuring the CLI with CliFx, centralizing NuGet package management, and enhancing security by encrypting stored Discord tokens.
2021 — Core architecture and filtering overhaul
16 changes.
This period focused on a comprehensive rewrite of the core data models and export engine, introducing modern C\# patterns and robust support for new Discord API features like polls, threads, and embeds. The work significantly expanded message filtering capabilities with a new grammar and added detailed test coverage to ensure reliability across CSV, HTML, and JSON output formats.
2022–2026 — Avalonia GUI migration
11 changes.
This period focused on migrating the graphical user interface from its previous framework to Avalonia, establishing new core infrastructure for view management, theming, and localization. The update introduced a redesigned dashboard for guild and channel selection, added granular controls for thread inclusion, and implemented multi-language support to enhance international usability.
Features
Add internationalization and native method utilities
The application now includes utilities to support internationalization and native OS interactions. A new Internationalization helper detects whether the current culture uses a 24-hour time format and returns the appropriate Avalonia clock identifier, ensuring time pickers display correctly for users in 24-hour regions. Additionally, a NativeMethods class exposes a P/Invoke wrapper for the Windows MessageBox API, enabling native message dialogs within the GUI.
DiscordChatExporter.Gui/Utils · high confidence
Add multi-language support for the GUI
The application now supports user interface localization. Users can select their preferred language from the settings, choosing between English, Ukrainian, German, French, Spanish, or System (auto-detect). The localization system covers all UI strings, including dashboard tooltips, token instructions, export settings, and dialog messages, with English serving as the fallback for any missing translations.
DiscordChatExporter.Gui/Localization · high confidence
Add utility extensions for Avalonia, environment, and Markdown parsing
The application now includes new internal helper methods to support the Avalonia UI migration and data processing. AvaloniaExtensions provide standardized ways to retrieve the main application view, find the top-level window, and safely shut down the application across different runtime modes. EnvironmentExtensions introduce a new capability to detect a stable machine identifier by reading the Windows registry or Linux machine-id files, which supports machine-bound operations. Additionally, MarkdigExtensions add a helper to extract plain text content from Markdown inline nodes, aiding in text processing.
DiscordChatExporter.Gui/Utils/Extensions · high confidence
Added Superpower parser extension methods
A new extension class for Superpower TextParser has been added, providing a Token method that automatically ignores surrounding whitespace and a Log method for debugging parser execution. These utilities simplify the creation and testing of text parsers within the core library.
DiscordChatExporter.Core/Utils/Extensions · high confidence
Added ThreadInclusionMode enum for filtering thread exports
A new ThreadInclusionMode enum has been introduced in both the CLI commands and GUI models, providing options to include None, Active, or All threads when exporting Discord data. This allows users to control which threads are included in their exports, offering more granular control over the exported content.
DiscordChatExporter.Cli/Commands/Shared, DiscordChatExporter.Gui/Models · high confidence
Introduce DashboardViewModel for guild and channel selection
The main dashboard interface is now driven by a new DashboardViewModel, which manages the state for token input, guild selection, and channel hierarchy building. This component handles the asynchronous retrieval of user guilds and channels (including optional thread inclusion based on settings), exposes observable properties for the UI to bind to, and coordinates with dialog and snackbar managers to display errors or settings. It also implements logic to persist the last used token and manage busy/progress states during data fetching.
DiscordChatExporter.Gui/ViewModels/Components · high confidence
New HyperLink control for clickable text in the GUI
A new HyperLink user control has been added to the GUI, allowing users to display text that can either execute a bound command or open a specified URL in the default browser when clicked. This control provides a consistent way to handle interactive links within the application interface, utilizing Avalonia's styling system for hover effects.
DiscordChatExporter.Gui/Views/Controls · high confidence
New common data utilities for file sizes and Discord asset URLs
The core library now includes new helper types in the \DiscordChatExporter.Core.Discord.Data.Common\ namespace. \FileSize\ is a new record struct that formats byte counts into human-readable strings (e.g., '1.5 MB') using invariant culture. \ImageCdn\ provides static methods to construct URLs for various Discord assets, including standard and custom emojis, guild/channel icons, user avatars, member avatars, and stickers, handling animated variants and fallbacks. Additionally, a simple \IHasId\ interface is introduced to standardize ID access across data models.
DiscordChatExporter.Core/Discord/Data/Common · high confidence
Security
Discord tokens are now encrypted at rest in the settings file
The application now encrypts the stored Discord token using AES-GCM with a machine-bound key derived from the system's machine ID and a project salt. This change ensures that tokens saved in the settings file are no longer stored as plain text, protecting them from unauthorized access on the local machine. The implementation includes a custom JSON converter that handles both encryption on save and decryption on load, with backward compatibility for older plain-text tokens which are automatically re-encrypted upon the next save.
DiscordChatExporter.Gui/Services · high confidence
Behavioural changes
CLI command base refactoring and new export options
The CLI command base classes have been restructured, introducing a new \DiscordCommandBase\ that centralizes authentication and rate-limiting logic, including a new \--respect-rate-limits\ option to control advisory rate limit handling. The \ExportCommandBase\ now supports exporting multiple channels in parallel with a \--parallel\ limit, allows filtering messages by ID using \--after\ and \--before\, and enables reversing message order with \--reverse\. Date formatting has shifted from a custom format string to a \--locale\ option, while the deprecated \--dateformat\ and \--bot\ options remain for backward compatibility with warnings. Asset management has been renamed to 'assets' (e.g., \--media\ becomes \--media\ but logic refers to assets, \--media-dir\ is now \--media-dir\), and validation ensures that \--reuse-media\ and \--media-dir\ are only used with \--media\, and that multiple channels are not exported to a single file without a directory or template path.
DiscordChatExporter.Cli/Commands/Base · high confidence
CLI restructured with new commands and thread inclusion options
The CLI interface has been restructured to support exporting all channels across all guilds via the new \exportall\ command, which can optionally pull from a Discord data dump. The \export\ command now accepts multiple channel IDs and automatically unwraps category IDs to export all contained channels. Additionally, the \channels\ command now supports listing threads with a new \--include-threads\ option that accepts flexible input formats (active, archived, all, or boolean-like values) via a custom input converter.
DiscordChatExporter.Cli/Commands · high confidence
Dialog UIs migrated to Avalonia with new settings and export controls
The Export Setup, Settings, and Message Box dialog views have been rewritten in Avalonia XAML (AXAML), replacing the previous framework. This migration introduces a redesigned Export Setup dialog with localized labels, markdown-parsed tooltips, and controls for output path, format, date/time limits, partitioning, and filtering. The Settings dialog now exposes controls for theme, language, auto-updates, token persistence, rate-limit preferences, thread inclusion, locale, UTC normalization, and parallel limit. The Message Box dialog provides a consistent, styled interface for standard user notifications.
DiscordChatExporter.Gui/Views/Dialogs · high confidence
DiscordChatExporter GUI migrates to Avalonia UI
The DiscordChatExporter desktop application has been rewritten using the Avalonia UI framework, replacing the previous UI technology. This migration introduces a modern Material Design interface with a three-way theme switcher (Light, Dark, and System default) that dynamically adapts to user preferences and OS settings. The new GUI includes a built-in localization system for multi-language support, a dependency-injection-based architecture for managing views and view models, and environment variable overrides (DISCORDCHATEXPORTER\_SETTINGS\_PATH and DISCORDCHATEXPORTER\_ALLOW\_AUTO\_UPDATE) to control settings storage and auto-update behavior. Users will experience improved styling consistency across controls like combo boxes, sliders, and dialogs, along with better shutdown handling and error reporting on Windows.
DiscordChatExporter.Gui · high confidence
DiscordChatExporter upgrades to .NET 10 and modernizes build infrastructure
The application has been upgraded to target .NET 10.0, requiring users to run the software on the .NET 10 runtime. The Docker image has been updated to use the .NET 10 Alpine base image, includes the full ICU libraries and timezone data for correct locale handling, and runs as a non-root user to fix file permission issues. Additionally, the project now uses a centralized NuGet package management configuration and emits source-generated files to improve debugging capabilities.
(repo-wide) · high confidence
Expanded message filtering capabilities with new filter types and improved search logic
The message filtering system has been refactored to support a broader range of export criteria. Users can now filter messages by reactions (using the \has:reaction\ syntax), pinned status (\has:pin\), and guild invites (\has:invite\). The existing \contains\ filter has been improved to respect word boundaries and spaces more accurately, and it now also searches within embed content (titles, descriptions, fields) and poll questions/answers. Additionally, new filters allow matching messages by author (\from:\) and mentions (\mentions:\), while the underlying filter engine now supports combining conditions with AND/OR logic and negation.
DiscordChatExporter.Core/Exporting/Filtering · high confidence
Improved CLI progress reporting and status handling
The CLI now uses Spectre.Console for displaying progress bars and status updates, providing a more consistent and visually clear experience during export operations. A new extension method ensures that progress tasks with empty or null descriptions are handled gracefully by defaulting to a placeholder, preventing potential crashes or confusing output. Additionally, the implementation ensures that failed progress tasks are marked as completed, improving robustness when underlying operations encounter errors.
DiscordChatExporter.Cli/Utils · high confidence
Improved HTTP resilience and URL encoding for HTML exports
The core utility layer now features a robust HTTP client with a retry policy that automatically handles server-side errors (5xx), rate limits, timeouts, and SSL exceptions, ensuring more reliable data export. Additionally, HTML exports now correctly handle absolute file paths by prepending the 'file://' protocol and normalizing separators, which fixes issues with opening exported files in browsers on Windows.
DiscordChatExporter.Core/Utils · high confidence
Introduce new CLI entry point using CliFx
The DiscordChatExporter.Cli application now uses a new Program.cs entry point that initializes the command-line interface via the CliFx library. This change establishes the foundation for the CLI by setting up the command builder to automatically discover and register commands from the assembly, replacing the previous startup mechanism.
DiscordChatExporter.Cli · high confidence
Main application initialization and update handling
The MainViewModel now orchestrates the application's startup sequence by displaying a support message for Ukraine and a warning for development builds, while also checking for and managing automatic updates via a snackbar notification system. It handles the finalization of pending updates on shutdown and ensures settings are saved, replacing previous manual or less structured initialization logic with a centralized view-model approach using the new Stylet framework.
DiscordChatExporter.Gui/ViewModels · high confidence
Main window UI migrated to Avalonia
The main application window has been rewritten using Avalonia UI (XAML-based) to replace the previous framework. This change updates the core layout structure, including the window dimensions, icon, and the integration of the DialogHost and SnackbarHost components for user notifications and dialogs.
DiscordChatExporter.Gui/Views · high confidence
Markdown parser refactored to support headings, lists, and improved formatting
The markdown parsing engine has been rewritten to better replicate Discord's rendering behavior, introducing support for new content structures including headings (using \# syntax) and unordered lists. The parser now uses a first-matched-first-served approach with regex-based matchers, allowing for more accurate handling of nested formatting like bold, italic, strikethrough, spoilers, and code blocks. This change also improves robustness by preventing stack overflows through recursion depth limits and handling invalid mentions or timestamps more gracefully.
DiscordChatExporter.Core/Markdown/Parsing · high confidence
New Dashboard UI with channel export shortcuts
The application now features a new Dashboard view that allows users to manage their Discord token, select guilds, and choose channels for export. A key usability improvement is that double-clicking a channel in the tree view now automatically triggers the export setup, streamlining the workflow. The interface also includes visual feedback for progress and handles category selection by preventing them from being exported.
DiscordChatExporter.Gui/Views/Components · high confidence
New WPF-to-Avalonia value converters for GUI data binding
The GUI now includes a set of new Avalonia value converters in the Converters folder to support the migration from WPF to Avalonia. These converters handle specific display logic: ChannelToHierarchicalNameStringConverter formats channel names, ExportFormatToStringConverter displays export format names, LocaleToDisplayNameStringConverter resolves locale codes to human-readable names, MarkdownToInlinesConverter parses Markdown text into styled UI inlines (handling bold, italic, links, lists), RateLimitPreferenceToStringConverter displays rate limit settings, and SnowflakeToTimestampStringConverter converts Discord snowflakes to timestamps. These components are essential for the correct rendering of data in the Avalonia-based interface.
DiscordChatExporter.Gui/Converters · high confidence
New embed data model and specialized projections
The embed parsing logic has been refactored to use a new, structured data model where the core \Embed\ record and its sub-components (Author, Field, Footer, Image, Video) are now distinct types. This change introduces specific projection classes for Poll Results, Spotify Tracks, Twitch Clips, and YouTube Videos, enabling the exporter to correctly identify and handle these specialized content types during export.
DiscordChatExporter.Core/Discord/Data/Embeds · high confidence
New export setup dialog and settings management in the GUI
The GUI now uses a dedicated ExportSetupViewModel to manage export configurations, introducing options to reverse message order, disable markdown formatting, and control asset downloading and reuse. Users can now specify a custom directory for assets and set date/time ranges for exports. The SettingsViewModel has been updated to support locale selection (defaulting to the system locale), theme switching, auto-update controls, and parallel export limits, while also persisting user preferences across sessions.
DiscordChatExporter.Gui/ViewModels/Dialogs · high confidence
New framework infrastructure for Avalonia-based GUI
This change introduces the core framework classes for the new Avalonia-based GUI, including a DialogManager that ensures sequential dialogs appear correctly, a ViewManager that automates view initialization via the Loaded event, and base classes for ViewModels and UserControls with type-safe DataContext handling. It also adds a SnackbarManager for user notifications, a ThemeVariant enum supporting a three-way theme switcher (System, Light, Dark), and a ViewModelManager for creating and configuring view models with dependency injection.
DiscordChatExporter.Gui/Framework · high confidence
New message filter grammar with expanded content matching and negation aliases
The message filtering system has been refactored to support a more robust grammar, introducing new filter capabilities and improving CLI usability. Users can now filter messages by specific content types using the \has:\ prefix, including links, embeds, files, videos, images, sounds, pins, and guild invites. Additionally, a new \reaction:\ filter allows matching messages based on reactions. The negation operator now accepts both \-\ and \\~\ (tilde) as aliases, resolving CLI conflicts where the dash character interferes with command-line options. The parser also handles quoted strings and escaped characters more reliably, ensuring that text filters do not accidentally match filter keywords.
DiscordChatExporter.Core/Exporting/Filtering/Parsing · high confidence
Rebuilt Discord data models to support new API features and modern C\# patterns
The core data layer in DiscordChatExporter.Core/Discord/Data has been completely rewritten using C\# records and a new \PowerKit\ extension library. This change introduces support for modern Discord API features, including message forwarding (via \MessageSnapshot\), polls (\Poll\, \PollAnswer\), and various system notifications. It also adds proper handling for voice channels, thread exports, and member-level avatars. The \User\ model now supports the new username system (removing discriminators), and the \Emoji\ model uses a new index for standard emoji codes. Additionally, the \Channel\ model now correctly handles parent hierarchies and direct message grouping, while \Attachment\ and \Sticker\ models have been updated to support new file types and formats.
DiscordChatExporter.Core/Discord/Data · high confidence
Refactor exception hierarchy to support fatal error classification
The core exception handling has been restructured to introduce a base \DiscordChatExporterException\ class that includes a new \IsFatal\ property, allowing the application to distinguish between recoverable errors and critical failures. Additionally, a new \ChannelEmptyException\ has been added to specifically handle cases where a channel contains no messages to export, replacing generic error handling with a more descriptive, context-specific exception type.
DiscordChatExporter.Core/Exceptions · high confidence
Refactor partition limit logic to use C\# 12 primary constructors and explicit format providers
The partitioning logic in the core library has been refactored to use C\# 12 primary constructors for the \FileSizePartitionLimit\, \MessageCountPartitionLimit\, and \NullPartitionLimit\ classes, simplifying their implementation. Additionally, the \PartitionLimit.TryParse\ and \Parse\ methods now accept an optional \IFormatProvider\ parameter, ensuring that string parsing for file sizes and message counts respects the caller's culture settings rather than relying on invariant or default behavior.
DiscordChatExporter.Core/Exporting/Partitioning · high confidence
Refactored Markdown parsing to support nested structures and lists
The Markdown parsing engine has been refactored to use a new node-based architecture, enabling support for nested formatting (such as bold text inside links) and list structures. This change introduces specific node types for headings, lists, list items, and various formatting styles, allowing for more complex and accurate representation of Discord message content in exports.
DiscordChatExporter.Core/Markdown · high confidence
Restructured export engine with new core components and format writers
The export logic in DiscordChatExporter.Core/Exporting has been reorganized into a new set of classes to manage the export lifecycle and output generation. A new ChannelExporter orchestrates the process, handling validation for forum channels and empty message ranges, while an ExportContext manages the resolution of guild members, channels, and roles on demand. The system now uses dedicated writers for each format: CsvMessageWriter for CSV output, HtmlMessageWriter for HTML (including message grouping and template rendering), and JsonMessageWriter for JSON (including detailed user, role, and embed data). Asset downloading is handled by a new ExportAssetDownloader that normalizes CDN URLs, supports legacy file naming for backwards compatibility, and uses keyed locking to prevent race conditions.
DiscordChatExporter.Core/Exporting · high confidence
Support for bot tokens and configurable rate limit handling
The Discord client now automatically detects whether the provided authentication token is a user or bot token, allowing bot accounts to export data. Additionally, users can now control how strictly the application respects Discord's advisory rate limits via a new \RateLimitPreference\ setting, which can be configured to ignore, respect for user tokens only, respect for bot tokens only, or always respect limits.
DiscordChatExporter.Core/Discord · high confidence
Support for case-insensitive data package index lookup
The data dump loading logic now performs a case-insensitive search for the channel index file (messages/index.json) within the data package archive. This ensures compatibility with different data dump versions that may use varying filename casing, preventing failures when the expected index file cannot be located due to case mismatches.
DiscordChatExporter.Core/Discord/Dump · high confidence
Test coverage
Add test infrastructure for automated CLI export verification; Expanded test coverage for DiscordChatExporter CLI specs.
Dependencies
Migrate to Centralized NuGet Package Management
The project now uses Central Package Management (CPM) to standardize dependency versions across all components. A new \Directory.Packages.props\ file centrally defines versions for key libraries including Avalonia 12.1.1, CliFx 3.0.1, and Microsoft.Extensions packages version 10.0.11, while individual project files reference these packages without specifying versions. This change simplifies dependency updates and ensures version consistency across the CLI, Core, GUI, and Test projects.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 49 → 48 (-0.5)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 84 → 83 (-1.5)
- Architecture 59 → 59 (-0.1)
- Maturity 54 → 55 (+0.2)
- Readiness 45 → 44 (-0.5)
- Security 72 → 74 (+2.4)
- Accessibility 42 → 41 (-1.1)
- Performance 80 → 80 (+0.0)
Resolved (11)
- Coverage not measured — no test passed in the analyzed run
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Medium IaC: CKV_DOCKER_3 (DiscordChatExporter.Cli.dockerfile)
- No exposed public API
- Off-boarding risk: anonymized user #1
- Split DiscordChatExporter.Core
- redundant comment (DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs)
New (45)
- CoverageExclusion (DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs)
- CoverageExclusion (DiscordChatExporter.Core/Discord/Snowflake.cs)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (.docs/Readme.md)
- Duplicated block (12 lines × 3) (DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs)
- Duplicated block (16 lines × 2) (DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs)
- Duplicated block (18 lines × 2) (DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs)
- Duplicated block (19–23 lines × 2) (DiscordChatExporter.Cli/Commands/ExportAllCommand.cs)
- Duplicated block (22 lines × 2) (DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs)
- Duplicated block (6 lines × 2) (DiscordChatExporter.Gui/Framework/UserControl.cs)
- Duplicated block (9 lines × 4) (DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Hotspot: DiscordChatExporter.Core/Exporting/PlainTextMessageExtensions.cs (DiscordChatExporter.Core/Exporting/PlainTextMessageExtensions.cs)
- Medium IaC: WD-DOCKER-0003 (DiscordChatExporter.Cli.dockerfile)
- Medium IaC: WD-DOCKER-0003 (DiscordChatExporter.Cli.dockerfile)
- …and 25 more
Changes since last survey
- 6 commits — 6 feature/other, 0 fixes
By area
- (root) — 2 commits
- DiscordChatExporter.Core/Discord — 2 commits
- .github/workflows — 1 commit
- DiscordChatExporter.Cli.Tests/Infra — 1 commit
Notable commits
- change: Add tests for polls
- change: Bump docker/setup-buildx-action from 4.2.0 to 4.3.0 in the actions group (#1587)
- change: Bump the nuget group with 10 updates (#1588)
- change: Bundle for macOS via MacBundle
- change: Refactor polls
- change: Render polls in HTML exports (#1581)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Tyrrrz/DiscordChatExporter was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 3a8ef99769ecddb4c405e1020c1139106e6cd03b — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.