Dimport 2025.9.19

Imports messages from JSON files generated by DiscordChatExporter and replaces expired links with media files downloaded by Dimage.
# Dimport

![Stars](https://img.shields.io/github/stars/Inc44/Dimport?style=social)
![Forks](https://img.shields.io/github/forks/Inc44/Dimport?style=social)
![Watchers](https://img.shields.io/github/watchers/Inc44/Dimport?style=social)
![Repo Size](https://img.shields.io/github/repo-size/Inc44/Dimport)
![Language Count](https://img.shields.io/github/languages/count/Inc44/Dimport)
![Top Language](https://img.shields.io/github/languages/top/Inc44/Dimport)
[![Issues](https://img.shields.io/github/issues/Inc44/Dimport)](https://github.com/Inc44/Dimport/issues?q=is%3Aopen+is%3Aissue)
![Last Commit](https://img.shields.io/github/last-commit/Inc44/Dimport?color=red)
[![Release](https://img.shields.io/github/release/Inc44/Dimport.svg)](https://github.com/Inc44/Dimport/releases)
[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/Inc44)
[![Build](https://github.com/Inc44/Dimage/actions/workflows/build.yml/badge.svg)](https://github.com/Inc44/Dimage/actions/workflows/build.yml)

Imports messages from JSON files generated by [DiscordChatExporter](https://github.com/Tyrrrz/DiscordChatExporter) and replaces expired links with media files downloaded by [Dimage](https://github.com/Inc44/Dimage).

## โš™๏ธ Features

- Imports messages from [DiscordChatExporter](https://github.com/Tyrrrz/DiscordChatExporter) JSON files as Discord bot messages.
- Replaces expired attachment links with local media files downloaded by [Dimage](https://github.com/Inc44/Dimage).
- Automatically scans multiple directory structures for media files (avatars, channels, emojis).
- Customizable Discord-like message appearance with extensive configuration options.
- Handles multiple images per message using Discord's multi-embed system.
- Converts reactions to interactive buttons or native Discord reactions.
- Preserves user mentions with clickable Discord format.
- Provides message range selection (first N, last N, or custom range).
- Includes cancellation system for long-running imports.
- Offers two import modes: embedded (Discord-like) and outside (raw content with attachments).
- Supports multiple imports inside channels (multiple servers were not tested).
- Optional embed-free import mode for minimal processing.

## โš ๏ธ Disclaimers

Discord doesn't allow sending messages and embeds from user accounts, so all imported messages are sent from the name of a Discord bot. This program tries to mimic real messages as much as possible using a variety of different options, so good luck.

## ๐Ÿš€ Installation from crates.io

```bash
cargo install dimport
```

## ๐Ÿ› ๏ธ Build from Source

```bash
git clone https://github.com/Inc44/Dimport.git
cd Dimport
cargo build --release
```

## ๐Ÿ“ฆ Publish

```bash
cargo publish
```

## ๐Ÿงพ Configuration

Create a `.env` file or set environment variables.

```
DISCORD_TOKEN=your_bot_token
```

## ๐Ÿ“– Usage Example

```bash
cargo run --release
```

```
/import "<export.json>" "<media_root>"
```

```
/cancel
```

```
/help
```

## ๐ŸŽจ Command-Line Arguments

| Argument              | Description                                                                                           |
|-----------------------|-------------------------------------------------------------------------------------------------------|
| `<json_path>`         | Path to the [DiscordChatExporter](https://github.com/Tyrrrz/DiscordChatExporter) JSON file (required) |
| `<media_path>`        | Path to the directory containing downloaded media files (optional)                                    |
| `--no-guild`          | Hide guild/server name from message footer                                                            |
| `--no-category`       | Hide category name from message footer                                                                |
| `--no-channel`        | Hide channel name from message footer                                                                 |
| `--no-timestamp`      | Hide message timestamps                                                                               |
| `--no-mentions`       | Skip converting @mentions to clickable Discord mentions                                               |
| `--no-reactions`      | Skip importing reactions entirely                                                                     |
| `--no-embed`          | Skip creating embeds (only works with `--outside`)                                                    |
| `--button`            | Display reactions as interactive buttons instead of native Discord reactions                          |
| `--reaction-users`    | Show detailed list of users who reacted to each message                                               |
| `--outside`           | Send metadata embed separately from attachments                                                       |
| `--disable-button`    | Make reaction buttons unclickable (only works with `--button`)                                        |
| `--range <start,end>` | Import messages within specified range (zero-indexed)                                                 |
| `--range-start <n>`   | Set starting message index for import range                                                           |
| `--range-end <n>`     | Set ending message index for import range                                                             |
| `--first <n>`         | Import only the first N messages                                                                      |
| `--last <n>`          | Import only the last N messages                                                                       |
| `--ephemeral`         | Hide messages of `/cancel` and `/help`                                                                |

## ๐ŸŽฏ Motivation

[DiscordChatExporter](https://github.com/Tyrrrz/DiscordChatExporter) supports only exporting. [Discord-Chat-Importer](https://github.com/Ethorbit/Discord-Chat-Importer) has been inactive for over two years and does not support link expiration introduced in late 2023. After creating the original version of [Dimage](https://github.com/Inc44/Dimage) in February 2025 and updating it recently, I decided to build a new alternative from scratch in Rust. It is inspired by [Discord-Chat-Importer](https://github.com/Ethorbit/Discord-Chat-Importer) in response style but includes new features and improved performance.

## ๐Ÿ› Bugs

Discord supports a maximum of 4 images per embed (PC only, 1 for other devices), not fixable yet. More details:

- [Is it possible to attach multiple images in an embed?](https://stackoverflow.com/questions/57182398/is-it-possible-to-attach-multiple-images-in-a-embed)
- [Finally a way to display multiple images in an Embed!](https://www.reddit.com/r/discordapp/comments/raz4kl/finally_a_way_to_display_multiple_images_in_an)

Discord opens the browser when clicking on a user handle instead of doing the same inside Discord, not fixable yet. More details:

- [Open a user's profile when sending a link like https://discord.com/users/USER_ID](https://github.com/discord/discord-api-docs/discussions/5183)

`set_var` of [dotenvy](https://github.com/allan2/dotenvy) is unsafe under the Rust 2024 edition. More details:

- [Functions that modify the environment have undocumented safety requirements](https://github.com/allan2/dotenvy/issues/112)

## โ›” Known Limitations

Discord bots can't react with the same emoji types multiple times to the message, so for mimicking multiple reactions, you can use `--button`. However, Discord does not support changing button text on click natively, so the button's reaction count doesn't change. Also, to avoid getting "Button interaction failed," you can freeze/disable buttons to make them unclickable using `--disable-button`, which unfortunately makes them grayed out. If you do not want to import reactions, you can use `--no-reactions`. So, good luck choosing your poison.

`/import` can't be registered as a slash command because it has too many flags or options. Therefore, its output cannot be ephemeral. Embeds are not suppressed for `/help` when ephemeral is used, probably because they disappear anyway.

`<json_path>` can be a link, either Google Drive download type `https://drive.usercontent.google.com/download?id=...` or GitHub raw type `https://raw.githubusercontent.com/user/repo/refs/heads/master/...`. However, other websites may not work for unknown reasons, like some temporary clipboards `https://nopaste.net/...`.

## ๐Ÿšง TODO

- [ ] Online media
- [ ] Registered descriptions
- [ ] Import from current channel to another channel
- [ ] Inline emojis (messages, reactions, buttons)
- [ ] (edited) status and disappearing photos
- [ ] User banner color instead of their exported first role
- [ ] Current user avatar
- [ ] /delete (last import, last n imports, all imports)
- [ ] Tests (json, media)

## ๐Ÿ™ Thanks

Creators of:

- [Rust](https://www.rust-lang.org)
- [Serenity and Poise](https://serenity-rs.github.io)
- [Serde](https://serde.rs)
- [Tokio](https://tokio.rs)
- [walkdir](https://github.com/BurntSushi/walkdir)
- [dotenvy](https://github.com/allan2/dotenvy)

People:

- Sharing how to send multiple images inside one embed
	- [Is it possible to attach multiple images in an embed?](https://stackoverflow.com/questions/57182398/is-it-possible-to-attach-multiple-images-in-a-embed)
	- [Finally a way to display multiple images in an Embed!](https://www.reddit.com/r/discordapp/comments/raz4kl/finally_a_way_to_display_multiple_images_in_an)

## ๐Ÿค Contribution

Contributions, suggestions, and new ideas are heartily welcomed. If you're considering significant modifications, please initiate an issue for discussion before submitting a pull request.

## ๐Ÿ“œ License

[![MIT](https://img.shields.io/badge/License-MIT-lightgrey.svg)](https://opensource.org/licenses/MIT)

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## ๐Ÿ’– Support

[![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/xamituchido)
[![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/inc44)
[![Patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/Inc44)