阅读抽搐耳语消息与油脂猴
Reading Twitch Whisper Messages with Greasemonkey
我有一个 greasemonkey 脚本,可以根据特定 twitch 频道上聊天机器人的耳语消息调整 Twitch.tv 的某些元素。我的目标是观察耳语聊天,阅读每条新的鞭打消息,相应地进行一些调整,然后关闭聊天窗口,这样我就不会看到我收到了窃窃私语。
我对Greasemonkey,HMTL或Javascript不太熟悉。我知道这样做的唯一方法是在包含所有耳语窗口(conversation-manager
)的类上使用observeDOM
:
// Observe twitch whisper chat
var whisperArea = document.getElementsByClassName('conversations-manager')[0];
observeDOM( whisperArea ,function(){
NewWhisperMessage();
});
据我所知,观察确实可靠。现在到没有的部分:我的方法NewWhisperMessage
自己。
首先,我想描述一下我的第一个方法。一开始,我试图找到所有新的耳语。收到耳语后,耳语窗口将打开。耳语窗口本身具有多条消息行,如下所示:
<div class="ember-view conversation-chat-line incoming" title="Sat Jul 09 2016 11:52:38 GMT+0200" id="ember2564">
<span style="" class="from">NameOfMessageWriter</span>
<span class="colon">:</span>
<span style="" class="message">
Here is the message!
</span>
</div>
一般来说,此时我只会把类的最后一个元素conversation-chat-line
var allChatMessages = document.getElementsByClassName("conversation-chat-line");
var newestChatMessage = allChatMessages[allChatMessages.length - 1];
这有时有效,但有点不可靠,因为似乎有时会在一个 DOM 更新中到达多个消息(这有意义吗?当我注意到这一点时,我想出了一个更复杂的想法,它工作更可靠,但似乎仍然经常失败。
我的方法大致分为 4 个步骤:
1)如果这是本会话的第一个新耳语(LastWhisperTitle
仍然是空的),那么必须找到一个起点。为此,我尝试在 twitch 聊天窗口中找到分隔符元素,以获取新的耳语消息(第 new-message-divider
类。从那里开始,我尝试在此之前获取聊天消息,并存储title
属性和此消息的消息文本以唯一标识消息(我不能使用 id
属性,因为它在耳语窗口关闭并重新打开时会发生变化)。此步骤仅执行一次。
2)现在我向后迭代所有聊天消息,直到到达由两个变量(标题和消息文本)标识的最后一个消息。要获取所有聊天消息,我使用getElementsByClassName
.我存储此最新消息的索引并从步骤 3) 开始)。
3)有了第一个新聊天消息的索引,我开始向前迭代并按顺序解析每条消息。
4) 阅读新消息时关闭耳语窗口。(条件仅允许在没有新消息到达时手动打开耳语窗口)
这是最后的梅托德:
var LastWhisperTitle = "";
var LastWhisperMessage = "";
var ChannelName = "NameOfChatBot"
function NewWhisperMessage(){
if(LastWhisperTitle == "") {
// New Session: Find first new whisper
// Find new message divider
var newMessageDividerArray = document.getElementsByClassName("new-message-divider");
var newMessageDivider = newMessageDividerArray[newMessageDividerArray.length - 1];
// Find newest message already read
var sibling = newMessageDivider.previousSibling;
while(sibling) {
if(sibling.nodeType == 1) {
if(sibling.className != "undefined"){
if(sibling.className.indexOf("conversation-chat-line") > -1) {
break;
}
}
}
sibling = sibling.previousSibling;
}
if(!sibling){
return;
}
// Store this message as last read whisper
LastWhisperTitle = sibling.title;
LastWhisperMessage = sibling.getElementsByClassName("message")[0].textContent.trim();
}
// Get all messages
var whisperMessageArray = document.getElementsByClassName("conversation-chat-line");
var foundNewMessage = false;
// Find index in array of the first new message
var firstNewMessageIndex = 0;
for(i = whisperMessageArray.length - 1; i >= 0; i--){
var currentWhisper = whisperMessageArray[i];
var currentTitle = currentWhisper.title;
var currentMessage = currentWhisper.getElementsByClassName("message")[0].textContent.trim()
if(currentTitle == LastWhisperTitle && currentMessage == LastWhisperMessage){
// This message was already read -> the message with the previous index is new
if(i == whisperMessageArray.length - 1) {
// No new message
return;
} else {
firstNewMessageIndex = i+1;
break;
}
}
}
if(firstNewMessageIndex == 0){
// No new message
return;
}
// Parse all messages from index to newest message
for( i = firstNewMessageIndex; i < whisperMessageArray.length; i++){
var currentWhisper = whisperMessageArray[i];
var writer = currentWhisper.getElementsByClassName("from")[0].textContent;
var message = currentWhisper.getElementsByClassName("message")[0].textContent.trim();
if(writer == ChannelName){
ParseWhisperMessage(message);
foundNewMessage = true;
}
LastWhisperTitle = currentWhisper.title;
LastWhisperMessage = message;
}
if(foundNewMessage){
// Close Chat Window
CloseWhisperWindow();
}
}
我仍然遇到问题,只阅读一些或根本没有耳语消息。我的方法可能有什么问题?
我似乎发现了问题。我的方法本身基本上有效,唯一的问题是当打开多个耳语对话时,一切都变得有问题,因为我在整个document
上使用document.getElementsByClassName("conversation-chat-line");
,这也将从其他用户(不仅是抽搐机器人)的对话中获取消息。这搞砸了LastWhisperTitle
和LastWhisperMessage
的价值观.
解决方案是将这段代码放在我的函数的开头:
var conversationHeaderNames = document.getElementsByClassName('conversation-header-name');
var currentConversation;
// Find the correct conversation window
for(i = 0; i < conversationHeaderNames.length; i++){
if(conversationHeaderNames[i].innerHTML.trim() == ChannelName){
currentConversation = conversationHeaderNames[i].parentNode.parentNode;
break;
}
}
if(!currentConversation) return; // No conversation with chat bot
然后我只需要用currentConversation
替换document
就可以了。
- Ajax聊天消息重复而不仅仅是更新
- 如果localstorage为空,则显示欢迎消息
- 绑定时将Parsley minlength消息作为选项传递时,未对其进行自定义
- 离开页面时弹出消息
- 有没有一种方法可以在控制台关闭的情况下让console.log()在IE中记录消息
- 消息显示之外的淘汰验证
- 选项卡侦听器未被来自后台脚本的消息激活
- jQuery在输入下验证post错误消息
- Scipt未在选定选项卡中执行以发送和接收消息
- 检查xmlhttprequest问题的消息
- AngularJs对ng消息的自定义替换
- ng消息仅在触摸时显示错误,并在错误的初始显示上转换
- 当用户按下回车键时,自动在text区域/text中插入消息
- 如果消息框答案为YES,则用Javascript填写表单
- 在javaservlet doPost方法中启动线程时,无法返回异常消息
- 解析云代码错误:解析.错误{代码:141,消息:“未调用成功/错误”}
- Node.js上的WebSocket,并在所有连接的客户端之间共享消息
- 在AngularJs中隐藏默认错误消息
- 使用JavaScript安全地发布消息
- 阅读抽搐耳语消息与油脂猴