Skip to content

wickstudio/discord.js-html-transcript

Repository files navigation

discord.js-html-transcript

discord.js-html-transcript

Generate pixel-perfect, native-looking Discord HTML transcripts.

npm version npm downloads Discord GitHub stars License

πŸ“– Official Documentation β€’ πŸ–₯️ Live Demo

Installation β€’ Quick Start β€’ Configuration β€’ API Reference


✨ What's New in v4

This package is a completely modernized fork of discord-html-transcripts by ItzDerock, rebuilt from the ground up with a native Discord UI that is indistinguishable from the real thing.

πŸ†• New Features

Feature Description
πŸ”€ Forwarded Messages Full support for Discord's forwarded message format with origin info
πŸŽ™οΈ Voice Messages Waveform visualization with play button, duration, and speed controls
πŸ“Š Polls / Voting Native poll rendering with answer options, vote counts, and progress bars
🏷️ Server Tags APP badges, role icons, and server tag badges on user profiles
πŸ”˜ Buttons & Select Menus Primary, secondary, success, danger, and link button styles + dropdown menus
πŸ”— Invite Link Previews Rich invite cards with server icon, member counts, and join button
πŸ–ΌοΈ Image Preview Lightbox Click any image to open a full-screen lightbox overlay
πŸ” Message Search Built-in search bar to find messages within transcripts
🧡 Thread Previews Thread starter messages with preview boxes and participant info
πŸ“Ž File Attachments Native-styled file attachment cards with download buttons
🎨 ANSI Code Blocks Full ANSI escape sequence rendering with colors and formatting
πŸ“± Fully Responsive Mobile-first responsive design that works perfectly on all screen sizes
πŸ“Œ Sticky Header Channel header stays visible while scrolling, just like Discord
βš™οΈ Configurable Features Toggle search, image preview, spoiler reveal, and more on/off
πŸ’Ύ Granular Asset Saving Fine-grained control over which remote assets (images, avatars, emojis, etc.) are preserved

