diff --git a/README.md b/README.md index ee2957df..420e0c75 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [discord-shield]: https://img.shields.io/discord/1407300551686885418?color=5865F2&logo=discord&logoColor=white + [discord-invite]: https://discord.gg/9Bzma6SwtW
@@ -10,219 +11,29 @@ [ ![discord-shield][] ][discord-invite] --- -A Discord modmail bot written in Rust that allows staff to manage support tickets via channels, with features like message editing, internationalization, structured error handling, and more. -The bot can operate in single-server or dual-server modes, supports SQLite for data storage, and offers a range of commands for staff to interact with users efficiently. - ---- -## ⚠️ Warning ⚠️ -This is my first major project in Rust; while I have solid experience in C and other languages, I'm learning Rust as I go — feedback and PRs are welcome. - -Project documentation is currently being written. - ---- -## Feature Summary (Currently Implemented) -- Open support ticket / staff⇄user thread (`!new_thread` or optional manual creation if enabled) -- **Single-server** or **dual-server (community + staff)** mode -- SQLite storage (threads, messages, staff alerts, blocked users) -- Incremental per-thread message numbering -- Staff replies → user DM + mirrored in thread channel -- Anonymous replies (`!anonreply` / `!ar`) -- Retroactive message editing (staff) with propagation & internal audit note (`!edit` / `!e`) -- Message deletion + renumbering (`!delete`) -- Controlled thread closing (`!close`) + forced orphan cleanup (`!force_close`) -- Scheduled closing with cancel and silent modes (see Thread Closing) -- Thread category moving with fuzzy matching (`!move` / `!mv`) -- Add/remove staff participants to a ticket (`!add_staff`, `!remove_staff`) -- Staff alert subscription with ping on next user activity (mentions + auto-clear on use) -- User/server membership awareness (e.g., user left server / not in community → system notice) -- Asynchronous recovery of missing messages (`!recover`) -- Typing proxy (user ↔ staff) configurable -- Configurable system messages (welcome / close) -- Configurable embed colors (user / staff / system) in hex -- Fine‑grained success/failure notification toggles -- Internationalization (multi-language + per-user preferences) – English & French shipped -- Structured error system (categorization, codes, TTL, auto-delete, translation) -- Error & language test commands (`!test_errors`, `!test_language`, `!test_all_errors`) -- In‑memory per-thread locks (basic race mitigation) -- Attachment download & relay -- Dynamic configuration validation (logs, features, Discord guild access) +A Discord modmail bot written in Rust that allows staff to manage support tickets via channels, with features like +message editing, internationalization, structured error handling, and more. +The bot can operate in single-server or dual-server modes, supports SQLite for data storage, and offers a range of +commands for staff to interact with users efficiently. --- -## Architecture -- `main.rs`: Initialization (DB, config, Serenity client, handlers, guild validation) -- `config.rs`: Load + structural validation + dependency injection (pool, error handler) -- `handlers/`: Discord event listeners (messages, reactions, members, interactions, moderation, ready, typing proxy) -- `commands/`: Prefix command logic (manual parsing) -- `db/` & `db/operations/`: SQLx abstraction (SQLite) – threads, messages, features, alerts -- `modules/`: Functional logic (message recovery, thread helpers) -- `utils/`: Utility helpers (conversion, message builder, content extraction, time, locks) -- `i18n/`: Dictionary system + multi-language resolution + fallback -- `errors/`: Strongly typed errors, dictionary mapping → localized embeds -- `features/`: Optional / experimental modules (e.g. poll) - -### Staff → User Reply Flow -1. Staff types `!reply` inside a thread channel -2. Parse content & attachments -3. Allocate message number (approx. atomic) → increment `next_message_number` -4. Send staff embed to thread + DM user -5. Persist in DB (`thread_messages`) with Discord IDs -6. Optional success notification - -### Thread Closing -- `!close`: Final DM (if user still guild member), mark closed & delete channel -- Scheduled closing with delay and optional silent mode (no user DM) -- `!close cancel`: Cancel a scheduled closing (prevents pending closure) -- `!force_close`: Delete orphaned channel OR residual untracked inbox channel - -### Message Editing -- `!edit `: Validate rights (author/staff), fetch IDs, edit thread + DM messages, update DB -- System message (audit) indicates change with deep link to edited message - ---- -## Configuration (config.toml) -Minimal example (adjust real IDs): -```toml -[bot] -token = "YOUR_TOKEN" -status = "DM FOR SUPPORT" -welcome_message = "We received your message! A staff member will reply soon." -close_message = "Thanks for contacting support! Your ticket is now closed." -typing_proxy_from_user = true -typing_proxy_from_staff = true -enable_logs = true -enable_features = true -logs_channel_id = 1404359738566133899 -features_channel_id = 1406940454859309076 - -[bot.mode] -type = "dual" -community_guild_id = 1209667980506892590 -staff_guild_id = 711880297245311856 - -[command] -prefix = "!" - -[thread] -inbox_category_id = 1376460196847505960 -embedded_message = true -user_message_color = "3d54ff" -staff_message_color = "ff3126" -system_message_color = "00ff00" -block_quote = true -time_to_close_thread = 5 -create_ticket_by_create_channel = true - -[notifications] -show_success_on_edit = false -show_partial_success_on_edit = true -show_failure_on_edit = true -show_success_on_reply = false -show_success_on_delete = false - -[logs] -show_log_on_edit = true - -[language] -default_language = "en" -auto_detect = true -fallback_language = "en" -supported_languages = ["en", "fr", "es", "de"] -[error_handling] -show_detailed_errors = false -log_errors = true -send_error_embeds = true -auto_delete_error_messages = true -error_message_ttl = 30 -``` - ---- -## Commands (Prefix configurable – default `!`) -General format: `!command [arguments]` - -| Command | Alias | Description | Example | -|----------------------------------|-------|-----------------------------------------------------------------------------------------------------------------|----------------------------------| -| new_thread | nt | Create a thread for a user | `!new_thread 123456789012345678` | -| reply | r | Reply (staff visible + DM) | `!reply Hello` | -| anonreply | ar | Anonymous reply | `!ar Thanks for reporting` | -| edit | e | Edit message number N | `!edit 5 Correction` | -| delete | — | Delete message N + renumber | `!delete 7` | -| add_staff <@user> | — | Add a staff member to the current ticket | `!add_staff @Moderator` | -| remove_staff <@user> | — | Remove a staff member from the current ticket | `!remove_staff @Moderator` | -| id [@user] | — | Show the numeric ID of a user (defaults to author if omitted) | `!id @User` | -| move | mv | Move thread to category (fuzzy) | `!move Resolved` | -| alert [cancel] | — | Set (or cancel) personal alert | `!alert` / `!alert cancel` | -| recover | — | Start async missing message recovery | `!recover` | -| close | — | Close current thread (DM user if still present) | `!close` | -| close cancel | — | Cancel a scheduled closing | `!close cancel` | -| force_close | — | Force delete orphan / leftover channel | `!force_close` | -| test_errors | — | Emit test error (db, discord, command, validation, message, thread, permission, user, channel, number, success) | `!test_errors db` | -| test_language | — | Set user language + trigger test error | `!test_language fr` | -| test_all_errors | — | Sequential demo of various errors | `!test_all_errors` | - -Notes: -- `move` uses Levenshtein matching (~50% distance threshold) on category names. - ---- -## Internationalization (i18n) -- Default + fallback language from config. -- Per-user preference via `!test_language ` (test command; a dedicated command could replace it later). -- Key namespaces: (reply.*, delete.*, new_thread.*, move.*, permission.*, success.*, close.*, alert.*, server.*, user.*, etc.). -- Missing translation → fallback language. - -### Adding a Language -1. Create file in `src/i18n/language/.rs` -2. Implement dictionary similar to `en.rs` -3. Add code to `supported_languages` + enum mapping - ---- -## Install & Run -### Prerequisites -- Rust (2024 edition toolchain) – see `rust-toolchain.toml` -- SQLite library (SQLx manages access) -- Create application + bot in [Discord Developer Portal] - -### Steps -```bash -git clone https://github.com/Akinator31/rustmail.git -cd rustmail -cp config.example.toml config.toml -cargo run --release -``` +## ⚠️ Warning ⚠️ -### Critical Variables -- Keep `bot.token` secret (do not commit). -- Enable required privileged intents (MESSAGE CONTENT, GUILD MEMBERS, PRESENCES) in the developer portal. +This is my first major project in Rust; while I have solid experience in C and other languages, I'm learning Rust as I +go — feedback and PRs are welcome. ---- -## Roadmap -Not yet determined. See GitHub Project. - ---- -## Message Conventions -- Staff → `staff_message_color` -- User → `user_message_color` -- System / success / errors → `system_message_color` (or derivative) -- `block_quote = true` applies quoted styling depending on builder implementation +Project documentation is currently being written. --- -## Maintenance -- Backups: copy `db/db.sqlite` -- New migration → restart binary (sqlx applies at startup via `init_database()`) -- Logs: currently stdout/stderr (improve later) ---- -## License -MIT. See LICENSE file. +## Getting Started ---- -## Contributions -Alpha phase: open descriptive issues (bugs, UX). PRs accepted after discussion. +- 🛠️ [Setting up the bot](https://github.com/Rustmail/rustmail/tree/main/docs/setup.md) +- 📦 [Commands](https://github.com/Rustmail/rustmail/tree/main/docs/commands.md) --- -## Final Disclaimer -Project is in **alpha**. APIs, structures, schemas and behaviors may change without backward compatibility. Do not use in critical environments or with sensitive data. Make frequent backups. ---- +## Support -Made with Rust 🦀 – contributions welcome. +If you need help, join the [Discord server][discord-invite] and ask for assistance in the #support channel. \ No newline at end of file diff --git a/config.example.toml b/config.example.toml index 7ca959b4..3f919976 100644 --- a/config.example.toml +++ b/config.example.toml @@ -37,13 +37,16 @@ show_success_on_delete = false [logs] show_log_on_edit = true +show_log_on_delete = true [language] default_language = "en" -auto_detect = true fallback_language = "en" supported_languages = ["en", "fr", "es", "de"] +[reminders] +embed_color = "ffb800" + [error_handling] show_detailed_errors = false log_errors = true diff --git a/docs/commands.md b/docs/commands.md new file mode 100644 index 00000000..5f9ea65d --- /dev/null +++ b/docs/commands.md @@ -0,0 +1,52 @@ +## Rustmail Commands + +This document provides a comprehensive list of commands available in Rustmail. All commands can be used as slash +commands or textual commands (with a configurable prefix for textual commands, default is `!`). + +### Table of Contents + +- [Slash Commands](#slash-commands) +- [Textual Commands](#textual-commands) + +### Slash Commands + +| Command | Description | Usage | +|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------| +| `/help` | Displays a list of available commands. | `/help` | +| `/new_thread` | Creates a new support ticket. | `/new_thread ` | +| `/close` | Closes the current ticket. You can schedule the closing with the `time_to_close` option. You can close the ticket silently with the `silent` option. And you can cancel a scheduled closure with `cancel` option. | `/close ` | +| `/force_close` | Closes an orphaned ticket (which the user are no longer on the discord server). | `/force_close` | +| `/reply` | Reply in a ticket channel. You can add an attachments to your message with `attachment` option. You can send your message as anonymous with the `anonymous` option. | `/reply ` | +| `/add_reminder` | Add a reminder that will ping you when the time is reached. You can set a custom content with the `content` option. | `/add_reminder