Resilient prepare, Twitch chat echo, parallel chat startup
- Prepare endpoint wraps each destination in try/catch; partial success if at least one destination is ready (e.g., Twitch works when YouTube is rate-limited) - Echo sent Twitch messages back to app WebSocket (IRC doesn't echo your own PRIVMSGs) - Start YouTube and Twitch chat clients in parallel via Promise.allSettled - Fix Twitch auth failure detection (Login unsuccessful + Login authentication failed) - Add Twitch IRC debug logging
This commit is contained in:
@@ -33,6 +33,7 @@ export class TwitchChatClient extends EventEmitter {
|
||||
this.ws = new WebSocket('wss://irc-ws.chat.twitch.tv:443');
|
||||
|
||||
this.ws.on('open', () => {
|
||||
console.log(`[Twitch-IRC] WebSocket open for #${this.channel}`);
|
||||
if (!this.ws) return;
|
||||
// Request capabilities
|
||||
this.ws.send('CAP REQ :twitch.tv/tags twitch.tv/commands');
|
||||
@@ -45,19 +46,22 @@ export class TwitchChatClient extends EventEmitter {
|
||||
|
||||
this.ws.on('message', (data: Buffer) => {
|
||||
const raw = data.toString();
|
||||
console.log(`[Twitch-IRC] #${this.channel} << ${raw.trim().substring(0, 200)}`);
|
||||
const lines = raw.split('\r\n').filter(Boolean);
|
||||
for (const line of lines) {
|
||||
this.handleLine(line);
|
||||
}
|
||||
});
|
||||
|
||||
this.ws.on('close', () => {
|
||||
this.ws.on('close', (code: number, reason: Buffer) => {
|
||||
console.log(`[Twitch-IRC] #${this.channel} closed: ${code} ${reason.toString()}`);
|
||||
this.connected = false;
|
||||
this.cleanup();
|
||||
this.emit('disconnected');
|
||||
});
|
||||
|
||||
this.ws.on('error', (err: Error) => {
|
||||
console.log(`[Twitch-IRC] #${this.channel} error: ${err.message}`);
|
||||
this.emit('error', err);
|
||||
});
|
||||
|
||||
@@ -106,8 +110,8 @@ export class TwitchChatClient extends EventEmitter {
|
||||
}
|
||||
|
||||
// Handle auth failure
|
||||
if (line.includes('NOTICE') && line.includes('Login authentication failed')) {
|
||||
this.emit('error', new Error('missing_scopes'));
|
||||
if (line.includes('NOTICE') && (line.includes('Login unsuccessful') || line.includes('Login authentication failed'))) {
|
||||
this.emit('error', new Error('Twitch login failed — token may be expired or missing chat scopes'));
|
||||
this.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user