I’m working on a modified version of the twitch node.js bot example trying to catch both chat and channel point redeems and run into a bit of a hiccup. I don’t think my code’s the problem since it works fine if I use my own (broadcaster) account to get an OAuth token and as the account that connects. My trouble is trying to get the BOT account to do the same thing. So far I’ve managed:
BOT subscribes to chat but not redeems if I use an OAuth token from BOT
BOT subscribes to redeems but not chat if I use an OAuth token from broadcaster
Subscribes to both if I use the broadcaster account and OAuth token
So I assume I’m running into some kind of permissions issue. Is it my scope that’s wrong? I’m currently using user:bot, user:read:chat, user:write:chat, and channel:read:redemptions – is this incorrect or missing something? BOT is a moderator in my channel if that matters.
Can I buy a clue? Please and thank you!
async function registerEventSubListeners() {
// Register channel.chat.message
let response = await fetch('https://api.twitch.tv/helix/eventsub/subscriptions', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + OAUTH_TOKEN,
'Client-Id': CLIENT_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'channel.chat.message',
version: '1',
condition: {
broadcaster_user_id: CHAT_CHANNEL_USER_ID,
user_id: BOT_USER_ID
},
transport: {
method: 'websocket',
session_id: websocketSessionID
}
})
});
if (response.status != 202) {
let data = await response.json();
console.error("Failed to subscribe to channel.chat.message. API call returned status code " + response.status);
console.error(data);
// process.exit(1);
} else {
let data = await response.json();
console.log(`Subscribed to channel.chat.message [${data.data[0].id}]`);
}
// Register channel.channel_points_custom_reward_redemption.add
response = await fetch('https://api.twitch.tv/helix/eventsub/subscriptions', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + OAUTH_TOKEN,
'Client-Id': CLIENT_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'channel.channel_points_custom_reward_redemption.add',
version: '1',
condition: {
broadcaster_user_id: CHAT_CHANNEL_USER_ID
},
transport: {
method: 'websocket',
session_id: websocketSessionID
}
})
});
if (response.status != 202) {
let data = await response.json();
console.error("Failed to subscribe to channel.channel_points_custom_reward_redemption.add. API call returned status code " + response.status);
console.error(data);
// process.exit(1);
} else {
let data = await response.json();
console.log(`Subscribed to channel.channel_points_custom_reward_redemption.add [${data.data[0].id}]`);
}
}
On a straight websocket you cannot mix tokens from two users.
So you need two websockets.
channel:read:redemptions is useless to get from the bot account as the bot doesn’t have channel points
The bot being a moderator is irrelevant as the channel points topics doesn’t take a moderator ID in the condition
So you want:
Socket A for reading chat as the bot
Socket B for recieving channel point redeeems as the broadcaster
You should of got a useful error in the response to your request.
Normally straight websockets are expected to be used in a world where you are the user authing and can’t normally get someone elses auth, so an added security layer exists to help hint that so a given socket can’t recieve from multiple oAuth tokens that represent different users. (and/or simplifies the rate limits)
Since you seem to be the bot and the broadcaster.
And it’s personal use, I’d just read chat as the broadcaster, so you only need the one websocket and read chat/read redeems, and send as a bot (via the send chat helix endpoint)
True, but it’s one of the two scopes that allows getting notifications of when other users redeem something, which is all I’m trying to do.
Which is what I’d like to do with the bot, except apparently only the broadcaster can subscribe to channel redeem event notifications.
Sigh. So before each time I want to use my code I’ll need to get an OAuth and refresh token from the broadcaster account, an OAuth and refresh token for the bot’s account, update those 4 variables in my code, and then maintain two separate WebSockets just so broadcaster can catch events that the bot can then reply to.
Broadly yes. However No, since this appears to be personal use there is an alternative:
After you have authed your bot to your client id
You can use an app access token to send to chat
So you only need to maintain the broadcasters oAuth token to connect a websocket to read chat as the broadcaster
Further more since this seems to be personal use: consider using a conduit
OAuth both accounts to your client id
Subscribe the topics to your conduit
Use a conduit of one shard
Make that shard be a websocket
Then everything works off an app access token. And you only need to maintain the app access token using your client id and secret
For both options sure you may need to occasionally reauth the pair of users to your client id if the link breaks. But you don’t need to store and maintain those tokens. Just a generated app access token