Phail Click Extension

Twitch overlay click tracking with WebSocket API

How It Works

Viewers click on the stream overlay. Each click is captured as normalized coordinates (0--1) and broadcast to all subscribers for that channel in real time.

Subscribe to Click Events

Connect to the WebSocket subscriber endpoint with your channel token:

wss://phail-click-ext.phailbot.com/ws/subscribe?token=YOUR_TOKEN

Get your token from the extension's config panel on your Twitch dashboard.

Click Event Format

Each click arrives as a JSON message:

{
  "type": "click",
  "x": 0.5234,
  "y": 0.3421,
  "viewerId": "12345678",
  "opaqueId": "U1234567890",
  "channelId": "87654321",
  "timestamp": 1720900000000
}
FieldTypeDescription
typestringAlways "click"
xfloatHorizontal position, 0 (left) to 1 (right)
yfloatVertical position, 0 (top) to 1 (bottom)
viewerIdstringTwitch user ID (empty if viewer hasn't shared identity)
opaqueIdstringAnonymous per-extension viewer ID
channelIdstringTwitch channel ID where the click happened
timestampintServer-side Unix milliseconds

Quick Start Example

const ws = new WebSocket(
  'wss://phail-click-ext.phailbot.com/ws/subscribe?token=YOUR_TOKEN'
);

ws.onmessage = function (event) {
  const click = JSON.parse(event.data);
  console.log(`Click at ${click.x}, ${click.y} by ${click.viewerId || 'anonymous'}`);
};

Streamer.bot Integration

Add a WebSocket Client in Streamer.bot pointed at your subscriber URL. Each click arrives as a JSON message you can parse in a C# sub-action:

// In a Streamer.bot Execute Code sub-action
using System.Text.Json;

public class CPHInline : CPHInlineBase {
    public bool Execute() {
        var json = args["rawInput"].ToString();
        var doc = JsonDocument.Parse(json);
        var root = doc.RootElement;

        double x = root.GetProperty("x").GetDouble();
        double y = root.GetProperty("y").GetDouble();
        string viewer = root.GetProperty("viewerId").GetString() ?? "anonymous";

        CPH.SetArgument("clickX", x);
        CPH.SetArgument("clickY", y);
        CPH.SetArgument("clickViewer", viewer);
        return true;
    }
}
Coordinates are normalized to 0--1 regardless of stream resolution. Multiply by your canvas/screen dimensions to get pixel positions.

Rate Limits

Viewer clicks are rate-limited to 10 per second per connection. Subscriber connections receive all clicks for their channel with no filtering.