🎨 UI Improvements

  • Redesigned button and select menu components matching Discord's current design
  • Modern dark theme background (#070709) matching native Discord
  • Improved embed border styling with subtle transparency
  • Enhanced markdown rendering (headings, lists, block quotes, code blocks)
  • Responsive image galleries with multi-image grid layouts
  • Native vote/poll UI with interactive styling
  • Voice message capsule with amplitude-proportional waveform bars
  • Custom file attachment cards with file type icons

πŸ“¦ Installation

# npm
npm install discord.js-html-transcript

# pnpm
pnpm add discord.js-html-transcript

# yarn
yarn add discord.js-html-transcript

Requirements: Node.js 16+ and discord.js v14 or v15


πŸ› οΈ Get Started

Using the built-in message fetcher

const discordTranscripts = require('discord.js-html-transcript');

const channel = message.channel;

const attachment = await discordTranscripts.createTranscript(channel);

channel.send({
  files: [attachment],
});

Using your own messages

const discordTranscripts = require('discord.js-html-transcript');

const messages = await channel.messages.fetch({ limit: 100 });

const attachment = await discordTranscripts.generateFromMessages(messages, channel);

channel.send({
  files: [attachment],
});

TypeScript

import * as discordTranscripts from 'discord.js-html-transcript';

const attachment = await discordTranscripts.createTranscript(channel, {
  returnType: discordTranscripts.ExportReturnType.Attachment,
  filename: `transcript-${channel.id}.html`,
});

βš™οΈ Configuration

Both createTranscript and generateFromMessages accept an options object. All options are optional - sensible defaults are used when omitted.

const attachment = await discordTranscripts.createTranscript(channel, {
  // ── Output ────────────────────────────────────────────────
  returnType: 'attachment',       // 'buffer' | 'string' | 'attachment'
  filename: 'transcript.html',   // output filename (when returnType is 'attachment')

  // ── Message Fetching (createTranscript only) ──────────────
  limit: -1,                     // max messages to fetch (-1 = all)
  filter: (message) => true,     // filter which messages to include

  // ── Asset Preservation ────────────────────────────────────
  saveImages: false,             // legacy: save image attachments as data URIs
  saveAssets: false,             // save ALL remote assets as data URIs
  assets: {
    attachments: false,          // images, videos, audio, and files
    embeds: false,               // embed media + author/footer icons
    components: false,           // media gallery items, thumbnails, component files
    avatars: false,              // user avatars
    emojis: false,               // custom emoji + twemoji assets
    guildIcons: false,           // header + favicon guild icon
    inviteIcons: false,          // invite preview server icons
    roleIcons: false,            // highest-role icon images
    serverTagBadges: false,      // server tag badge images
  },

  // ── Feature Toggles ───────────────────────────────────────
  features: {
    search: true,                // built-in message search UI
    imagePreview: true,          // click-to-open image lightbox
    spoilerReveal: true,         // click spoilers to reveal
    messageLinks: true,          // reply click-to-scroll behavior
    profileBadges: true,         // APP badges, server tags, role icons
    embedTweaks: true,           // client-side embed border/style fixes
  },

  // ── Appearance ────────────────────────────────────────────
  footerText: 'Exported {number} message{s}.',
  poweredBy: true,               // show "Powered by" footer credit
  favicon: 'guild',             // 'guild' or a custom URL string
  hydrate: false,                // server-side hydrate the HTML

  // ── Callbacks ─────────────────────────────────────────────
  callbacks: {
    resolveChannel: (channelId) => channel.client.channels.fetch(channelId),
    resolveUser:    (userId)    => channel.client.users.fetch(userId),
    resolveRole:    (roleId)    => channel.guild?.roles.fetch(roleId),
    resolveInvite:  (code)      => /* return { name, icon, online, members, url } */,
    resolveImageSrc: (attachment, message) => /* return data URI or URL */,
    resolveAssetSrc: (asset)    => /* return data URI or URL */,
  },
});

Image Compression

Install sharp as a dev dependency to enable image compression:

npm install sharp --save-dev
const { TranscriptImageDownloader } = require('discord.js-html-transcript');

const attachment = await discordTranscripts.createTranscript(channel, {
  callbacks: {
    resolveImageSrc: new TranscriptImageDownloader()
      .withMaxSize(5120) // 5MB max per image (in KB)
      .withCompression(40, true) // 40% quality, convert to webp
      .build(),
  },
});

Saving All Assets (Offline Transcripts)

For transcripts that survive Discord CDN expiration:

const { TranscriptAssetDownloader } = require('discord.js-html-transcript');

const attachment = await discordTranscripts.createTranscript(channel, {
  saveAssets: true,
  // Or for fine-grained control:
  assets: {
    attachments: true,
    embeds: true,
    avatars: true,
    emojis: true,
    guildIcons: true,
  },
  callbacks: {
    resolveAssetSrc: new TranscriptAssetDownloader()
      .withMaxSize(10240) // 10MB per asset
      .build(),
  },
});

πŸ–ΌοΈ Preview

Messages & Attachments

Normal Image Multi Images File Attachment
Normal Image Multi Images File

Forwarded Messages & Reactions

Forwarded Image Forwarded + Reactions
Forwarded Forwarded Reactions

Polls, Threads & Mentions

Poll Thread Mentions
Poll Thread Mentions

Buttons, Select Menus & Slash Commands

Buttons & Select Menu Slash Command & Voice
Buttons Slash

Embeds

Embed 1 Embed 2 Embed 3
Embed Embed Embed

Links & Invites

Links Invite Preview
Links Invite

Markdown Formatting

Basic Formatting Code Blocks Headings
Basic Code Headings
Block Quotes Lists ANSI Styling
Quotes Lists ANSI

πŸ“š API Reference

createTranscript(channel, options?)

Fetches messages from a channel and generates an HTML transcript.

Parameter Type Description
channel TextBasedChannel The channel to export
options CreateTranscriptOptions Configuration options (see above)

Returns: Promise<AttachmentBuilder | Buffer | string>

const transcript = await discordTranscripts.createTranscript(channel, {
  limit: 500,
  filter: (msg) => !msg.author.bot,
  returnType: 'attachment',
});

generateFromMessages(messages, channel, options?)

Generates a transcript from a pre-fetched array of messages.

Parameter Type Description
messages Message[] | Collection<string, Message> Messages to include
channel Channel Channel for header/guild info
options GenerateFromMessagesOptions Configuration options (see above)

Returns: Promise<AttachmentBuilder | Buffer | string>

const messages = await channel.messages.fetch({ limit: 100 });
const transcript = await discordTranscripts.generateFromMessages(messages, channel);

Return Types

Use the ExportReturnType enum for type-safe return values:

import { ExportReturnType } from 'discord.js-html-transcript';

// Returns a Buffer
const buffer = await discordTranscripts.createTranscript(channel, {
  returnType: ExportReturnType.Buffer,
});

// Returns a string
const html = await discordTranscripts.createTranscript(channel, {
  returnType: ExportReturnType.String,
});

// Returns an AttachmentBuilder (default)
const attachment = await discordTranscripts.createTranscript(channel, {
  returnType: ExportReturnType.Attachment,
});

Asset Classes

TranscriptImageDownloader

const downloader = new TranscriptImageDownloader()
  .withMaxSize(5120) // max file size in KB
  .withCompression(40, true) // quality %, convert to webp
  .build(); // returns a resolveImageSrc callback

TranscriptAssetDownloader

const downloader = new TranscriptAssetDownloader()
  .withMaxSize(10240) // max file size in KB
  .build(); // returns a resolveAssetSrc callback

πŸ“– Full Example

const discordTranscripts = require('discord.js-html-transcript');
const { TranscriptAssetDownloader } = require('discord.js-html-transcript');

client.on('messageCreate', async (message) => {
  if (message.content === '!transcript') {
    const transcript = await discordTranscripts.createTranscript(message.channel, {
      returnType: 'attachment',
      filename: `transcript-${message.channel.id}.html`,
      limit: -1,
      assets: {
        attachments: true,
        embeds: true,
        avatars: true,
        emojis: true,
        guildIcons: true,
        inviteIcons: true,
        roleIcons: true,
        serverTagBadges: true,
      },
      features: {
        search: true,
        imagePreview: true,
        spoilerReveal: true,
        messageLinks: true,
        profileBadges: true,
        embedTweaks: true,
      },
      callbacks: {
        resolveAssetSrc: new TranscriptAssetDownloader().withMaxSize(10240).build(),
      },
      footerText: 'Exported {number} message{s}.',
      poweredBy: true,
    });

    await message.reply({
      content: 'πŸ“„ Here is your transcript!',
      files: [transcript],
    });
  }
});

πŸ†š Comparison with Original

Feature discord-html-transcripts discord.js-html-transcript
Basic Messages & Embeds βœ… βœ…
Forwarded Messages ❌ βœ…
Voice Messages ❌ βœ…
Polls / Voting ❌ βœ…
Server Tags & Role Icons ❌ βœ…
Buttons & Select Menus (Modern) ❌ βœ…
Discord Invite Previews ❌ βœ…
Image Preview Lightbox ❌ βœ…
Message Search ❌ βœ…
ANSI Code Block Styling ❌ βœ…
Thread Preview Cards ❌ βœ…
Fully Responsive Mobile UI ❌ βœ…
Sticky Channel Header ❌ βœ…
Feature Toggle System ❌ βœ…
Granular Asset Saving ❌ βœ…
Native File Attachment Cards ❌ βœ…
Image Compression (sharp) ❌ βœ…
Multi-Image Gallery Grid ❌ βœ…

🀝 Credits

This package is built upon the excellent foundation of discord-html-transcripts by ItzDerock. Original styles powered by @derockdev/discord-components.

All new features, UI modernization, mobile responsiveness, and component redesigns by Wick Studio.


πŸ’¬ Support


πŸ“œ License

This project is licensed under the Apache License 2.0.


Made with ❀️ by Wick Studio

About

Generate beautiful, pixel-perfect Discord HTML transcripts with full support for modern Discord UI - buttons, select menus, polls, voice messages, forwarded messages, server tags, and more.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors