Search code examples
pythonnetwork-programmingbotsircchannel

Python IRC Bot, distinguish from channel messages and private messages


I'm coding a simple IRC bot in Python. Actually, It can connect to a specific channel, read messages and send response, but it can't distinguish between channel messages and private messages.

Example:
John, connected to the same channel, send a private message to the Bot's chat, like "!say hello"; Bot have to send "hello" to the same private chat, only to John.
Instead, when bot read "!say hello" in channel's board, have to send "hello" to the channel.

My code:

ircmsg = connection.ircsock.recv(2048)
ircmsg_clean = ircmsg.strip(str.encode('\n\r'))
if ircmsg.find(str.encode("!say")) != -1:
    try:
        parts = ircmsg_clean.split()
        content = parts[4]
        connection.sendMsg(channel, content)
    except IndexError:
        connection.sendMsg(channel, "Invalid syntax")

Connection file:

def sendmsg(channel, msg):
ircsock.send(str.encode("PRIVMSG " + channel +" :" + msg + "\n"))

I know how to send a message to a specific user:

def sendPrivateMsg(username, msg):
ircsock.send(str.encode("PRIVMSG " + username + " :" + msg + "\n"))

But have to know from where the message came, channel or user, and send appropriate response.

Sorry for my bad english.


Solution

  • The source of the message is included in the protocol message, now you are just not using it.

    In the part where you do this

    parts = ircmsg_clean.split()
    

    you get it in to the list parts.

    If I remember correctly, and understand the RFQ right, the irc message you receive from the server looks something like this:

    :[email protected] PRIVMSG BotName :Are you receiving this message ?

    so splitting that would result in this:

    [':[email protected]', 'PRIVMSG', 'BotName', ':Are', 'you', 'receiving', 'this', 'message', '?']
    

    The sender of the message is that the first element parts, so parts[0]. You would need to strip away the extra ':'.

    The target of the message is at parts[2], and that can be your name or the channel name, and you then need to compare the target to your own name to know if it is a message to you or to a channel.

    If that is true, you can then do something like this:

    source = parts[0].strip(':')
    content = ' '.join(parts[3:]).strip(':')
    connection.sendMsg(source, content)
    

    Notice that the actual content of the message is also splitted, so you need to rejoin that into a string if you are doing it like that. If you are hitting that IndexError it means that you received a message that had only one word, since the first word is at index 3, not 4.