mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-07-18 19:46:16 +02:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a405ab184e | |||
| b861a69799 | |||
| d53b4c825a | |||
| 30678e96e5 |
@@ -1,5 +1,8 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
|
- name: ⚠ Feature request
|
||||||
|
url: https://github.com/Tyrrrz/.github/blob/master/docs/project-status.md
|
||||||
|
about: Sorry, but this project is in maintenance mode and no longer accepts new feature requests.
|
||||||
- name: 💬 Discord server
|
- name: 💬 Discord server
|
||||||
url: https://discord.gg/2SUWKFnHSm
|
url: https://discord.gg/2SUWKFnHSm
|
||||||
about: Chat with the project community.
|
about: Chat with the project community.
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
name: ✨ Feature request
|
|
||||||
description: Request a new feature.
|
|
||||||
labels: [enhancement]
|
|
||||||
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
🧐 **Guidelines:**
|
|
||||||
|
|
||||||
- Search through [existing issues](https://github.com/Tyrrrz/DiscordChatExporter/issues?q=is%3Aissue) first to ensure that this feature has not been requested before.
|
|
||||||
- Write a descriptive title for your issue. Avoid generic or vague titles such as "Some suggestions" or "Ideas for improvement".
|
|
||||||
- Keep your issue focused on one single problem. If you have multiple feature requests, please create separate issues for each of them.
|
|
||||||
- Provide as much context as possible in the details section. Include screenshots, screen recordings, links, references, or anything else you may consider relevant.
|
|
||||||
- If you want to ask a question instead of requesting a feature, please use [discussions](https://github.com/Tyrrrz/DiscordChatExporter/discussions/new) instead.
|
|
||||||
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: Flavor
|
|
||||||
description: Is this feature request related to specific flavor(s) of DiscordChatExporter? If not applicable, leave this field blank.
|
|
||||||
multiple: true
|
|
||||||
options:
|
|
||||||
- GUI (Graphical User Interface)
|
|
||||||
- CLI (Command Line Interface)
|
|
||||||
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: Export format
|
|
||||||
description: Is this feature request related to specific export format(s)? If not applicable, leave this field blank.
|
|
||||||
multiple: true
|
|
||||||
options:
|
|
||||||
- HTML
|
|
||||||
- TXT
|
|
||||||
- JSON
|
|
||||||
- CSV
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Details
|
|
||||||
description: Clear and thorough explanation of the feature you have in mind.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
### v2.35.2 (08-Sep-2022)
|
||||||
|
|
||||||
|
- Updated usage guide to mention the need to enable "Message Content Intent" to use a bot as a medium for exporting messages.
|
||||||
|
- [CLI] Fixed an issue where passing an existing directory as the output path failed when exporting multiple channels (for example, when running `exportdm`). An ambiguous output path will now always be treated as a directory path if that directory already exists. If it doesn't exist, it will be treated as a file path, matching the previous behavior.
|
||||||
|
|
||||||
### v2.35.1 (26-Aug-2022)
|
### v2.35.1 (26-Aug-2022)
|
||||||
|
|
||||||
- Added `~` character as an alias for `-` when negating a message filter. This should make it easier to use negated filters from CLI where the dash character already has other meanings.
|
- Added `~` character as an alias for `-` when negating a message filter. This should make it easier to use negated filters from CLI where the dash character already has other meanings.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>2.35.1</Version>
|
<Version>2.35.2</Version>
|
||||||
<Company>Tyrrrz</Company>
|
<Company>Tyrrrz</Company>
|
||||||
<Copyright>Copyright (c) Oleksii Holub</Copyright>
|
<Copyright>Copyright (c) Oleksii Holub</Copyright>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public abstract class ExportCommandBase : TokenCommandBase
|
|||||||
[CommandOption(
|
[CommandOption(
|
||||||
"output",
|
"output",
|
||||||
'o',
|
'o',
|
||||||
Description = "Output file or directory path."
|
Description = "Output file or directory path. Directory path should end in a slash."
|
||||||
)]
|
)]
|
||||||
public string OutputPath
|
public string OutputPath
|
||||||
{
|
{
|
||||||
@@ -97,8 +97,7 @@ public abstract class ExportCommandBase : TokenCommandBase
|
|||||||
|
|
||||||
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<Channel> channels)
|
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<Channel> channels)
|
||||||
{
|
{
|
||||||
var cancellationToken = console.RegisterCancellationHandler();
|
// Reuse media option should only be used when the media option is set.
|
||||||
|
|
||||||
// https://github.com/Tyrrrz/DiscordChatExporter/issues/425
|
// https://github.com/Tyrrrz/DiscordChatExporter/issues/425
|
||||||
if (ShouldReuseMedia && !ShouldDownloadMedia)
|
if (ShouldReuseMedia && !ShouldDownloadMedia)
|
||||||
{
|
{
|
||||||
@@ -107,14 +106,26 @@ public abstract class ExportCommandBase : TokenCommandBase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the user does not try to export all channels into a single file.
|
||||||
|
// Output path must either be a directory, or contain template tokens.
|
||||||
// https://github.com/Tyrrrz/DiscordChatExporter/issues/799
|
// https://github.com/Tyrrrz/DiscordChatExporter/issues/799
|
||||||
if (channels.Count > 1 && !PathEx.IsDirectoryPath(OutputPath) && !OutputPath.Contains('%'))
|
// https://github.com/Tyrrrz/DiscordChatExporter/issues/917
|
||||||
|
var isValidOutputPath =
|
||||||
|
// Anything is valid when exporting a single channel
|
||||||
|
channels.Count <= 1 ||
|
||||||
|
// When using template tokens, assume the user knows what they're doing
|
||||||
|
OutputPath.Contains('%') ||
|
||||||
|
// Otherwise, require an existing directory or an unambiguous directory path
|
||||||
|
Directory.Exists(OutputPath) || PathEx.IsDirectoryPath(OutputPath);
|
||||||
|
|
||||||
|
if (!isValidOutputPath)
|
||||||
{
|
{
|
||||||
throw new CommandException(
|
throw new CommandException(
|
||||||
"Attempted to export multiple channels, but the output path is neither a directory nor a template."
|
"Attempted to export multiple channels, but the output path is neither a directory nor a template."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cancellationToken = console.RegisterCancellationHandler();
|
||||||
var errors = new ConcurrentDictionary<Channel, string>();
|
var errors = new ConcurrentDictionary<Channel, string>();
|
||||||
|
|
||||||
// Export
|
// Export
|
||||||
|
|||||||
@@ -17,13 +17,14 @@ public class GuideCommand : ICommand
|
|||||||
|
|
||||||
console.Output.WriteLine(" * Automating user accounts is technically against TOS — USE AT YOUR OWN RISK!");
|
console.Output.WriteLine(" * Automating user accounts is technically against TOS — USE AT YOUR OWN RISK!");
|
||||||
console.Output.WriteLine(" 1. Open Discord in your web browser and login");
|
console.Output.WriteLine(" 1. Open Discord in your web browser and login");
|
||||||
console.Output.WriteLine(" 2. Press Ctrl+Shift+I to show developer tools");
|
console.Output.WriteLine(" 2. Open any server or direct message channel");
|
||||||
console.Output.WriteLine(" 3. Navigate to the Network tab");
|
console.Output.WriteLine(" 3. Press Ctrl+Shift+I to show developer tools");
|
||||||
console.Output.WriteLine(" 4. Press Ctrl+R to reload");
|
console.Output.WriteLine(" 4. Navigate to the Network tab");
|
||||||
console.Output.WriteLine(" 5. Search for a request containing \"messages?limit=50\" or similar");
|
console.Output.WriteLine(" 5. Press Ctrl+R to reload");
|
||||||
console.Output.WriteLine(" 6. Select the Headers tab on the right");
|
console.Output.WriteLine(" 6. Search for a request containing \"messages?limit=50\" or similar");
|
||||||
console.Output.WriteLine(" 7. Scroll down to the Request Headers section");
|
console.Output.WriteLine(" 7. Select the Headers tab on the right");
|
||||||
console.Output.WriteLine(" 8. Copy the value of the \"authorization\" header");
|
console.Output.WriteLine(" 8. Scroll down to the Request Headers section");
|
||||||
|
console.Output.WriteLine(" 9. Copy the value of the \"authorization\" header");
|
||||||
console.Output.WriteLine();
|
console.Output.WriteLine();
|
||||||
|
|
||||||
// Bot token
|
// Bot token
|
||||||
@@ -34,6 +35,7 @@ public class GuideCommand : ICommand
|
|||||||
console.Output.WriteLine(" 2. Open your application's settings");
|
console.Output.WriteLine(" 2. Open your application's settings");
|
||||||
console.Output.WriteLine(" 3. Navigate to the Bot section on the left");
|
console.Output.WriteLine(" 3. Navigate to the Bot section on the left");
|
||||||
console.Output.WriteLine(" 4. Under Token click Copy");
|
console.Output.WriteLine(" 4. Under Token click Copy");
|
||||||
|
console.Output.WriteLine(" * Your bot needs to have Message Content Intent enabled to read messages");
|
||||||
console.Output.WriteLine();
|
console.Output.WriteLine();
|
||||||
|
|
||||||
// Guild or channel ID
|
// Guild or channel ID
|
||||||
|
|||||||
@@ -135,22 +135,14 @@
|
|||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Background="{DynamicResource MaterialDesignCardBackground}"
|
Background="{DynamicResource MaterialDesignCardBackground}"
|
||||||
IsEnabled="{Binding IsBusy, Converter={x:Static converters:InverseBoolConverter.Instance}}">
|
IsEnabled="{Binding IsBusy, Converter={x:Static converters:InverseBoolConverter.Instance}}">
|
||||||
<Grid.Resources>
|
|
||||||
<Style TargetType="TextBlock">
|
|
||||||
<Setter Property="FontWeight" Value="Light" />
|
|
||||||
</Style>
|
|
||||||
</Grid.Resources>
|
|
||||||
<!-- Placeholder / usage instructions -->
|
<!-- Placeholder / usage instructions -->
|
||||||
<Grid Visibility="{Binding AvailableGuilds, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}}">
|
<Grid Visibility="{Binding AvailableGuilds, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}}">
|
||||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="32,16"
|
Margin="32,16"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
|
FontWeight="Light"
|
||||||
LineHeight="20">
|
LineHeight="20">
|
||||||
<Run FontSize="18" Text="Please provide authentication token to continue" />
|
|
||||||
<LineBreak />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<!-- User token -->
|
<!-- User token -->
|
||||||
<InlineUIContainer>
|
<InlineUIContainer>
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
@@ -158,7 +150,7 @@
|
|||||||
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
||||||
Kind="Account" />
|
Kind="Account" />
|
||||||
</InlineUIContainer>
|
</InlineUIContainer>
|
||||||
<Run FontSize="16" Text="To get token for your personal account:" />
|
<Run FontSize="16" FontWeight="SemiBold" Text="To get token for your personal account:" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="* Automating user accounts is technically against TOS —" />
|
<Run Text="* Automating user accounts is technically against TOS —" />
|
||||||
<Run FontWeight="SemiBold" Text="use at your own risk" /><Run Text="!" />
|
<Run FontWeight="SemiBold" Text="use at your own risk" /><Run Text="!" />
|
||||||
@@ -169,31 +161,33 @@
|
|||||||
</Hyperlink>
|
</Hyperlink>
|
||||||
<Run Text="and login" />
|
<Run Text="and login" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="2. Press" />
|
<Run Text="2. Open any server or direct message channel" />
|
||||||
|
<LineBreak />
|
||||||
|
<Run Text="3. Press" />
|
||||||
<Run FontWeight="SemiBold" Text="Ctrl+Shift+I" />
|
<Run FontWeight="SemiBold" Text="Ctrl+Shift+I" />
|
||||||
<Run Text="to show developer tools" />
|
<Run Text="to show developer tools" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="3. Navigate to the" />
|
<Run Text="4. Navigate to the" />
|
||||||
<Run FontWeight="SemiBold" Text="Network" />
|
<Run FontWeight="SemiBold" Text="Network" />
|
||||||
<Run Text="tab" />
|
<Run Text="tab" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="4. Press" />
|
<Run Text="5. Press" />
|
||||||
<Run FontWeight="SemiBold" Text="Ctrl+R" />
|
<Run FontWeight="SemiBold" Text="Ctrl+R" />
|
||||||
<Run Text="to reload" />
|
<Run Text="to reload" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="5. Search for a request containing" />
|
<Run Text="6. Search for a request containing" />
|
||||||
<Run FontWeight="SemiBold" Text="messages?limit=50" />
|
<Run FontWeight="SemiBold" Text="messages?limit=50" />
|
||||||
<Run Text="or similar" />
|
<Run Text="or similar" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="6. Select the" />
|
<Run Text="7. Select the" />
|
||||||
<Run FontWeight="SemiBold" Text="Headers" />
|
<Run FontWeight="SemiBold" Text="Headers" />
|
||||||
<Run Text=" tab on the right" />
|
<Run Text=" tab on the right" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="7. Scroll down to the" />
|
<Run Text="8. Scroll down to the" />
|
||||||
<Run FontWeight="SemiBold" Text="Request Headers" />
|
<Run FontWeight="SemiBold" Text="Request Headers" />
|
||||||
<Run Text="section" />
|
<Run Text="section" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="8. Copy the value of the" />
|
<Run Text="9. Copy the value of the" />
|
||||||
<Run FontWeight="SemiBold" Text="authorization" />
|
<Run FontWeight="SemiBold" Text="authorization" />
|
||||||
<Run Text="header" />
|
<Run Text="header" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
@@ -206,7 +200,7 @@
|
|||||||
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
||||||
Kind="Robot" />
|
Kind="Robot" />
|
||||||
</InlineUIContainer>
|
</InlineUIContainer>
|
||||||
<Run FontSize="16" Text="To get token for a bot account:" />
|
<Run FontSize="16" FontWeight="SemiBold" Text="To get token for a bot account:" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
<Run Text="1. Open Discord" />
|
<Run Text="1. Open Discord" />
|
||||||
<Hyperlink Command="{s:Action OpenDiscordDeveloperPortal}">
|
<Hyperlink Command="{s:Action OpenDiscordDeveloperPortal}">
|
||||||
@@ -224,10 +218,14 @@
|
|||||||
<Run Text="click" />
|
<Run Text="click" />
|
||||||
<Run FontWeight="SemiBold" Text="Copy" />
|
<Run FontWeight="SemiBold" Text="Copy" />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
|
<Run Text="* Your bot needs to have" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Message Content Intent" />
|
||||||
|
<Run Text="enabled to read messages" />
|
||||||
|
<LineBreak />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
|
|
||||||
<Run FontSize="16" Text="If you have questions or issues, please refer to the" />
|
<Run Text="If you have questions or issues, please refer to the" />
|
||||||
<Hyperlink Command="{s:Action ShowHelp}" FontSize="16">wiki</Hyperlink><Run FontSize="16" Text="." />
|
<Hyperlink Command="{s:Action ShowHelp}">wiki</Hyperlink><Run Text="." />
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
[](https://tyrrrz.me/donate)
|
[](https://tyrrrz.me/donate)
|
||||||
[](https://twitter.com/tyrrrz/status/1495972128977571848)
|
[](https://twitter.com/tyrrrz/status/1495972128977571848)
|
||||||
|
|
||||||
> 🟢 **Project status**: active<sup>[[?]](https://github.com/Tyrrrz/.github/blob/master/docs/project-status.md)</sup>
|
> 🟡 **Project status**: maintenance mode<sup>[[?]](https://github.com/Tyrrrz/.github/blob/master/docs/project-status.md)</sup>
|
||||||
|
|
||||||
**DiscordChatExporter** can be used to export message history from a [Discord](https://discord.com) channel to a file.
|
**DiscordChatExporter** can be used to export message history from a [Discord](https://discord.com) channel to a file.
|
||||||
It works with direct messages, group messages, and server channels, and supports Discord's dialect of markdown as well as all other rich media features.
|
It works with direct messages, group messages, and server channels, and supports Discord's dialect of markdown as well as all other rich media features.
|
||||||
|
|||||||
Reference in New Issue
Block a user