Twitch overlay click tracking with WebSocket API
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.
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.
Each click arrives as a JSON message:
{
"type": "click",
"x": 0.5234,
"y": 0.3421,
"viewerId": "12345678",
"opaqueId": "U1234567890",
"channelId": "87654321",
"timestamp": 1720900000000
}
| Field | Type | Description |
|---|---|---|
type | string | Always "click" |
x | float | Horizontal position, 0 (left) to 1 (right) |
y | float | Vertical position, 0 (top) to 1 (bottom) |
viewerId | string | Twitch user ID (empty if viewer hasn't shared identity) |
opaqueId | string | Anonymous per-extension viewer ID |
channelId | string | Twitch channel ID where the click happened |
timestamp | int | Server-side Unix milliseconds |
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'}`);
};
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;
}
}
Viewer clicks are rate-limited to 10 per second per connection. Subscriber connections receive all clicks for their channel with no filtering.