2016-07-13 111 views
0

我有一個greasemonkey腳本,根據來自特定抽搐通道上聊天bot的悄悄話消息來調整Twitch.tv的某些元素。我的目標是觀察耳語聊天,閱讀每個新的whipser消息,相應地做一些調整,然後關閉聊天窗口,以便我看不到我耳語。使用Greasemonkey閱讀抽搐悄悄話消息

我並不熟悉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> 

一般來說,在這一刻,我只想通過

var allChatMessages = document.getElementsByClassName("conversation-chat-line"); 
var newestChatMessage = allChatMessages[allChatMessages.length - 1]; 

這工作somtimes採取conversation-chat-line類的最後一個元素,但是是怎麼樣的不可靠,因爲似乎有時會有多堆消息到達一個DOM更新(這是否合理?)。正如我注意到的那樣,我想出了一個更加複雜的想法,它更加可靠,但似乎仍然經常失敗。

我的工作方式大致4個步驟:

1)如果這是本次會議的第一個新的耳語(LastWhisperTitle仍然是空的),那麼出發點必須被發現。爲此,我嘗試在twitch聊天窗口中找到新的低語消息(類new-message-divider)中的分隔符元素。從那裏開始,我嘗試在此之前獲取聊天消息,並將此消息的title屬性和消息文本存儲爲(我不能使用id屬性,因爲它在耳語窗口關閉並重新打開時發生變化)這一步只做一次

2)現在我向後迭代所有聊天消息,直到達到最後一個由兩個變量(標題和消息文本)標識。要獲取我使用的所有聊天消息,請使用getElementsByClassName。我存儲這個最新消息的索引,並從步驟3)開始。

3)具有第一個新聊天消息的索引,我開始迭代轉發並按順序解析每條消息。

4)讀取新消息時關閉耳語窗口。 (有條件的只是允許手動打開私聊窗口時,沒有新的消息到達)

這裏是最後mehtod:

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

} 

我仍然有,在所有隻有一些或沒有耳語消息被讀取的問題。我的方法有什麼問題?

+0

沒有現場實例很難說。你能告訴我們如何在抽搐中打開低語聊天嗎? – wOxxOm

+0

由於Twitch在燼中實現它的方式,我們在BetterTTV中實施更多竊竊私語的問題很多。我不確定你在這裏做什麼,但是如果它需要修改DOM中的竊竊私語,你將不會有美好的時光。我們發現即使是小小的變化也會讓整個事情崩潰。 – Teak

回答

0

我似乎發現了這個問題。我的方法本身基本上工作,唯一的問題是,當多個耳語對話被打開時,所有都變成越野車,因爲我使用整個document上的document.getElementsByClassName("conversation-chat-line");,它也將來自其他用戶(不僅是抽動機器人)的對話中的消息。這會混淆LastWhisperTitleLastWhisperMessage的值。

解決的辦法是把這個代碼在我的函數的開頭:

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 

,然後我就不得不更換documentcurrentConversation和它的作品。