Search code examples
pythonchatbotsircmessage

Python IRC bot for Twitch receiving two messages in one output


So I've created a Chat bot for Twitch.tv which has been working fine for multiple months until a couple of days ago. Either the chat is too flooded or twitch changed something with the way they send messages. Either way, in every message received I add a new line when printing into the console and some messages do not have this added line, which means multiple messages can fit in one irc.recv(). I tried editing the size of the recv, but haven't had any success. This is an image of the print that the irc.recv() gives, in case it helps.

https://i.sstatic.net/pWeGt.jpg

If you look at the middle, you'll see that the two messages does not have a space between them which means if the second person would do something bannable, the first user would be banned.

And as you can see it could be easy to separate messages by following the ":nick!nick@nick.tmi.twitch.tv PRIVMSG #channel :", but it could also be easy for someone who understands this design to abuse the bot and timeout anyone.

What I hope to achieve is a way to modify the irc.recv() so that it only and always receives exactly one message.

Here are a couple of snippets of the code to get a better understanding of what is going on.

# -*- coding: utf-8 -*-
import socket
import threading
import datetime
import time


bot_owner = 'asd'
nick = 'asdrobot' 
channel = '#asd'
server = 'irc.twitch.tv'
password = 'asd' #login authentication

global irc
irc = socket.socket()
irc.connect((server, 6667)) #connects to the server
irc.send('PASS ' + password + '\r\n')
irc.send('USER ' + nick + ' 0 * :' + bot_owner + '\r\n')
irc.send('NICK ' + nick + '\r\n')
irc.send('JOIN ' + channel + '\r\n')

while True:
        senderdata = irc.recv(1024) #gets output from IRC server
        sendermessage = ''      #Empties variable
        senderuser = ''         #Empties variable
        senderusertemplist = [] #Empties variable
        if(senderdata.find('PRIVMSG') != -1): 
              print senderdata
              try:
                   senderuser = senderdata.split(':')[1]
                   senderuser = senderuser.split('!')[0] #determines the sender of the messages
              except IndexError as e:
                   senderuser = 'ERRORERROR'
                   print 'can not split this data'
                   print e
              sendermessage = senderdata.split(channel)[-1]
              sendermessage = sendermessage.split(':', 1)[-1]
              sendermessagelow = sendermessage.lower()

These are just the most important pieces, and by the time the code reaches this point, the problem has already occurred.

If there is no way to "fix" the problem and it's part of how IRC works I'd love to know, but if you know a way to fix it I'd be extremely grateful.

Thank you.


Solution

  • I decided to go with the performance > security since security in this case isn't that much of a big deal. Here is how I solved it:

    senderdata = irc.recv(2048) #gets output from IRC server
        linecount = senderdata.count('\r\n')
        if(linecount == 1):
            print senderdata
            print "Single message"
            tryComment(senderdata)
        elif(senderdata.find('tmi.twitch.tv JOIN ' + channel) != -1):
            print linecount-1, 'People joined'
        elif(senderdata.find('tmi.twitch.tv PART ' + channel) != -1):
            print linecount-1, 'People left'
        elif(linecount > 1):
            print "Multiple messages"
            messagelist = []
            messagelist = senderdata.split('\r\n')
            print len(messagelist)
            for i in range(0, len(messagelist)):
    
                if (len(messagelist[i]) > 0):
                    print messagelist[i]
                    tryComment(messagelist[i])
                    print "message number: "
                    print i
                else:
                    print "This message is empty"
                    print i
    

    And if someone is trying to replicate this "solution" the "tryComment()" is the original main loop which checks the message. The checking function is ignored if it's someone who joined, someone who left or if the message is empty.