# Discord Channel To HTML Transcripts

PyPI Downloads GitHub Repo Commit Activity Last Commit Branch PyPI Version PyPI Python Versions

## Purpose A Python library for creating HTML transcripts of Discord channels. This is useful for logging, archiving, or sharing conversations from a Discord server. *The base code comes from [py-discord-html-transcripts](https://github.com/FroostySnoowman/py-discord-html-transcripts) and has been adapted and improved.* --- ## Preview
📸 Cliquez pour voir les aperçus / Click to see previews | | | |---|---| | ![Preview 1](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/1.png?raw=true) | ![Preview 2](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/2.png?raw=true) | | ![Preview 3](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/3.png?raw=true) | ![Preview 4](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/4.png?raw=true) | | ![Preview 5](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/5.png?raw=true) | ![Preview 6](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/6.png?raw=true) | | ![Preview 7](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/7.png?raw=true) | ![Preview 8](https://github.com/Xougui/DiscordTranscript/blob/main/screenshots/8.png?raw=true) |
--- ## 🇫🇷 Documentation en Français
🇫🇷 Documentation en Français ## Table des matières - [Prérequis](#prérequis) - [Installation](#installation) - [Utilisation](#utilisation) - [Exemples](#exemples) - [Paramètres](#paramètres) --- ## Prérequis - Python 3.10 ou plus récent - `discord.py` v2.4.0 ou plus récent (ou un fork compatible comme `nextcord` ou `disnake`) --- ## Installation Pour installer la librairie, exécutez la commande suivante : ```sh pip install DiscordTranscript ``` **NOTE :** Cette librairie est une extension pour `discord.py` et ne fonctionne pas de manière autonome. Vous devez avoir un bot `discord.py` fonctionnel pour l'utiliser. --- ## Utilisation Il existe trois méthodes principales pour exporter une conversation : `quick_export`, `export`, et `raw_export`. - `quick_export`: La manière la plus simple d'utiliser la librairie. Elle récupère l'historique du salon, génère la transcription, puis la publie directement dans le même salon. - `export`: La méthode la plus flexible. Elle permet de personnaliser la transcription avec plusieurs options. - `raw_export`: Permet de créer une transcription à partir d'une liste de messages que vous fournissez. --- ## Exemples ### Utilisation de base
Exemple ```python import discord import DiscordTranscript from discord.ext import commands intents = discord.Intents.default() intents.members = True intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) @bot.command() async def save(ctx: commands.Context): await DiscordTranscript.quick_export(ctx.channel, bot=bot) bot.run("VOTRE_TOKEN") ```
### Utilisation personnalisable
Exemple ```python import io import discord import DiscordTranscript from discord.ext import commands # ... (initialisation du bot) @bot.command() async def save_custom(ctx: commands.Context): transcript = await DiscordTranscript.export( ctx.channel, limit=100, tz_info="Europe/Paris", military_time=True, bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"transcript-{ctx.channel.name}.html", ) await ctx.send(file=transcript_file) ```
### Utilisation brute (raw)
Exemple ```python import io import discord import DiscordTranscript from discord.ext import commands # ... (initialisation du bot) @bot.command() async def save_purged(ctx: commands.Context): deleted_messages = await ctx.channel.purge(limit=50) transcript = await DiscordTranscript.raw_export( ctx.channel, messages=deleted_messages, bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"purged-transcript-{ctx.channel.name}.html", ) await ctx.send("Voici la transcription des messages supprimés :", file=transcript_file) ```
### Intégrer les pièces jointes dans le HTML
Exemple ```python import io import discord import DiscordTranscript from DiscordTranscript.construct.attachment_handler import AttachmentToDataURIHandler from discord.ext import commands # ... (initialisation du bot) @bot.command() async def save_with_embedded_attachments(ctx: commands.Context): # Optionnel: personnaliser l'optimisation des images et l'encodage DataURI handler = AttachmentToDataURIHandler( only_expiring=True, # Convertit seulement les liens Discord expirants optimize_images=True, # Redimensionne et compresse les images max_image_dimension=1280, # Dimension maximale (px) quality=80, # Qualité de compression (1-100) ) transcript = await DiscordTranscript.export( ctx.channel, attachment_handler=handler, bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"transcript-{ctx.channel.name}.html", ) await ctx.send(file=transcript_file) ```
### Personnaliser les couleurs du thème (Custom Colors)
Exemple Vous pouvez générer un fichier modèle prêt à l'emploi contenant toutes les variables de couleurs modifiables : ```python import io import discord import DiscordTranscript from discord.ext import commands # Génère un fichier modèle de configuration des couleurs (si besoin) DiscordTranscript.generate_custom_colors_file("my_colors.txt") @bot.command() async def save_themed(ctx: commands.Context): transcript = await DiscordTranscript.export( ctx.channel, custom_colors_file="my_colors.txt", bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"transcript-{ctx.channel.name}.html", ) await ctx.send(file=transcript_file) ``` Un exemple de fichier est également disponible dans [`examples/custom_colors.example.txt`](examples/custom_colors.example.txt).
--- ## Paramètres Voici une liste des paramètres que vous pouvez utiliser dans les fonctions `export()` et `raw_export()` pour personnaliser vos transcriptions. | Paramètre | Type | Description | Défaut | | --- | --- | --- | --- | | `messages` | `List[discord.Message]` | Une liste de messages à utiliser pour la transcription. | `None` | | `limit` | `int` | Le nombre maximum de messages à récupérer. | `None` (illimité) | | `before` | `datetime.datetime` | Récupère les messages avant cette date. | `None` | | `after` | `datetime.datetime` | Récupère les messages après cette date. | `None` | | `tz_info` | `str` | Le fuseau horaire à utiliser pour les horodatages. Doit être un nom de la base de données TZ (ex: "Europe/Paris"). | `"UTC"` | | `military_time` | `bool` | Si `True`, utilise le format 24h. Si `False`, utilise le format 12h (AM/PM). | `True` | | `fancy_times` | `bool` | Si `True`, utilise des horodatages relatifs (ex: "Aujourd'hui à..."). Si `False`, affiche la date complète. | `True` | | `bot` | `discord.Client` | L'instance de votre bot. Nécessaire pour résoudre les informations des utilisateurs qui ont quitté le serveur. | `None` | | `guild`| `discord.Guild` | L'instance de votre serveur. Nécessaire pour résoudre les informations des membres (rôles, couleurs, etc.). | `None` | | `attachment_handler` | `AttachmentHandler` | Un gestionnaire pour contrôler la façon dont les pièces jointes sont traitées. Voir l'exemple [Intégrer les pièces jointes dans le HTML](#intégrer-les-pièces-jointes-dans-le-html). | `None` (les liens des pièces jointes pointent vers le CDN de Discord) | | `custom_colors_file` | `str \| Path \| os.PathLike` | Le chemin vers un fichier texte de configuration des couleurs personnalisées. | `None` | | `language` | `str` | La langue à utiliser pour la transcription. | `"en"` | **Note :** Le paramètre `messages` est uniquement disponible pour la fonction `raw_export()`. ### Exemples de paramètres Voici comment vous pouvez utiliser les paramètres pour personnaliser vos transcriptions. - **`messages`**: Pour créer une transcription à partir d'une liste de messages que vous avez déjà. (Uniquement pour `raw_export`) ```python # Récupère les 50 derniers messages my_messages = await ctx.channel.history(limit=50).flatten() transcript = await DiscordTranscript.raw_export( ctx.channel, messages=my_messages, # Fournit la liste de messages bot=bot, ) ``` - **`limit`**: Pour limiter le nombre de messages à 100. ```python transcript = await DiscordTranscript.export( ctx.channel, limit=100, # Limite à 100 messages bot=bot, ) ``` - **`before` et `after`**: Pour exporter les messages d'une période spécifique. ```python import datetime transcript = await DiscordTranscript.export( ctx.channel, # Exportera les messages envoyés entre le 10 et le 20 juin 2023 after=datetime.datetime(2023, 6, 10), # Après le 10 juin 2023 before=datetime.datetime(2023, 6, 20), # Avant le 20 juin 2023 bot=bot, ) ``` - **`tz_info`**: Pour afficher les heures en fonction d'un fuseau horaire (ex: heure de Paris). ```python transcript = await DiscordTranscript.export( ctx.channel, tz_info="Europe/Paris", # Fuseau horaire de Paris bot=bot, ) ``` - **`military_time`**: Pour utiliser le format 12h (AM/PM) au lieu du format 24h. ```python transcript = await DiscordTranscript.export( ctx.channel, military_time=False, # Affiche 1:00 PM au lieu de 13:00 bot=bot, ) ``` - **`fancy_times`**: Pour afficher la date complète au lieu de "Aujourd'hui à...". ```python transcript = await DiscordTranscript.export( ctx.channel, fancy_times=False, # Affiche la date complète (ex: 23/09/2025) bot=bot, ) ``` - **`bot`**: Pour résoudre les informations des utilisateurs (même s'ils ont quitté le serveur). ```python transcript = await DiscordTranscript.export( ctx.channel, bot=bot, # Fournit l'instance du bot ) ``` - **`guild`**: Pour vous assurer que les rôles et les couleurs des membres sont corrects. ```python transcript = await DiscordTranscript.export( ctx.channel, guild=ctx.guild, # Fournit l'instance du serveur bot=bot, ) ``` - **`attachment_handler`**: Pour intégrer les pièces jointes directement dans le fichier HTML (avec options de compression et d'optimisation des images). ```python from DiscordTranscript.construct.attachment_handler import AttachmentToDataURIHandler transcript = await DiscordTranscript.export( ctx.channel, # Intègre les pièces jointes en tant que Data URIs avec optimisation d'images attachment_handler=AttachmentToDataURIHandler( only_expiring=True, # Ne convertit que les URLs Discord expirantes optimize_images=True, # Compresse et redimensionne les images max_image_dimension=1280, # Taille max (px) quality=80 # Qualité (1-100) ), bot=bot, ) ```
--- ## 🇬🇧 English Documentation
🇬🇧 English Documentation ## Table of Contents - [Prerequisites](#prerequisites-en) - [Installation](#installation-en) - [Usage](#usage-en) - [Examples](#examples-en) - [Parameters](#parameters-en) --- ## Prerequisites - Python 3.10 or newer - `discord.py` v2.4.0 or newer (or a compatible fork like `nextcord` or `disnake`) --- ## Installation To install the library, run the following command: ```sh pip install DiscordTranscript ``` **NOTE:** This library is an extension for `discord.py` and does not work standalone. You must have a functional `discord.py` bot to use it. --- ## Usage There are three main methods for exporting a conversation: `quick_export`, `export`, and `raw_export`. - `quick_export`: The simplest way to use the library. It retrieves the channel's history, generates the transcript, and then publishes it directly in the same channel. - `export`: The most flexible method. It allows you to customize the transcript with several options. - `raw_export`: Allows you to create a transcript from a list of messages you provide. --- ## Examples ### Basic Usage
Example ```python import discord import DiscordTranscript from discord.ext import commands intents = discord.Intents.default() intents.members = True intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) @bot.command() async def save(ctx: commands.Context): await DiscordTranscript.quick_export(ctx.channel, bot=bot) bot.run("YOUR_TOKEN") ```
### Customizable Usage
Example ```python import io import discord import DiscordTranscript from discord.ext import commands # ... (bot initialization) @bot.command() async def save_custom(ctx: commands.Context): transcript = await DiscordTranscript.export( ctx.channel, limit=100, tz_info="America/New_York", military_time=True, bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"transcript-{ctx.channel.name}.html", ) await ctx.send(file=transcript_file) ```
### Raw Usage
Example ```python import io import discord import DiscordTranscript from discord.ext import commands # ... (bot initialization) @bot.command() async def save_purged(ctx: commands.Context): deleted_messages = await ctx.channel.purge(limit=50) transcript = await DiscordTranscript.raw_export( ctx.channel, messages=deleted_messages, bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"purged-transcript-{ctx.channel.name}.html", ) await ctx.send("Here is the transcript of the deleted messages:", file=transcript_file) ```
### Embedding Attachments in HTML
Example ```python import io import discord import DiscordTranscript from DiscordTranscript.construct.attachment_handler import AttachmentToDataURIHandler from discord.ext import commands # ... (bot initialization) @bot.command() async def save_with_embedded_attachments(ctx: commands.Context): # Optional: Customize image optimization & DataURI encoding handler = AttachmentToDataURIHandler( only_expiring=True, # Convert only expiring Discord URLs to Data URIs optimize_images=True, # Resize & compress images before Base64 encoding max_image_dimension=1280, # Maximum width/height in pixels quality=80, # Compression quality (1-100) ) transcript = await DiscordTranscript.export( ctx.channel, attachment_handler=handler, bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"transcript-{ctx.channel.name}.html", ) await ctx.send(file=transcript_file) ```
### Customizing Theme Colors (Custom Colors)
Example You can generate a ready-to-use template file containing all customizable color variables: ```python import io import discord import DiscordTranscript from discord.ext import commands # Generate a color configuration template file (if needed) DiscordTranscript.generate_custom_colors_file("my_colors.txt") @bot.command() async def save_themed(ctx: commands.Context): transcript = await DiscordTranscript.export( ctx.channel, custom_colors_file="my_colors.txt", bot=bot, ) if transcript is None: return transcript_file = discord.File( io.BytesIO(transcript.encode()), filename=f"transcript-{ctx.channel.name}.html", ) await ctx.send(file=transcript_file) ``` An example template is also available in [`examples/custom_colors.example.txt`](examples/custom_colors.example.txt).
--- ## Parameters Here is a list of parameters you can use in the `export()` and `raw_export()` functions to customize your transcripts. | Parameter | Type | Description | Default | | --- | --- | --- | --- | | `messages` | `List[discord.Message]` | A list of messages to use for the transcript. | `None` | | `limit` | `int` | The maximum number of messages to retrieve. | `None` (unlimited) | | `before` | `datetime.datetime` | Retrieves messages before this date. | `None` | | `after` | `datetime.datetime` | Retrieves messages after this date. | `None` | | `tz_info` | `str` | The timezone to use for timestamps. Must be a TZ database name (e.g., "America/New_York"). | `"UTC"` | | `military_time` | `bool` | If `True`, uses 24h format. If `False`, uses 12h format (AM/PM). | `True` | | `fancy_times` | `bool` | If `True`, uses relative timestamps (e.g., "Today at..."). If `False`, displays the full date. | `True` | | `bot` | `discord.Client` | Your bot's instance. Necessary to resolve user information for members who have left the server. | `None` | | `guild`| `discord.Guild` | Your server's instance. Necessary to resolve member information (roles, colors, etc.). | `None` | | `attachment_handler`| `AttachmentHandler` | A handler to control how attachments are processed. See the [Embedding Attachments in HTML](#embedding-attachments-in-html) example. | `None` (attachment links point to Discord's CDN) | | `custom_colors_file` | `str \| Path \| os.PathLike` | Path to a custom colors configuration text file. | `None` | | `language` | `str` | The language to use for the transcript. | `"en"` | **Note:** The `messages` parameter is only available for the `raw_export()` function. ### Parameter Examples Here’s how you can use the parameters to customize your transcripts. - **`messages`**: To create a transcript from a list of messages you already have. (Only for `raw_export`) ```python # Fetches the last 50 messages my_messages = await ctx.channel.history(limit=50).flatten() transcript = await DiscordTranscript.raw_export( ctx.channel, messages=my_messages, # Provide the list of messages bot=bot, ) ``` - **`limit`**: To limit the number of messages to 100. ```python transcript = await DiscordTranscript.export( ctx.channel, limit=100, # Limit to 100 messages bot=bot, ) ``` - **`before` and `after`**: To export messages from a specific period. ```python import datetime transcript = await DiscordTranscript.export( ctx.channel, # Will export messages sent between June 10th and June 20th, 2023 after=datetime.datetime(2023, 6, 10), # After June 10, 2023 before=datetime.datetime(2023, 6, 20), # Before June 20, 2023 bot=bot, ) ``` - **`tz_info`**: To display times in a specific timezone (e.g., New York time). ```python transcript = await DiscordTranscript.export( ctx.channel, tz_info="America/New_York", # New York timezone bot=bot, ) ``` - **`military_time`**: To use 12-hour format (AM/PM) instead of 24-hour format. ```python transcript = await DiscordTranscript.export( ctx.channel, military_time=False, # Displays 1:00 PM instead of 13:00 bot=bot, ) ``` - **`fancy_times`**: To display the full date instead of "Today at...". ```python transcript = await DiscordTranscript.export( ctx.channel, fancy_times=False, # Displays the full date (e.g., 09/23/2025) bot=bot, ) ``` - **`bot`**: To resolve user information (even if they have left the server). ```python transcript = await DiscordTranscript.export( ctx.channel, bot=bot, # Provide the bot instance ) ``` - **`guild`**: To ensure member roles and colors are correct. ```python transcript = await DiscordTranscript.export( ctx.channel, guild=ctx.guild, # Provide the guild instance bot=bot, ) ``` - **`attachment_handler`**: To embed attachments directly into the HTML file (with image compression and optimization options). ```python from DiscordTranscript.construct.attachment_handler import AttachmentToDataURIHandler transcript = await DiscordTranscript.export( ctx.channel, # Embeds attachments as Data URIs with image optimization attachment_handler=AttachmentToDataURIHandler( only_expiring=True, # Convert only expiring Discord URLs optimize_images=True, # Compress and resize images max_image_dimension=1280, # Max dimension (px) quality=80 # Quality (1-100) ), bot=bot, ) ```