thelounge-plugin-emotes
v1.0.0
Published
Twitch-style emotes for The Lounge IRC client. Supports 7TV, BetterTTV, and FrankerFaceZ global emotes.
Downloads
11
Maintainers
Readme
thelounge-plugin-emotes
Twitch-style emotes for The Lounge IRC client. Renders emotes from 7TV, BetterTTV, and FrankerFaceZ inline in chat messages — both global and per-channel.
Features
- Global emotes from 7TV, BTTV, and FrankerFaceZ (130+ emotes)
- Channel emotes — add any Twitch channel name to load their 7TV, BTTV, and FFZ emotes (800+ per channel)
- Emote picker — ☺ button in the chat bar opens a searchable emote palette with provider tabs
- Settings panel — gear icon in the picker to manage channel emote sources
- Auto-refresh — emote data refreshes every hour
- Hover tooltips — shows emote name and provider on hover
- Emote-only messages — messages with only emotes (up to 3) render at natural size
- Retina support —
srcsetwith 2x images for high-DPI displays - Natural sizing — emotes render at their native size with 128px max safeguards
- Accessible —
alttext andaria-labelon all emote images
Installation
thelounge install thelounge-plugin-emotesRestart The Lounge after installing. The plugin works out of the box — no configuration required.
What happens on install
- Fetches global emotes from 7TV, BTTV, and FFZ
- Injects the client-side script into The Lounge's HTML
- Starts rendering emotes in chat messages immediately
Manual script loading (fallback)
The plugin injects client.js by intercepting The Lounge's HTTP responses. If emotes don't appear after install, you can load the script manually:
Install Violentmonkey or Tampermonkey, then create a new script:
// ==UserScript==
// @name The Lounge Emotes
// @match https://your-lounge-url/*
// @grant none
// @run-at document-idle
// ==/UserScript==
const s = document.createElement("script");
s.src = "/packages/thelounge-plugin-emotes/client.js";
document.head.appendChild(s);Replace https://your-lounge-url/* with your instance URL.
Open developer tools (F12) and run:
const s = document.createElement("script");
s.src = "/packages/thelounge-plugin-emotes/client.js";
document.head.appendChild(s);This only lasts until page refresh.
Usage
Commands
| Command | Description |
|---------|-------------|
| /emotes | Show emote count, active channels, and usage info |
| /emotes search <term> | Search emotes by name (max 25 results) |
| /emotes refresh | Force reload emote data from all providers |
| /emotes channel add <name> | Add a Twitch channel's emotes |
| /emotes channel remove <name> | Remove a channel's emotes |
| /emotes channels | List active channel emote sources |
Emote Picker
Click the ☺ button in the chat input bar to open the emote picker:
- Search — filter emotes by name in real time
- Provider tabs — filter by All, 7TV, BTTV, or FFZ
- Click to insert — clicking an emote inserts its name into the chat input
- Settings — click the ⚙ gear icon to manage channel emote sources
Channel Emotes
Add any Twitch channel to load their third-party emotes:
- Open the emote picker → click ⚙ → enter a channel name (e.g.
xqc) - Or use the command:
/emotes channel add xqc
The plugin resolves the Twitch username to an ID via ivr.fi, then fetches channel-specific emotes from all three providers. Up to 10 channels can be added.
Emote Priority
When emote names collide across providers or channels, the first one loaded wins:
- Global emotes: 7TV → BTTV → FFZ
- Channel emotes are added after globals (per channel, same provider order)
How It Works
Server (index.js)
- Fetches emotes from 7TV, BTTV, and FFZ APIs on startup
- Resolves Twitch usernames → IDs via
api.ivr.fifor channel emotes - Caches emote data in memory and writes
emote-data.jsonto the package directory - Injects a
<script>tag into The Lounge's HTML response viahttp.ServerResponseprototype patch - Modifies Content-Security-Policy headers to allow emote CDN image sources
- Refreshes emote data every hour
- Persists channel configuration in The Lounge's persistent storage directory
Client (client.js)
- Fetches
emote-data.jsonand builds a regex from all emote names - Uses a
MutationObserverto watch for new chat messages - Walks text nodes in message content and replaces emote codes with
<img>elements - Provides the emote picker UI, settings panel, and hover tooltips
Styles (emotes.css)
- Auto-injected via The Lounge's
Stylesheets.addFile()API - Emotes render at natural size with
max-height: 128px/max-width: 128pxsafeguards - Picker panel uses The Lounge's CSS custom properties for theme consistency
Emote Providers
| Provider | Global API | Channel API | CDN |
|----------|-----------|-------------|-----|
| 7TV | /v3/emote-sets/global | /v3/users/twitch/{id} | cdn.7tv.app |
| BetterTTV | /v3/cached/emotes/global | /v3/cached/users/twitch/{id} | cdn.betterttv.net |
| FrankerFaceZ | /v1/set/global | /v1/room/{username} | cdn.frankerfacez.com |
Security
- All emote URLs are validated as HTTPS before rendering
- Emote names are validated against a strict allowlist pattern (
/^[\w\-:()!]+$/) - Twitch IDs are validated as numeric before use in API calls
- HTTP responses are capped at 5MB to prevent memory exhaustion
- Redirect chains are limited to 3 hops
- Channel names are validated (
/^[a-zA-Z0-9_]{1,25}$/) - Maximum of 10 channel emote sources
- All external API calls use HTTPS with timeouts
- No user credentials or tokens are stored server-side
Requirements
- The Lounge
^4.0.0 - Node.js
>=14.0.0
Contributing
Contributions are welcome. Please open an issue first to discuss what you'd like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -am 'Add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
License
MIT © Zendorea
