Table of Contents

Twitch PubSub

PubSub enables you to subscribe to a topic, for updates (e.g., when a user cheers on a channel).

The Twitch PubSub system allows back-end services to broadcast realtime messages to clients. Example applications include:

  • An instant messaging service sending instant messages between friends.
  • A back-end video system pushing real-time viewer count updates to video players.
  • A presence system broadcasting users’ online status to all their friends.

As Module: Twitch4J

To use PubSub you need to enable the PubSub when building the Twitch4J Instance, as shown below:

TwitchClient twitchClient = TwitchClientBuilder.builder()
	...
	.withEnablePubSub(true)
	...
	.build();
def twitchClient = TwitchClientBuilder.builder()
	...
	.withEnablePubSub(true)
	...
	.build()
val twitchClient = TwitchClientBuilder.builder()
	...
	.withEnablePubSub(true)
	...
	.build()

Standalone

Initialize the PubSub as Standalone Module:

TwitchPubSub client = TwitchPubSubBuilder.builder().build();
def client = TwitchPubSubBuilder.builder().build();
val client = TwitchPubSubBuilder.builder().build();

Handle the Results

Messages received over PubSub will be dispatched using the EventManager, please see the Twitch4J -> Events Documentation on how to listen for events or check out the individual pages below for specific code samples.

Available Topics

In PubSub Context you subscribe to topics, a topic is for example whispers to user twitch4j or subscriptions in channel twitch4j.

Note that nearly all of the pubsub topics rely upon the user ID to subscribe to them, rather than the user name. See API - Helix -> Users Get, if one needs to convert between the two.

Here is a list of available topics along with code samples:

Official

Unofficial

Disclaimer: Use at your own risk after understanding the Twitch Developer Agreement. These topics may break at any time and there is no guarantee of support. The authors of the Twitch4J library assume no responsibility for your actions.

We hope Twitch will document these topics as there is no official way to get much of this data, and they could be used for creating powerful integrations.

Unsubscribing

Once a topic is no longer relevant, one can unsubscribe from it to stop receiving further events of that type.

// Initial subscription
PubSubSubscription subscription = twitchClient.getPubSub().listenForWhisperEvents(credential, userId);

// Later unsubscription
twitchClient.getPubSub().unsubscribeFromTopic(subscription);
// Initial subscription
def subscription = twitchClient.pubSub.listenForWhisperEvents(credential, userId)

// Later unsubscription
twitchClient.pubSub.unsubscribeFromTopic(subscription)
// Initial subscription
val subscription = twitchClient.pubSub.listenForWhisperEvents(credential, userId)

// Later unsubscription
twitchClient.pubSub.unsubscribeFromTopic(subscription)

Rate-limits

A single TwitchPubSub instance may only be subscribed to up to 50 topics at a time, under Twitch’s default limits. This yields another reason to unsubscribe from irrelevant topics; it creates headroom for other topics.

If still more headroom is needed, one can construct additional TwitchPubSub instances, each with a limit of 50 topics. Twitch recommends no greater than 10 pubsub connections be made from a single IP (each TwitchPubSub instance is equivalent to a single connection), but this is not a hard limit.

To simplify this, we offer TwitchPubSubConnectionPool as a class that can abstract away the creation/deletion of additional PubSub connections for you:

// Create a dynamically-sized connection pool
TwitchPubSubConnectionPool pool = TwitchPubSubConnectionPool.builder()
	.maxSubscriptionsPerConnection(50)
	.build();

// Register our listener(s)
pool.getEventManager().onEvent(ChatModerationEvent.class, System.out::println);

// Define our requests (that can exceed 50 in count)
PubSubRequest req1 = ... ;
PubSubRequest req2 = ... ;
PubSubRequest req3 = ... ;

// Subscribe to topics
PubSubSubscription resp1 = pool.subscribe(req1);
PubSubSubscription resp2 = pool.subscribe(req2);
PubSubSubscription resp3 = pool.subscribe(req3);

// Later, can unsubscribe from any
pool.unsubscribe(resp2);
// Create a dynamically-sized connection pool
def pool = TwitchPubSubConnectionPool.builder()
	.maxSubscriptionsPerConnection(50)
	.build();

// Register our listener(s)
pool.eventManager.onEvent(ChatModerationEvent) { System.out.println(it) }

// Define our requests (that can exceed 50 in count)
PubSubRequest req1 = ...
PubSubRequest req2 = ...
PubSubRequest req3 = ...

// Subscribe to topics
PubSubSubscription resp1 = pool.subscribe(req1)
PubSubSubscription resp2 = pool.subscribe(req2)
PubSubSubscription resp3 = pool.subscribe(req3)

// Later, can unsubscribe from any
pool.unsubscribe(resp2);
// Create a dynamically-sized connection pool
val pool = TwitchPubSubConnectionPool.builder()
	.maxSubscriptionsPerConnection(50)
	.build();

// Register our listener(s)
pool.eventManager.onEvent(ChatModerationEvent::class.java, System.out::println);

// Define our requests (that can exceed 50 in count)
var req1: PubSubRequest = ...
var req2: PubSubRequest = ...
var req3: PubSubRequest = ...

// Subscribe to topics
val resp1: PubSubSubscription = pool.subscribe(req1)
val resp2: PubSubSubscription = pool.subscribe(req2)
val resp3: PubSubSubscription = pool.subscribe(req3)

// Later, can unsubscribe from any
pool.unsubscribe(resp2);

A more concrete example of this can be found here.