discord-html-transcripts

repository·master·Indexed 43 days ago

https://github.com/itzderock/discord-html-transcripts

A Node.js module for generating visually appealing HTML transcripts of Discord channels for discord.js v14 and v15. It supports Discord markdown, embeds, system messages, slash commands, and attachments with built-in XSS protection. Features include automatic message fetching via createTranscript, custom message generation via generateFromMessages, and optional image compression using the sharp library.

Tokens
7.1K
Snippets
22
Records
29
Agent score
53%

What's inside discord-html-transcripts

  1. Overview of discord-html-transcripts

    master

    discord-html-transcripts is a Node.js module designed to generate visually appealing HTML transcripts from Discord data.

    Key features include:

    • Markdown Support: Processes Discord-specific markdown such as **bold**, _italics_, and ~~strikethroughs~~.
    • Discord Styling: Formats attachments and embeds to mimic the Discord user interface.
    • Security: Includes built-in XSS protection to prevent the insertion of arbitrary HTML tags by users.
  2. Compress images in transcripts using sharp

    master

    When saveImages is set to true, images are stored as-is. To reduce the resulting file size, install the sharp module and use the TranscriptImageDownloader within the resolveImageSrc callback.

    This allows you to set a maximum size and define compression quality/format (e.g., converting to WebP).

    // Requires 'sharp' to be installed
    callbacks: {
      resolveImageSrc: new TranscriptImageDownloader()
        .withMaxSize(5120) // 5MB in KB
        .withCompression(40, true) // 40% quality, convert to webp
        .build(),
    }
  3. Configure transcript generation options

    master

    Both createTranscript and generateFromMessages accept an optional configuration object.

    Available Options:

    • limit: Max amount of messages to fetch. Use -1 to fetch recursively.
    • returnType: 'attachment' (default), 'buffer', or 'string'. Use the ExportReturnType enum for type safety.
    • filename: Name of the file (only valid if returnType is 'attachment').
    • saveImages: If true, downloads all images and embeds them in the HTML. This allows viewing images even after they are deleted from Discord, but increases file size.
    • footerText: Custom text for the footer. Use {number} for the message count and {s} for pluralization.
    • poweredBy: Boolean to include/exclude the "Powered by discord-html-transcripts" footer.
    • hydrate: Boolean to determine if the HTML should be hydrated server-side.
    • filter: A function (message) => boolean to include or exclude specific messages (e.g., (message) => !message.author.bot).
    • callbacks: An object to provide custom resolvers for Discord entities:
      • resolveChannel: (channelId: string) => Awaitable<Channel | null>
      • resolveUser: (userId: string) => Awaitable<User | null>
      • resolveRole: (roleId: string) => Awaitable<Role | null>
      • resolveImageSrc: (attachment: APIAttachment, message: APIMessage) => Awaitable<string | null | undefined>
    const attachment = await discordTranscripts.createTranscript(channel, {
        limit: -1,
        returnType: 'attachment',
        filename: 'transcript.html',
        saveImages: false,
        footerText: "Exported {number} message{s}",
        callbacks: {
          resolveChannel: (channelId) => /* logic */,
          resolveUser: (userId) => /* logic */,
          resolveRole: (roleId) => /* logic */,
          resolveImageSrc: (attachment, message) => /* logic */
        },
        poweredBy: true,
        hydrate: true,
        filter: (message) => !message.author.bot
    });
  4. Configure image saving and resolution

    master

    When generating transcripts, you can control how images/attachments are handled using the following options in generateFromMessages or createTranscript:

    • saveImages: A boolean. If true, the library will attempt to download images and embed them in the transcript.
    • callbacks.resolveImageSrc: A function used to determine the URL of an image.

    Important: If you set saveImages: true, the library uses a default TranscriptImageDownloader unless you provide your own resolveImageSrc callback. If both are provided, resolveImageSrc takes precedence and a warning is logged.

  5. Generate a transcript from custom messages with generateFromMessages

    master

    Use generateFromMessages when you want to provide your own specific set of messages for the transcript instead of having the library fetch them automatically from a channel. This allows for finer control over exactly which messages are included in the output.

    Parameters:

    • messages: An array of discord.js Message objects or a Collection<string, Message>.
    • channel: A TextBasedChannel (used to extract metadata like guild name, icon, and channel name).
    • options: A GenerateFromMessagesOptions object to configure the output.

    By default, the function returns an AttachmentBuilder which can be sent directly to a Discord channel using channel.send({ files: [attachment] }).

    import * as discordTranscripts from "discord-html-transcripts";
    import { Collection, Message } from "discord.js";
    
    const messages = new Collection<string, Message>();
    const channel = /* your channel object */;
    
    // Fill the messages collection with the desired messages
    
    const transcript = await discordTranscripts.generateFromMessages(
        messages, 
        channel, 
        { /* options */ }
    );
    
    // Send the resulting attachment to the channel
    await channel.send({
        files: [transcript]
    });
  6. Generate a transcript from custom messages

    master

    Use generateFromMessages(messages, channel, options?) if you already have a collection of messages and do not want the library to fetch them from Discord.

    • messages: Must be a Collection<string, Message> or Message[].
    • channel: The channel used for metadata like the ticket name, guild icon, and guild name.

    The method must be awaited and returns the transcript as configured in the options.

    const discordTranscripts = require('discord-html-transcripts');
    
    const messages = someWayToGetMessages(); // Collection<string, Message> or Message[]
    const channel = someWayToGetChannel(); // Used for metadata
    
    // Must be awaited
    const attachment = await discordTranscripts.generateFromMessages(messages, channel);
    
    channel.send({
      files: [attachment],
    });
  7. Use createTranscript to generate a channel transcript

    master

    The createTranscript function fetches messages from a specified TextBasedChannel and generates an HTML transcript. By default, it returns an AttachmentBuilder object, which can be passed directly to message.reply or other discord.js methods in the files array.

    Note that createTranscript is an asynchronous function and must be awaited.

    const discordTranscripts = require("discord-html-transcripts");
    
    client.on('messageCreate', async (message) => {
        if (message.content === "!transcript") {
            // Fetches messages and returns an AttachmentBuilder
            const transcript = await discordTranscripts.createTranscript(
                message.channel,
                {
                    saveImages: true,
                    footerText: "Saved {number} message{s}"
                }
            );
    
            // Send the transcript directly to the channel
            await message.reply({
                content: "Here's your transcript!",
                files: [transcript]
            });
        }
    });
  8. Generate a transcript using the built-in message fetcher

    master

    Use createTranscript(channel, options?) to automatically fetch messages from a Discord channel and generate an HTML transcript. This method is ideal when you want the library to handle the message fetching logic for you. The method must be awaited and returns an attachment (default), a buffer, or a string depending on your configuration.

    Note: This module is designed to work with discord.js v14/v15 only. For v13 support, use version 2.X.X.

    const discordTranscripts = require('discord-html-transcripts');
    
    const channel = message.channel; // Must be a TextChannel
    
    // Must be awaited
    const attachment = await discordTranscripts.createTranscript(channel);
    
    channel.send({
      files: [attachment],
    });
  9. Configure transcript generation options

    master

    When using discord-html-transcripts, you can pass an options object to control the output format, appearance, and content. The primary configuration types are GenerateFromMessagesOptions and CreateTranscriptOptions.

    // Example of configuration options
    const options: CreateTranscriptOptions<ExportReturnType.Buffer> = {
      returnType: ExportReturnType.Buffer,
      saveImages: true,
      limit: 100,
      filter: (msg) => !msg.system,
      filename: 'my-transcript.html'
    };
  10. Configure createTranscript parameters

    master

    The createTranscript function accepts two arguments:

    1. channel: TextBasedChannel: The channel to fetch messages from. This can be a TextChannel, NewsChannel, ThreadChannel, or VoiceChannel (as defined in discord.js).
    2. options: CreateTranscriptOptions: An optional configuration object.

    Available Options

    OptionTypeDescription
    limitnumberThe maximum number of messages to fetch.
    filter(message: Message<boolean>) => booleanA predicate function called for each message. If it returns false, the message is excluded from the transcript.
    saveImagesboolean(Inherited from generatefrommessages) Whether to include images in the transcript.
    footerTextstring(Inherited from generatefrommessages) Custom text for the transcript footer. Supports {number} placeholder.
    // Signature
    createTranscript(channel, (options = {}));
  11. Configure GenerateFromMessagesOptions

    master

    The options object allows you to customize the transcript generation process.

    Return Type

    options.returnType: Determines the format of the returned data.

    • 'buffer': Returns the HTML data as a Buffer.
    • 'string': Returns the HTML data as a string.
    • 'attachment': Returns an AttachmentBuilder (Default).

    File and Content Customization

    • options.filename: The name of the output file (only used if returnType is 'attachment'). Default: transcript-{channel id}.html.
    • options.saveImages: A boolean. If true, the library downloads all image attachments and embeds them directly in the HTML. This prevents broken images if the original Discord attachments are deleted, but significantly increases file size and may hit Discord's upload limits.
    • options.footerText: Custom text for the transcript footer. Supports placeholders:
      • {number}: Total number of messages exported.
      • {s}: Adds an 's' if the number is > 0 (for pluralization).
    • options.poweredBy: A boolean to show or hide the "Powered by discord-html-transcripts" footer (Default: true).

    Custom Resolvers (Callbacks)

    If your bot uses specific caching or custom fetching logic, you can provide custom callback functions via options.callbacks to resolve Discord entities mentioned in the transcript:

    • resolveChannel: (channelId: string) => Awaitable<Channel | null>
    • resolveUser: (userId: string) => Awaitable<User | null>
    • resolveRole: (roleId: string) => Awaitable<Role | null>
    const attachment = await discordTranscripts.generateFromMessages(
        messages,
        channel,
        {
            returnType: 'attachment', // 'buffer' | 'string' | 'attachment'
            filename: 'transcript.html',
            saveImages: false,
            footerText: "Exported {number} message{s}",
            poweredBy: true,
            callbacks: {
                resolveChannel: async (channelId) => await channel.client.channels.fetch(channelId),
                resolveUser: async (userId) => await channel.client.users.fetch(userId),
                resolveRole: async (roleId) => await channel.guild.roles.fetch(roleId)
            }
        }
    );