Chat Bot twitch IRC 集成,无法从 NAMES 421 Unknown Command 获得响应
Chat Bot twitch IRC integration, Cannot get a response from NAMES 421 Unknown Command
我已使用 IRC 启动器成功连接到 twitch 聊天 javascript program。
当 运行 程序时,我能够看到发送到我连接的频道的消息,但每当我通过 socket.send('NAMES')
发送 NAMES
信号时,抽搐 returns我一个 421 unknown command
代码。
我真正想知道的是,如何获得频道中当前存在的用户列表?
我对所提供的聊天机器人稍作修改的版本如下:
var chatClient = function chatClient(options){
this.username = options.username;
this.password = options.password;
this.channel = options.channel;
this.server = 'irc-ws.chat.twitch.tv';
this.port = 443;
}
chatClient.prototype.open = function open(){
this.webSocket = new WebSocket('wss://' + this.server + ':' + this.port + '/', 'irc');
this.webSocket.onmessage = this.onMessage.bind(this);
this.webSocket.onerror = this.onError.bind(this);
this.webSocket.onclose = this.onClose.bind(this);
this.webSocket.onopen = this.onOpen.bind(this);
};
chatClient.prototype.onError = function onError(message){
console.log('Error: ' + message);
};
/* This is an example of a leaderboard scoring system. When someone sends a message to chat, we store
that value in local storage. It will show up when you click Populate Leaderboard in the UI.
*/
chatClient.prototype.onMessage = function onMessage(message){
if(message !== null){
var parsed = this.parseMessage(message.data);
if(parsed !== null){
console.log(parsed)
if(parsed.command === "PRIVMSG") {
userPoints = localStorage.getItem(parsed.username);
if(userPoints === null){
localStorage.setItem(parsed.username, 10);
}
else {
localStorage.setItem(parsed.username, parseFloat(userPoints) + 0.25);
}
} else if(parsed.command === "PING") {
this.webSocket.send("PONG :" + parsed.message);
}
}
}
};
chatClient.prototype.message = function message(){
var socket = this.webSocket;
console.log($(".message-text").val())
if (socket !== null && socket.readyState === 1) {
console.log("socket not null")
socket.send("PRIVMSG " + this.channel + " :" + $(".message-text").val() + "\r\n")
console.log("PRIVMSG " + this.channel + " :" + $(".message-text").val())
}
}
chatClient.prototype.names = function names(){
var socket = this.webSocket;
if (socket !== null && socket.readyState === 1) {
socket.send('NAMES')
}
}
chatClient.prototype.onOpen = function onOpen(){
var socket = this.webSocket;
if (socket !== null && socket.readyState === 1) {
console.log('Initializing connection and authenticating...');
console.log('username: ' + this.username);
console.log('password: ' + this.password);
console.log('channel: ' + this.channel);
socket.send('PASS ' + this.password);
socket.send('NICK ' + this.username);
socket.send('JOIN ' + this.channel);
socket.send('CAP REQ :twitch.tv/tags');
socket.send('CAP REQ :twitch.tv/commands');
socket.send('CAP REQ :twitch.tv/membership');
}
};
chatClient.prototype.onClose = function onClose(){
console.log('Disconnected from the chat server.');
};
chatClient.prototype.close = function close(){
if(this.webSocket){
this.webSocket.close();
}
};
/* This is an example of an IRC message with tags. I split it across
multiple lines for readability. The spaces at the beginning of each line are
intentional to show where each set of information is parsed. */
//@badges=global_mod/1,turbo/1;color=#0D4200;display-name=TWITCH_UserNaME;emotes=25:0-4,12-16/1902:6-10;mod=0;room-id=1337;subscriber=0;turbo=1;user-id=1337;user-type=global_mod
// :twitch_username!twitch_username@twitch_username.tmi.twitch.tv
// PRIVMSG
// #channel
// :Kappa Keepo Kappa
chatClient.prototype.parseMessage = function parseMessage(rawMessage) {
var parsedMessage = {
message: null,
tags: null,
command: null,
original: rawMessage,
channel: null,
username: null
};
if(rawMessage[0] === '@'){
var tagIndex = rawMessage.indexOf(' '),
userIndex = rawMessage.indexOf(' ', tagIndex + 1),
commandIndex = rawMessage.indexOf(' ', userIndex + 1),
channelIndex = rawMessage.indexOf(' ', commandIndex + 1),
messageIndex = rawMessage.indexOf(':', channelIndex + 1);
parsedMessage.tags = rawMessage.slice(0, tagIndex);
parsedMessage.username = rawMessage.slice(tagIndex + 2, rawMessage.indexOf('!'));
parsedMessage.command = rawMessage.slice(userIndex + 1, commandIndex);
parsedMessage.channel = rawMessage.slice(commandIndex + 1, channelIndex);
parsedMessage.message = rawMessage.slice(messageIndex + 1);
} else if(rawMessage.startsWith("PING")) {
parsedMessage.command = "PING";
parsedMessage.message = rawMessage.split(":")[1];
}
return parsedMessage;
}
/* Builds out the top 10 leaderboard in the UI using a jQuery template. */
function buildLeaderboard(){
var chatKeys = Object.keys(localStorage),
outputTemplate = $('#entry-template').html(),
leaderboard = $('.leaderboard-output'),
sortedData = chatKeys.sort(function(a,b){
return localStorage[b]-localStorage[a]
});
leaderboard.empty();
for(var i = 0; i < 10; i++){
var viewerName = sortedData[i],
template = $(outputTemplate);
template.find('.rank').text(i + 1);
template.find('.user-name').text(viewerName);
template.find('.user-points').text(localStorage[viewerName]);
leaderboard.append(template);
}
}
显然 Twitch IRCd 不支持请求 NAMES 命令。
但支持加入频道时回复NAMES
你几乎做对了所有事情。
为了获得频道名单并真正加入,您应该先提交您的 CAP 请求,然后加入频道。当服务器响应时,他也会给你频道名称列表。
实际订单
socket.send('CAP REQ :twitch.tv/tags');
socket.send('CAP REQ :twitch.tv/commands');
socket.send('CAP REQ :twitch.tv/membership');
socket.send('JOIN ' + this.channel);
我已使用 IRC 启动器成功连接到 twitch 聊天 javascript program。
当 运行 程序时,我能够看到发送到我连接的频道的消息,但每当我通过 socket.send('NAMES')
发送 NAMES
信号时,抽搐 returns我一个 421 unknown command
代码。
我真正想知道的是,如何获得频道中当前存在的用户列表?
我对所提供的聊天机器人稍作修改的版本如下:
var chatClient = function chatClient(options){
this.username = options.username;
this.password = options.password;
this.channel = options.channel;
this.server = 'irc-ws.chat.twitch.tv';
this.port = 443;
}
chatClient.prototype.open = function open(){
this.webSocket = new WebSocket('wss://' + this.server + ':' + this.port + '/', 'irc');
this.webSocket.onmessage = this.onMessage.bind(this);
this.webSocket.onerror = this.onError.bind(this);
this.webSocket.onclose = this.onClose.bind(this);
this.webSocket.onopen = this.onOpen.bind(this);
};
chatClient.prototype.onError = function onError(message){
console.log('Error: ' + message);
};
/* This is an example of a leaderboard scoring system. When someone sends a message to chat, we store
that value in local storage. It will show up when you click Populate Leaderboard in the UI.
*/
chatClient.prototype.onMessage = function onMessage(message){
if(message !== null){
var parsed = this.parseMessage(message.data);
if(parsed !== null){
console.log(parsed)
if(parsed.command === "PRIVMSG") {
userPoints = localStorage.getItem(parsed.username);
if(userPoints === null){
localStorage.setItem(parsed.username, 10);
}
else {
localStorage.setItem(parsed.username, parseFloat(userPoints) + 0.25);
}
} else if(parsed.command === "PING") {
this.webSocket.send("PONG :" + parsed.message);
}
}
}
};
chatClient.prototype.message = function message(){
var socket = this.webSocket;
console.log($(".message-text").val())
if (socket !== null && socket.readyState === 1) {
console.log("socket not null")
socket.send("PRIVMSG " + this.channel + " :" + $(".message-text").val() + "\r\n")
console.log("PRIVMSG " + this.channel + " :" + $(".message-text").val())
}
}
chatClient.prototype.names = function names(){
var socket = this.webSocket;
if (socket !== null && socket.readyState === 1) {
socket.send('NAMES')
}
}
chatClient.prototype.onOpen = function onOpen(){
var socket = this.webSocket;
if (socket !== null && socket.readyState === 1) {
console.log('Initializing connection and authenticating...');
console.log('username: ' + this.username);
console.log('password: ' + this.password);
console.log('channel: ' + this.channel);
socket.send('PASS ' + this.password);
socket.send('NICK ' + this.username);
socket.send('JOIN ' + this.channel);
socket.send('CAP REQ :twitch.tv/tags');
socket.send('CAP REQ :twitch.tv/commands');
socket.send('CAP REQ :twitch.tv/membership');
}
};
chatClient.prototype.onClose = function onClose(){
console.log('Disconnected from the chat server.');
};
chatClient.prototype.close = function close(){
if(this.webSocket){
this.webSocket.close();
}
};
/* This is an example of an IRC message with tags. I split it across
multiple lines for readability. The spaces at the beginning of each line are
intentional to show where each set of information is parsed. */
//@badges=global_mod/1,turbo/1;color=#0D4200;display-name=TWITCH_UserNaME;emotes=25:0-4,12-16/1902:6-10;mod=0;room-id=1337;subscriber=0;turbo=1;user-id=1337;user-type=global_mod
// :twitch_username!twitch_username@twitch_username.tmi.twitch.tv
// PRIVMSG
// #channel
// :Kappa Keepo Kappa
chatClient.prototype.parseMessage = function parseMessage(rawMessage) {
var parsedMessage = {
message: null,
tags: null,
command: null,
original: rawMessage,
channel: null,
username: null
};
if(rawMessage[0] === '@'){
var tagIndex = rawMessage.indexOf(' '),
userIndex = rawMessage.indexOf(' ', tagIndex + 1),
commandIndex = rawMessage.indexOf(' ', userIndex + 1),
channelIndex = rawMessage.indexOf(' ', commandIndex + 1),
messageIndex = rawMessage.indexOf(':', channelIndex + 1);
parsedMessage.tags = rawMessage.slice(0, tagIndex);
parsedMessage.username = rawMessage.slice(tagIndex + 2, rawMessage.indexOf('!'));
parsedMessage.command = rawMessage.slice(userIndex + 1, commandIndex);
parsedMessage.channel = rawMessage.slice(commandIndex + 1, channelIndex);
parsedMessage.message = rawMessage.slice(messageIndex + 1);
} else if(rawMessage.startsWith("PING")) {
parsedMessage.command = "PING";
parsedMessage.message = rawMessage.split(":")[1];
}
return parsedMessage;
}
/* Builds out the top 10 leaderboard in the UI using a jQuery template. */
function buildLeaderboard(){
var chatKeys = Object.keys(localStorage),
outputTemplate = $('#entry-template').html(),
leaderboard = $('.leaderboard-output'),
sortedData = chatKeys.sort(function(a,b){
return localStorage[b]-localStorage[a]
});
leaderboard.empty();
for(var i = 0; i < 10; i++){
var viewerName = sortedData[i],
template = $(outputTemplate);
template.find('.rank').text(i + 1);
template.find('.user-name').text(viewerName);
template.find('.user-points').text(localStorage[viewerName]);
leaderboard.append(template);
}
}
显然 Twitch IRCd 不支持请求 NAMES 命令。 但支持加入频道时回复NAMES
你几乎做对了所有事情。
为了获得频道名单并真正加入,您应该先提交您的 CAP 请求,然后加入频道。当服务器响应时,他也会给你频道名称列表。
实际订单
socket.send('CAP REQ :twitch.tv/tags');
socket.send('CAP REQ :twitch.tv/commands');
socket.send('CAP REQ :twitch.tv/membership');
socket.send('JOIN ' + this.channel);