npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

tubechat

v1.0.18

Published

Library to connect to broadcast chats on youtube

Readme

Contributors Issues License npm version

About The Project

The TubeChat NodeJS library offers a highly efficient way to integrate with YouTube's live chat.

Its key differentiator is the use of yt-chat-signaler, which listens to YouTube's internal RPC signals. Unlike other libraries that rely on constant, resource-intensive polling (setInterval), TubeChat only fetches new messages when they are actually available, resulting in superior performance and efficiency.

Getting Started

Installation

First install our library

npm install tubechat

Usage

Import the library

import { TubeChat } from 'tubechat'

Instantiate the class

const tubeChat = new TubeChat({
  // All settings are optional
  useSignaler: true, 
});

Constructor Options

You can pass an options object to the TubeChat constructor to customize its behavior:

  • useSignaler (boolean): Whether to use the yt-chat-signaler for intelligent, push-based fetching. It is highly recommended to keep this enabled for performance. Defaults to true.
  • headers (HeadersInit): Custom headers to be used for all HTTP requests made by the library.
  • intervalChat (number): The base interval in milliseconds for fetching chat messages. This is mainly a fallback for when the signaler is not in use. Defaults to 1000.
  • signalerConnectedInterval (number): The long-polling interval in milliseconds for when the signaler is connected and waiting for a push signal. Defaults to 15000.
  • signalerDisconnectedInterval (number): The faster polling interval for when the signaler is temporarily disconnected, ensuring messages are not missed. Defaults to 1000.
  • maxRetries (number): Maximum number of retry attempts for the initial connection to a chat. Defaults to 4.

Connecting to a Chat

To connect to a chat, you need a Video ID. The method returns a promise indicating if the join was successful.

tubeChat.join(videoId, skipFirstResults, options)
  • videoId (string, required): The ID of the YouTube live stream.
  • skipFirstResults (boolean, optional): If true, it will ignore the initial batch of messages that YouTube sends upon connection (which are often historical messages). Defaults to false.
  • options (object, optional):
    • headers (HeadersInit): Custom headers specifically for this video's connection requests.
    • interval (number): A custom polling interval for this specific video, overriding the global setting.

How to get a Video ID from a Channel Name?

If you need to monitor a channel and get its videoId when it goes live, we recommend using a library like Flow Monitor. It can watch a channel and notify you when a stream starts, providing the necessary videoId.

Here’s a brief example of how you could integrate it:

import { FlowMonitor } from 'flow-monitor';
import { TubeChat } from 'tubechat';

const fMonitor = new FlowMonitor();
const tubeChat = new TubeChat();

// Tell Flow Monitor to watch a channel
fMonitor.connect('LofiGirl', 'youtube');

// When Flow Monitor detects a live stream, it gives you the videoId
fMonitor.on('streamUp', (liveData) => {
  console.log(`${liveData.channel} is live with video ID: ${liveData.vodId}`);
  
  // Now, use the videoId to join the chat with TubeChat
  tubeChat.join(liveData.vodId);
});

// Start monitoring
fMonitor.start();

Event Handling

