A Paper/Spigot plugin that bridges YouTube Live Chat into Minecraft. Each player can connect to their own YouTube live stream and receive chat messages directly in-game — per-player, not server-wide.
- Per-player YouTube chat — each player connects to their own stream
- Persistent sessions — video IDs are saved, survives disconnects and restarts
- Auto-reconnect — players automatically reconnect to their last stream on join
- Customizable format — players can set their own chat format with
/ytchat format - Role badges — owner, moderator, and verified users get colored names and badge icons
- Hex color support — full
&#RRGGBBhex colors alongside&clegacy codes - Configurable messages — every plugin message is editable in
message.yml - Configurable sounds — start/stop sounds, or disable them
- Emoji filtering — strips YouTube emoji shortcodes from messages
- Custom events — developers can listen to
YTChatStartEvent,YTChatStopEvent, andYouTubeChatMessageEvent - Tab completion — sub-commands and format placeholders auto-complete
- Java 21+
- Paper 1.21+ (or Spigot 1.21+)
- Download the latest
ytchat-*-jar-with-dependencies.jarfrom Releases - Place it in your server's
plugins/folder - Start or restart the server
- Config files will be generated in
plugins/YTChat/
| Command | Description |
|---|---|
/ytchat start <videoId> |
Connect to a YouTube live stream |
/ytchat start |
Reconnect to your last saved stream |
/ytchat stop |
Disconnect from YouTube chat |
/ytchat format <format> |
Set a custom chat message format |
/ytchat format reset |
Reset format to default |
/ytchat status |
Check your connection status |
/ytchat reload |
Reload all config files (OP only) |
| Permission | Description | Default |
|---|---|---|
ytchat.cmd |
Allows using all /ytchat commands |
Everyone |
ytchat.reload |
Allows using /ytchat reload |
OP only |
# Polling interval in seconds
poll-interval: 5
# Auto-reconnect players to their last video on join
auto-reconnect: trueAll plugin messages, chat format, role colors, badges, and sounds are configured here.
Chat format placeholders:
| Placeholder | Description |
|---|---|
%prefix% |
The chat prefix (default: &#FF0000[YTChat]) |
%author% |
YouTube author name (auto-colored by role) |
%badge% |
Role badge icons (owner/moderator/verified) |
%message% |
The chat message content |
Role colors and badges (configurable in message.yml):
| Role | Default Color | Badge |
|---|---|---|
| Owner | Gold (&#FFD700) |
Crown |
| Moderator | Blue (ᖳFF) |
Hammer |
| Verified | Green (7FF55) |
Checkmark |
| Default | Gray (&7) |
None |
Sounds:
sound:
start: BLOCK_NOTE_BLOCK_BELL # on successful connect
stop: BLOCK_NOTE_BLOCK_BASS # on disconnect
volume: 1.0
pitch: 1.0Set any sound to '' (empty) to disable it.
Command messages use %prefix% which auto-resolves to the chat.prefix value — change the prefix once, it updates everywhere.
git clone https://github.com/FewPz/YTChat.git
cd YTChat
mvn clean packageThe built JAR will be at target/ytchat-*-jar-with-dependencies.jar.
src/com/peeranat/ytchat/
├── YTChatPlugin.java # Entry point — wiring only
├── command/
│ ├── YTChatCommand.java # /ytchat command handler
│ └── YTChatTabCompleter.java # Tab completion
├── event/
│ ├── YTChatStartEvent.java # Fired before connecting (cancellable)
│ ├── YTChatStopEvent.java # Fired after disconnecting
│ └── YouTubeChatMessageEvent.java # Fired per chat message
├── listener/
│ ├── ChatMessageListener.java # Formats and sends YT messages to player
│ └── PlayerConnectionListener.java # Auto-reconnect on join, cleanup on quit
├── model/
│ └── ChatMessage.java # Data model with role flags
├── repository/
│ ├── ChatConfigRepository.java # Reads config.yml
│ ├── MessageRepository.java # Reads message.yml
│ └── PlayerDataRepository.java # Per-player persistent data (playerdata.yml)
├── service/
│ └── YouTubeChatService.java # YouTube API polling, per-player connections
└── util/
├── ColorUtil.java # Hex + legacy color parsing
├── EmojiUtil.java # YouTube emoji shortcode stripping
└── SoundUtil.java # Sound playback via Registry API
Other plugins can listen to YTChat events:
Fired for every YouTube chat message received. Async event.
@EventHandler
public void onYouTubeChat(YouTubeChatMessageEvent event) {
ChatMessage msg = event.getChatMessage();
UUID playerUUID = msg.getOwnerUUID();
String author = msg.getAuthorName();
String message = msg.getMessage();
boolean isOwner = msg.isOwner();
boolean isModerator = msg.isModerator();
boolean isVerified = msg.isVerified();
// Cancel to prevent the message from being sent
event.setCancelled(true);
}Fired on the main thread before a player connects. Cancellable.
@EventHandler
public void onStart(YTChatStartEvent event) {
UUID playerUUID = event.getPlayerUUID();
String videoId = event.getVideoId();
// Cancel to prevent the connection
event.setCancelled(true);
}Fired on the main thread when a connection stops. Not cancellable.
@EventHandler
public void onStop(YTChatStopEvent event) {
UUID playerUUID = event.getPlayerUUID();
YTChatStopEvent.Reason reason = event.getReason();
// Reasons: COMMAND, DISCONNECT, PLUGIN_DISABLE, REPLACED
}This project is open source.