123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- # vIRCBot, a simple IRC bot
- #
- # Copyright (C) 2022 Ferass EL HAFIDI <vitali64pmemail@protonmail.com>
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero General Public License as
- # published by the Free Software Foundation, either version 3 of the
- # License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
- # Import Miniirc
- import miniirc
- from miniirc_extras import *
- # Required for messages delay (0.5 secs delay or else its connection
- # becomes unstable for some reason)
- import time
- # Import configs
- from bot_config import *
- # Import things required for indexing URLs
- import re
- from urllib.request import urlopen
- from html import unescape # For unescaping html (
- # This works only with version >= 1.4.0 of miniirc
- assert miniirc.ver >= (1, 4, 0), "vIRCBot requires miniirc >= v1.4.0."
- # Create a miniirc 'irc' object
- irc = miniirc.IRC(server, serverport, nick, channels, ns_identity=nickserv, debug=True)
- print("Welcome to vIRCBot!")
- # Define receivedTellMsg
- receivedTellMsg = True
- # Send messages the convienient way
- def ircSendMSG(channel, message):
- time.sleep(0.5)
- irc.send('PRIVMSG', channel, message)
- # Help message
- def helptext(channel):
- helptext = [
- " )introduce : Introduce myself.",
- " --- Join and leave ---",
- " invite <bot> <channel> : Join a channel.",
- " [%s] )part : Leave this channel." % cmd_part,
- " --- Echo messages ---",
- " [%s] )echo message : Echo a message in this channel." % cmd_echo,
- " [%s] )chanecho message>><pm/chan> : Echo a message in a pm/channel." % cmd_chanecho,
- " [%s] )quackecho : You guessed it!" % cmd_quackecho,
- " [%s] )tell user << message : Tell someone something " % cmd_tell,
- " as soon as they send a message.",
- " --- Channel management ---",
- " [%s] )op <user> : OP a user." % chan_management,
- " [%s] )kick <user> : KICK a user." % chan_management,
- " --- Bot configuration ---",
- " )config <config option> : WIP!",
- " )nick <nick> : Change nick."
- ]
- i=0
- for text in helptext:
- time.sleep(0.5)
- ircSendMSG(channel, helptext[i])
- i=i+1
- @miniirc.Handler('PRIVMSG', colon=False)
- def help(irc, hostmask, args):
- text = args[-1]
- words = args[-1].split(" ")
- t = text.lower()
- w = [x.lower() for x in words]
- channel = args[0]
- # Support relay bots
- if "[" + words[0][words[0].find("[")+1:words[0].find("]")] + "]" in words[0]:
- if "<" + words[1][words[1].find("<")+1:words[1].find(">")] + ">" in words[1]:
- words.pop(0)
- words.pop(0)
- command = words[0].lower()
- if command.startswith(")help"):
- ircSendMSG(channel, "Hi! My name is %s! I'm powered by vIRCBot, " % irc.nick
- + "a libre software made by vitali64! "
- "If you have any issues, you can contact my owner. "
- "His name is %s." % owner[0]
- + "If you want to see available commands, say ')commands'. "
- "The source code is located here: %s."
- % sourcecodeurl)
- elif command.startswith(")commands"):
- ircSendMSG(channel, "%s: I've sent a list of commands on a PM." % hostmask[0])
- helptext(hostmask[0])
- # Handle invites
- @miniirc.Handler('INVITE', colon=False)
- def invite(irc, hostmask, args):
- channel = args[-1].split(" ")[0]
- time.sleep(5)
- irc.send('JOIN', channel)
- ircSendMSG(channel, "Hello! I'm a bot! Someone told me to "
- + "join this channel so I did. "
- + "If you want me to leave, say ')part'"
- + " while being op.")
- # Here goes your own features.
- # For adding one, you can add something like this:
- # if command.startswith(")mycommand"): Verifies if your message starts with
- # your command
- # ircSendMSG('PRIVMSG', channel, "my message!") Sends a message
- # irc.send('NICK', "nick_change_time_XD") Changes the bot's nickname
- @miniirc.Handler('PRIVMSG', colon=False)
- def customFeatures(irc, hostmask, args):
- text = args[-1]
- words = args[-1].split(" ")
- w = [x.lower() for x in words]
- channel = args[0]
- # Support relay bots
- if "[" + words[0][words[0].find("[")+1:words[0].find("]")] + "]" in words[0]:
- if "<" + words[1][words[1].find("<")+1:words[1].find(">")] + ">" in words[1]:
- words.pop(0)
- words.pop(0)
- command = words[0].lower()
- if channel.startswith("#"):
- ops = irc.chans[channel].modes.getset("o")
- isChannel = True
- else:
- isChannel = False
- # Some built-in commands
- if command.startswith(")help"):
- # Help message (since we already have a function
- # for that, we just say 'pass'.
- pass
- elif command.startswith(")nick") and hostmask[1] == owner[1]:
- ircSendMSG(channel, "Changing nick ...")
- irc.send('NICK', words[1])
- elif command.startswith(")config"):
- # Currently doesn't work at all :^)
- ircSendMSG(channel, "Please note that this command is a WIP!")
- elif command.startswith(")introduce") or command.startswith(nick):
- # Introduce itself
- ircSendMSG(channel, "Hello! I'm a bot. Type )help for more details.")
- elif command.startswith(")join") and cmd_join == "on":
- pass
- # # Join channels
- # ircSendMSG(channel, "Joining %s" % words[1])
- # irc.send('JOIN', words[1])
- # ircSendMSG(words[1], "Hello! I'm a bot! Someone told me to")
- # ircSendMSG(words[1], "join this channel so I did.")
- # ircSendMSG(words[1], "If you want me to leave, say ')part'.")
- elif command.startswith(")echo") and cmd_echo == "on":
- # Echo messages
- ircSendMSG(channel, "%s" % args[-1].split("//////")[0].replace(")echo", "Echo:"))
- elif command.startswith(")chanecho") and cmd_chanecho == "on":
- # Echo messages in other rooms
- if isChannel == True:
- ircSendMSG(args[-1].split(">>")[1], "%s" %
- args[-1].split(">>")[0].replace(")chanecho",
- "Message from %s: "
- % hostmask[0]))
- elif command.startswith(")mysteriouschanecho") and cmd_chanecho == "on":
- # Echo messages in other rooms
- if isChannel == True:
- ircSendMSG(args[-1].split(">>")[1], "%s" %
- args[-1].split(">>")[0].replace(")mysteriouschanecho",""))
- elif command.startswith(")part") and cmd_part == "on":
- # Leave the current channel
- if isChannel != True:
- # If it's a PM, don't do anything
- ircSendMSG(channel, "You need to be in a channel to do that.")
- elif hostmask[0] in ops:
- # If the one running the command is OP, leave
- ircSendMSG(channel, "Goodbye!")
- irc.send('PART', channel, "Requested by %s" % hostmask[0])
- else:
- # Else, complain about them not being op
- ircSendMSG(channel, "You do not have permission to do this.")
- elif command.startswith(")kick") and chan_management == "on":
- # Kick a user
- if isChannel != True:
- # If the bot isn't on a channel, don't do anything
- ircSendMSG(channel, "You need to be in a channel to do that.")
- elif hostmask[0] in ops:
- # If the one running the command is OP, kick the specified user
- ircSendMSG(channel, "Kicking %s" % words[1])
- irc.send('KICK', channel, words[1],
- "You annoyed everyone here, please sit down and relax for a second")
- else:
- # Else, complain about the one running the command that they're not OP
- ircSendMSG(channel, "You do not have permission to do this.")
- elif command.startswith(")op") and chan_management == "on":
- # OP a user
- if isChannel != True:
- # It's dumb to op someone in a PM
- ircSendMSG(channel, "You need to be in a channel to do that.")
- elif hostmask[0] in ops:
- # If the one running the command is themselves OP, do it
- ircSendMSG(channel, "Giving OP to %s" % words[1])
- irc.send('MODE', 'o', words[1])
- else:
- # Else, complain
- ircSendMSG(channel, "You do not have permission to do this.")
- elif command.startswith(")quackecho") and cmd_quackecho == "on":
- # QUACK?!Echo XD
- ircSendMSG(channel, "QUACK?!ECHO: º·.º ·.º· º·..º·. \\_o< %s?!" % words[1])
- elif "http://" in text or "https://" in text:
- # The way of doing it may change in the future
- foundURL = False
- i=0
- while foundURL == False:
- if words[i].startswith("http"):
- url = words[i]
- foundURL = True
- html_string = str(urlopen(url).read())
- match = re.search('<title>(.*?)</title>', html_string)
- title = unescape(match.group(1)) if match else False
- if title != False: # If a title is detected, print it.
- # Also unescape it (')amp;' -> ')')
- ircSendMSG(channel, "Title: %s" % title)
- else:
- i=i+1
- elif command.startswith(")tell") and cmd_tell == "on":
- global tellMessage # Global variables that are accessible everywhere
- global tellUser # Needed for the handleTellMessages function to
- global receivedTellMsg # Work.
- global sentByUser
- if hostmask[0] == words[1]:
- ircSendMSG(channel, "%s: You can tell yourself that." % hostmask[0])
- elif words[1] == irc.nick:
- ircSendMSG(channel,
- "%s: I'm already there, you can tell me everything!" % hostmask[0])
- elif "<<" not in args[-1]:
- ircSendMSG(channel,
- "%s: Usage: )tell user << message" % hostmask[0])
- else:
- tellMessage = args[-1].split("<<")[-1]
- tellUser = words[1]
- receivedTellMsg = False
- sentByUser = hostmask[0]
- ircSendMSG(channel, "%s: I'll tell %s that when they're around." % ( hostmask[0], tellUser ))
- # Tell people about things (?)
- @miniirc.Handler('PRIVMSG', colon=False)
- def handleTellMessages(irc, hostmask, args):
- global receivedTellMsg
- global tellUser
- global tellMessage
- global sentByUser
- channel = args[0]
- if receivedTellMsg == False and hostmask[0] == tellUser:
- receivedTellMsg = True
- ircSendMSG(channel, "%s: %s wanted to tell you this:%s"
- % ( hostmask[0], sentByUser, tellMessage ))
- # If a user connects, welcome them
- @miniirc.Handler('JOIN', colon=False)
- def welcomeUser(irc, hostmask, args):
- channel = args[0]
- if hostmask[0] != irc.nick and welcome_user == "on":
- # This checks if the one who joined isn't actually the bot and also if
- # the option to greet the user is enabled.
- ircSendMSG(channel, "Hello %s, welcome to this channel!" % hostmask[0])
- ircSendMSG(channel, introduction)
- # If the script is being run directly, do this:
- if __name__ == '__main__':
- # Usual IRC shenanigans
- irc.require("users")
- irc.require("chans")
- irc.connect()
- irc.wait_until_disconnected()
|