All events, in addition to their specific data, also return chatId (the video ID), userChannel (the channel's vanity name, e.g., "@LofiGirl"), and videoData (an object with details about the video).

Connection Events

// Emitted when a connection to the chat is successfully established.
tubeChat.on('join', (chatId, userChannel, videoData) => {
  console.log(`Joined chat for ${userChannel} (Video: ${chatId})`);
});

// Emitted when the client disconnects from a chat.
tubeChat.on('disconnected', (chatId, userChannel, videoData) => {
  console.log(`Disconnected from ${userChannel} (Video: ${chatId})`);
});

// Emitted when there's an error joining a chat.
tubeChat.on('joinError', (chatId, error) => {
  console.error(`Failed to join chat ${chatId}:`, error.message);
});

// Emitted on connection retry attempts.
tubeChat.on('retry', (chatId, error, retry, maxRetries) => {
  console.log(`Retrying connection to ${chatId} (${retry}/${maxRetries})...`);
});

// Emitted on general errors, usually during message fetching.
tubeChat.on('error', (chatId, message) => {
  console.error(`An error occurred in chat ${chatId}:`, message);
});

Chat Message Events

// A regular chat message.
tubeChat.on('message', (message, chatId, userChannel, videoData) => {
  const author = message.author.channelName;
  const text = message.message.map(part => part.text).join('');
  console.log(`[${userChannel}] ${author}: ${text}`);
});

// A Super Chat message (paid message or sticker).
tubeChat.on('superchat', (message, chatId, userChannel, videoData) => {
  console.log(`${message.author.channelName} sent a Super Chat of ${message.formatted}!`);
});

// A new or returning member announcement.
tubeChat.on('member', (message, chatId, userChannel, videoData) => {
  if (message.isResub) {
    console.log(`${message.author.channelName} has been a member for ${message.author.badges.months} months!`);
  } else {
    console.log(`Welcome ${message.author.channelName}, our newest member!`);
  }
});

// When a user gifts one or more subscriptions to the community.
tubeChat.on('subgift_announce', (message, chatId, userChannel, videoData) => {
  console.log(`${message.author.channelName} gifted ${message.count} subs to the community!`);
});

// When a specific user receives a gifted subscription.
tubeChat.on('subgift', (message, chatId, userChannel, videoData) => {
  console.log(`${message.author.channelName} received a gifted sub from ${message.gifter}!`);
});

// For "Jewels" donations, typically from YouTube Shorts.
tubeChat.on('jewels', (message, chatId, userChannel, videoData) => {
  console.log(`${message.author.channelName} sent Jewels!`);
});

Moderation and System Events

// When a message is deleted by a moderator.
tubeChat.on('deletedMessage', (messageId, chatId, userChannel, videoData) => {
  console.log(`Message ${messageId} was deleted from chat ${chatId}.`);
});

// When all messages from a specific user are deleted (ban/timeout).
tubeChat.on('deleteUserMessages', (channelId, chatId, userChannel, videoData) => {
  console.log(`All messages from user ${channelId} were removed in chat ${chatId}.`);
});

// For changes in chat mode (e.g., slow mode, subscribers-only).
tubeChat.on('system', (message, chatId, userChannel, videoData) => {
  console.log(`System message in ${chatId}: ${message.message}`);
});

Raw Data Event

// Emits the raw action object from YouTube for custom parsing.
tubeChat.on('raw', (actions) => {
  // console.log('Received raw actions:', actions);
});

Signaler for Efficiency

This library integrates yt-chat-signaler to listen for new messages efficiently, reducing the need for constant polling. When useSignaler is true (the default), TubeChat will receive a push notification when a new message is available. You can listen to the signaler's own events if you need fine-grained control or diagnostics.

if (tubeChat.signaler) {
  tubeChat.signaler.on('connected', (chatData) => {
    console.log(`Signaler connected for video: ${chatData.chatId}`);
  });

  tubeChat.signaler.on('data', ({ chatData }) => {
    console.log(`Signaler received new message notification for ${chatData.chatId}`);
  });
}

Additional Functions

  • leave(videoId) Disconnects from a specific video's chat.

    tubeChat.leave('VIDEO_ID_HERE');
  • videos A public Map containing the state and data of all currently connected video chats.

    // Get a list of all connected video IDs
    const connectedVideoIds = Array.from(tubeChat.videos.keys());
    console.log('Connected to:', connectedVideoIds);
    
    // Get data for a specific video
    const videoDetails = tubeChat.videos.get('VIDEO_ID_HERE');

License

Distributed under the MIT License. See LICENSE for more information.

Authors

  • ZackSB - Master's degree in life - ZackSB - Built tubechat

Acknowledgements