tmi.js
tmi.js copied to clipboard
`disconnected` callback's "reason" parameter is blank
Actual behaviour: The disconnected event's reason parameter for its callback is blank.
Expected behaviour: The callback for the disconnected event would receive a string saying why it was disconnect.
Code sample
this.client = new tmi.client({
identity: {
username: opts.username.toLowerCase(),
password: opts.token
},
channels: [opts.username]
})
this.client.on('disconnected', (reason) => {
log.error(`Twitchchat disconnected ${reason}`)
this.connected = false
this.client.connect()
})
this.client.connect()
Error log:
Jan 10 23:46:34: error: Twitchchat disconnected
Jan 10 20:48:43: error: Twitchchat disconnected
Server configuration
- Operating system: Ubuntu 18
- Node version (if applicable): 10.12.0
- NPM version (if applicable): 6.4.1
- tmi.js version: 1.2.1
Tried replicating this with the code currently on Git.
Test details: Operating Systems:
- Ubuntu 18.04.3 LTS
- Windows 10 Home (build 18362.356)
Node version:
- v10.16.3
- v10.16.1
NPM version:
- 6.11.3
- 6.11.3
With both tests I tried:
- Disconnecting manually (calling
client.disconnect()) - Supplying invalid login data (incorrect oauth code to
new tmi.Client())
In both tests, both cases have reason defined. This would lead me to believe this issue has been resolved, either by an update to tmi.js, or by an update to Ubuntu/Node/NPM.
This issue can be closed and marked as resolved.
I have the same issue and i cant find the problem why my bot is disconnecting randomly from twitch.
Test details: Operating Systems: Debian 9.0
Node version: v11.15.0
NPM version: 6.12.0
@EightyNine
What does your options object like? (You can leave out the oauth (identity.password) token)
This would allow us to test more accurately
Bot = new tmi.client({
options: {
clientId: process.env.BOT_CLIENTID,
debug: false
},
identity: {
username: process.env.BOT_NAME,
password: process.env.BOT_PASS
},
connection: {
cluster: "aws",
reconnect: true,
reconnectInterval: 2000,
//secure: true,
timeout: 180000
},
channels: ["channel1", "channel2", ..... ]
});
My bot is joining the most channel with the join command. Here a chart to see the is broke up the connection without a reason.
https://gyazo.com/b414a06523863471520481abea367f06
Was there ever any resolution to this? I have the same issue. I get:
[11:50] info: Connecting to irc-ws.chat.twitch.tv on port 443..
[11:50] info: Sending authentication to server..
[11:50] error: Could not connect to server. Reconnecting in 2 seconds..
[11:50] info: Connecting to irc-ws.chat.twitch.tv on port 443..
[11:50] info: Sending authentication to server..
[11:50] error: Could not connect to server. Reconnecting in 2 seconds..
[11:50] info: Connecting to irc-ws.chat.twitch.tv on port 443..
[11:50] info: Sending authentication to server..
[11:50] error: Could not connect to server. Reconnecting in 3 seconds..
[11:50] info: Connecting to irc-ws.chat.twitch.tv on port 443..
[11:50] info: Sending authentication to server..
[11:50] error: Could not connect to server. Reconnecting in 5 seconds..
[11:50] info: Connecting to irc-ws.chat.twitch.tv on port 443..
[11:50] info: Sending authentication to server..
[11:50] error: Could not connect to server. Reconnecting in 8 seconds..
[11:50] info: Connecting to irc-ws.chat.twitch.tv on port 443..
[11:50] info: Sending authentication to server..
[11:50] error: Maximum reconnection attempts reached.
Then in the disconnect logs all I get is
[11:50:11.702] DEBUG (10724): Twitch Client Disconnected
reason: ""
It seems like there is some kind of issue with my setup, but I don't get any other errors or descriptors as to what I might be doing incorrectly.
Here's the snip for creating the client:
const tokenPass = `${this.botAccount.token.token_type} ${this.botAccount.token.access_token}`;
this.twitchClient = new Client({
connection: {
maxReconnectAttempts: 5,
timeout: 18000,
},
channels: [this.botAccount.channel],
options: { debug: process.env.NODE_ENV === "development" },
identity: {
username: this.botAccount.username,
password: tokenPass,
},
});
this.twitchClient.on("disconnected", (reason) => {
logger.debug(
{ reason, twitchClient: this.twitchClient },
"Twitch Client Disconnected"
);
});
try {
await this.twitchClient.connect();
this.STATUS = "READY";
resolve();
logger.debug("Created and connected new authenticated twitch client");
} catch (err) {
reject(err);
this.STATUS = "ERROR";
logger.error(
{ err },
"Failed to connect new twitch authenticated client"
);
}
});
Connecting anonymously works 100% fine. It's only when authenticating that I have an issue. It seems like the authentication IS working, though. If I provide an incorrect bearer token I get a 400 invalid client.
I got it working for myself, but holy heck was it a pain to figure out... Essentially after hours and hours of troubleshooting and trying different things it boiled down to not having a wide enough scope. Despite the documentation stating
That doesn't appear to be the case. After I changed the authorization flow to use
const twitchAuthURI = `https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=${botAccount.client_id}&redirect_uri=http://localhost:9000%2Fsetup&scope=chat%3Aread+chat%3Aedit+channel%3Amoderate+whispers%3Aread+whispers%3Aedit+channel_editor&token_type=bearer&state=${state}`;
As the OAuth token request, instead of
const twitchAuthURI = `https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=${botAccount.client_id}&redirect_uri=http://localhost:9000%2Fsetup&scope=chat%3Aedit%20whispers%3Aedit&state=${state}`;
everything magically started working!
There are TWO major differences...
- token_type=bearer : I never saw anything mentioning this token_type parameter anywhere in any documentation (either twitch side or tmi.js side), the only way I knew to add it is through working backwards from an app that provides a token that works
- The scopes are WAY wider. I only opted to request the scopes that I really need for my bot at this time, but apparently that was a mistake.
Once I fixed the authorization request to use the above URI, sending the results to the server and using my previous workflow works 100%. I did change my code back to use the documented oauth:{token} instead of using the {token_type} {token} which I posted above (as that's where I was in my trial and error banging head against the wall strat).
Here's what my working server-side code looks like:
const tokenPass = `oauth:${this.botAccount.token.access_token}`;
this.twitchClient = new Client({
connection: {
maxReconnectAttempts: 5,
timeout: 18000,
secure: true,
},
channels: [this.botAccount.channel],
options: {
debug: process.env.NODE_ENV === "development",
},
identity: {
username: this.botAccount.username,
password: tokenPass,
},
});
this.twitchClient.on("disconnected", (reason) => {
logger.debug(
{ reason, status: this.twitchClient?.readyState },
"Twitch Client Disconnected"
);
});
this.twitchClient.on("connected", (reason) => {
logger.debug("Twitch client connected");
});
try {
await this.twitchClient.connect();
this.STATUS = "READY";
resolve();
logger.debug("Created and connected new authenticated twitch client");
} catch (err) {
reject(err);
this.STATUS = "ERROR";
logger.error(
{ err },
"Failed to connect new twitch authenticated client"
);
}
My current project is kind of becoming a bit cumbersome to use as reference, so I wouldn't necessarily recommend it... But it IS currently working as-is at this point (though currently vastly under documented as it's just in the beginning phase of playing with stuff and figuring out what does and doesn't work).
If anyone does want an example though, you can find my project here. https://github.com/ScriptPup/TwitchHelpers In particular, the server logic is mostly here While the client logic is here (check for the showBotTemplate function if it's changed since I posted this).
Lastly, the resources I used to work backwards and figure this out:
- A working project: https://github.com/FrozenTear7/twitch-spambot (awesome documentation and super easy to spin this up following them which helped me vastly in verifying the problem was with the auth flow and not some kind of edge-case network issue, a problem with my account or application registration, etc.)
- Again, this little token generator was also extremely helpful: https://twitchapps.com/tmi/
If the maintainers were able to put together a simple minimal-viable working project example or something and link it in the docs, that would help tremendously. It'd also be a good idea to review the claims about needing only scopes chat:read and/or chat:edit.
Hope this helps someone who stumbles upon the topic like I did in the future. Good luck!