I try to create a nodejs chatbot from example in documentation, but not works

i start to develop stuff for twitch, and i start from a simple chatbot
i try many ways to put this works and not works
i start again from documentation, with nodejs… but not works
what i do wrong?

example taken from Example Chatbot Guide | Twitch Developers

import WebSocket from 'ws';
import dotenv from 'dotenv';
dotenv.config();

const BOT_USER_ID = 'chatbot-314blackout';
let OAUTH_TOKEN = 'CHANGE_ME_TO_YOUR_OAUTH_TOKEN';
const CLIENT_ID = process.env.CLIENT_ID;
const CLIENT_SECRET = process.env.CLIENT_SECRET;

const CHAT_CHANNEL_USER_ID = "268962144";
//const CHAT_CHANNEL_USER_ID = '314blackout';

const EVENTSUB_WEBSOCKET_URL = 'wss://eventsub.wss.twitch.tv/ws';

var websocketSessionID;

(async () => {
    await getAccessToken();
    await getAuth();
    const websocketClient = startWebSocketClient();
})();

async function getAccessToken() {
    const response = await fetch('https://id.twitch.tv/oauth2/token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({
            client_id: CLIENT_ID,
            client_secret: CLIENT_SECRET,
            grant_type: 'client_credentials'
        })
    });
    const data = await response.json();
    OAUTH_TOKEN = data.access_token;
    console.log('ok');
    return data.access_token;
}


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
        }
    });

    if (response.status != 200) {
        let data = await response.json();
        console.error("Token is not valid. /oauth2/validate returned status code " + response.status);
        console.error(data);
        process.exit(1);
    }

    console.log("Validated token.");
}

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) {
    console.log(data);
    switch (data.metadata.message_type) {
        case 'session_welcome':
            websocketSessionID = data.payload.session.id;
            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
        })
    });
    console.log(response)

    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
    console.log(CHAT_CHANNEL_USER_ID);
    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
            }
        })
    });
    console.log(response);
    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}]`);
    }
}

the error i get is this

Failed to subscribe to channel.chat.message. API call returned status code 400
{
  error: 'Bad Request',
  status: 400,
  message: 'cannot create a subscription for a user that does not exist'
}

i’ve read this Can't get twitch's node.js chat bot example to connect - #3 by hrrmrr but not works :frowning:

You didn’t convert this username to a user_id

And this isn’t a valid username

This function only checks if a token is good and there no token generation.

You are using websockets, so you need a user token from the user you want to read chat as.

In your code you have:

  • no token generation
  • the read chat as is a username instead of a userID
  • an invalid “read chat as username”

You can compare to this “working example”

https://barrycarlyon.github.io/twitch_misc/eventsub/websockets/web/chat/

Which will ask the visiting user to authenticate and then connect to that visitng users chat.
With the option to connect to other chats.

You’ll find it always uses the numerical ID’s in eventsub calls.

So

            condition: {
                broadcaster_user_id: CHAT_CHANNEL_USER_ID,
                user_id: BOT_USER_ID
            },

I want to read cohhcarnage chat so broadcaster_user_id is 26610234
I have authenticated as barrycarlyon so user_id is 15185913

The owner of the clientID is irrelevant as it’s just a thing used to get oAuth tokens from users

2 Likes

ok i take your script and reproduce it, but i not understand how send message

Using the Send Chat Message API: Reference | Twitch Developers

Assuming as well you have request the relevant scope which over websocket requires a user access token so the scope needed is user:write:chat

1 Like

so i ask permission

        document.getElementById('authorize').setAttribute('href', 'https://id.twitch.tv/oauth2/authorize?client_id=' + client_id + '&redirect_uri=' + encodeURIComponent(redirect) + '&response_type=token&scope=user:read:chat+user:write:chat');

and need to bake a function for send message, i try it

works, i create a simple response to “!word” and is interesting
thank you i save your repository

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.