Last active
August 4, 2024 16:07
-
-
Save BarryCarlyon/13e19ca3f4c98c8183d54b733581a9e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://dev.twitch.tv/docs/chat/chatbot-guide/ | |
*/ | |
import WebSocket from 'ws'; | |
const OAUTH_TOKEN = 'CHANGE_ME_TO_YOUR_OAUTH_TOKEN'; // Needs scopes user:bot, user:read:chat, user:write:chat | |
const CHAT_CHANNEL_USER_ID = 'CHANGE_ME_TO_THE_CHAT_CHANNELS_USER_ID'; // This is the User ID of the channel that the bot will join and listen to chat messages of | |
let CLIENT_ID = ''; // We will infer the Client ID from the provided token | |
let BOT_USER_ID = ''; // We will infer the Bot ID from the provided token | |
const EVENTSUB_WEBSOCKET_URL = 'wss://eventsub.wss.twitch.tv/ws'; | |
var websocketSessionID; | |
// Start executing the bot from here | |
(async () => { | |
// Verify that the authentication is valid | |
await getAuth(); | |
// Start WebSocket client and register handlers | |
const websocketClient = startWebSocketClient(); | |
})(); | |
// WebSocket will persist the application loop until you exit the program forcefully | |
async function getAuth() { | |
// https://dev.twitch.tv/docs/authentication/validate-tokens/#how-to-validate-a-token | |
let response = await fetch('https://id.twitch.tv/oauth2/validate', { | |
method: 'GET', | |
headers: { | |
'Authorization': 'OAuth ' + OAUTH_TOKEN | |
} | |
}); | |
let data = await response.json(); | |
if (response.status != 200) { | |
console.error("Token is not valid. /oauth2/validate returned status code " + response.status); | |
console.error(data); | |
process.exit(1); | |
} | |
console.log("Validated token."); | |
if (data.hasOwnProperty('user_id')) { | |
console.error("Token is the wrong type, no user_id found"); | |
process.exit(1); | |
} | |
BOT_USER_ID = data.user_id; | |
CLIENT_ID = data.client_id; | |
// consider scope validation | |
} | |
function startWebSocketClient() { | |
let websocketClient = new WebSocket(EVENTSUB_WEBSOCKET_URL); | |
websocketClient.on('error', console.error); | |
websocketClient.on('open', () => { | |
console.log('WebSocket connection opened to ' + EVENTSUB_WEBSOCKET_URL); | |
}); | |
websocketClient.on('message', (data) => { | |
handleWebSocketMessage(JSON.parse(data.toString())); | |
}); | |
return websocketClient; | |
} | |
function handleWebSocketMessage(data) { | |
switch (data.metadata.message_type) { | |
case 'session_welcome': // First message you get from the WebSocket server when connecting | |
websocketSessionID = data.payload.session.id; // Register the Session ID it gives us | |
// Listen to EventSub, which joins the chatroom from your bot's account | |
registerEventSubListeners(); | |
break; | |
case 'notification': // An EventSub notification has occurred, such as channel.chat.message | |
switch (data.metadata.subscription_type) { | |
case 'channel.chat.message': | |
// First, print the message to the program's console. | |
console.log(`MSG #${data.payload.event.broadcaster_user_login} <${data.payload.event.chatter_user_login}> ${data.payload.event.message.text}`); | |
// Then check to see if that message was "HeyGuys" | |
if (data.payload.event.message.text.trim() == "HeyGuys") { | |
// If so, send back "VoHiYo" to the chatroom | |
sendChatMessage("VoHiYo") | |
} | |
break; | |
} | |
break; | |
} | |
} | |
async function sendChatMessage(chatMessage) { | |
let response = await fetch('https://api.twitch.tv/helix/chat/messages', { | |
method: 'POST', | |
headers: { | |
'Authorization': 'Bearer ' + OAUTH_TOKEN, | |
'Client-Id': CLIENT_ID, | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ | |
broadcaster_id: CHAT_CHANNEL_USER_ID, | |
sender_id: BOT_USER_ID, | |
message: chatMessage | |
}) | |
}); | |
if (response.status != 200) { | |
let data = await response.json(); | |
console.error("Failed to send chat message"); | |
console.error(data); | |
} else { | |
console.log("Sent chat message: " + chatMessage); | |
} | |
} | |
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 { | |
const data = await response.json(); | |
console.log(`Subscribed to channel.chat.message [${data.data[0].id}]`); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment