Apologies for the in-depth explanation, but there’s a tl;dr at the end
Ok, so in this lockdown boredom I’m essentially trying to teach myself how to build a twitch bot from scratch using only node.js’s net module(and the tls module… because security!) for the tcp connections. My first foray was to connect using the irc protocol. (irc.twitch.tv port 6667) which was nice and clean cut. But I’m trying to figure out how to get more in-depth information from the callbacks as well such as follows, subs, and point redeem events. Though this has lead down a rabbit hole of other questions which has me curious about how to connect in other ways.
Now I understand I have a couple options, WebSockets and Webhooks essentially, though that seems to be subdivided a bit(with… EventSubs being a future project?). I’ll add a second question topic in order to keep things concise about my confusion between the various connection endpoints(unsure this is the right word here.)
However, when it comes to connecting specifically to ws://irc-ws.chat.twitch.tv:80 I can’t seem to simply get the EXACT format of the header correctly. Here is what I can do so far in node.js:
const net = require('net');
data_buf = '';
host = 'echo.websocket.org';
port = 80;
var client = new net.Socket().connect({
port: port,
host: host
}, function() {
console.log('Connected');
client.write('GET / HTTP/1.1\r\n'
+ 'Upgrade:websocket\r\n'
+ 'Connection:Upgrade\r\n'
+ 'Host:' + host + '\r\n'
+ 'Origin:http://www.websocket.org\r\n'
+ '\r\n');
});
client.on('data', function(chunk) {
data_buf += chunk.toString('utf-8');
let data_str = '';
while(data_buf.indexOf('\n') >= 0) {
data_str = data_buf.substr(0, data_buf.indexOf('\n'));
data_buf = data_buf.substr(data_buf.indexOf('\n') + 1);
console.log(data_str);
}
});
which is a sample that works for the websocket echo at an external public site.
HTTP/1.1 101 Web Socket Protocol Handshake
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Headers: x-websocket-extensions
Access-Control-Allow-Headers: x-websocket-version
Access-Control-Allow-Headers: x-websocket-protocol
Access-Control-Allow-Origin: http://www.websocket.org
Connection: Upgrade
Date: Sun, 17 Jan 2021 07:58:23 GMT
Server: Kaazing Gateway
Upgrade: WebSocket
WebSocket-Location: ws://echo.websocket.org/
WebSocket-Origin: http://www.websocket.org
The problem occurs that if I attempt to switch to something similar for twitch:
const net = require('net');
data_buf = '';
host = 'irc-ws.chat.twitch.tv';
port = 80;
var client = new net.Socket().connect({
port: port,
host: host
}, function() {
console.log('Connected');
client.write('GET / HTTP/1.1\r\n'
+ 'Upgrade:websocket\r\n'
+ 'Connection:Upgrade\r\n'
+ 'Host:' + host + '\r\n'
+ 'Origin:https://www.twitch.tv\r\n'
+ 'Sec-WebSocket-Protocol:irc\r\n'
+ 'Sec-WebSocket-Version:13\r\n'
+ '\r\n');
});
client.on('data', function(chunk) {
data_buf += chunk.toString('utf-8');
let data_str = '';
while(data_buf.indexOf('\n') >= 0) {
data_str = data_buf.substr(0, data_buf.indexOf('\n'));
data_buf = data_buf.substr(data_buf.indexOf('\n') + 1);
console.log(data_str);
}
});
and it turns out to be a Bad Request:
HTTP/1.1 400 Bad Request
Date: Sun, 17 Jan 2021 08:05:17 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 12
Connection: keep-alive
X-Content-Type-Options: nosniff
Bad Request
now at this point I know there’s going to be a LOT more involved with creating a raw websocket client from “scratch”(this ain’t assembler or something, I know ) but I figure I can probably get to the next step if I can just figure out(or better yet be linked to where in the docs it lists) the precise formatting I need in order to send an entire request header that twitch is happy with
(Bonus thank you’s if you can do this for
pubsub-edge.twitch.tv
as well!)
tl;dr → just need the precise formatting for an entire request header for the twitch websockets =)