-
Notifications
You must be signed in to change notification settings - Fork 249
Plugins
Writing plugins for CloudBot is simple! This guide seeks to explain everything you need to do to.
If you have any trouble understanding the guide, come chat with us in the #cloudbot IRC channel on irc.esper.net.
Every plugin written for CloudBot is essentially a python file located in the plugins directory. The plugin must be written in python 3, and the file name must end in .py to be detected by CloudBot.
Each plugin file may contain any number of hooks, to create commands, listen to events, watch input for certain patterns, or control other plugins.
If this is your first time writing plugins for CloudBot, check out the Writing your first command plugin guide.
Here are a few example hook types. We'll go into more detail later, but this lists all the ones you can use
The command hook can be used to register a command in CloudBot.
Here's an example command which will return the input given to it, added to itself.
from cloudbot import hook
@hook.command()
def echo(text):
return text + " " + text
If you want hook to respond to multiple commands, you can pass them as arguments to the hook.
from cloudbot import hook
@hook.command("echo", "hello")
def echo(text):
return text + " " + text
With this example, the hook will be triggered by .echo
or .hello
@hook.regex(myregex)
Takes an argument corresponding to the regex string, or compiled regex, followed by optional flags. Each line of chat is matched against the provided regex pattern; if the bot finds a match, the hooked function will be called with the match object.
Here's an example that will match the regex ^Hi TestBot(!|\?|\.)?$
, and will return Hi!
to the user saying it.
from cloudbot import hook
@hook.regex(r"^Hi TestBot(!|\?|\.)?$")
def hi_hook(match):
return "Hi!"
@hook.irc_raw(myevent)
IRC_RAW hooks are called whenever a specific IRC command is issued. For example, to run some code whenever a user talks, you can use 'PRIVMSG' as the argument. Using '*' as the argument will hook all IRC activity.
Some useful events to hook onto are:
- PRIVMSG - called when a user speaks
- KICK - called when a user is kicked
- NICK - called when a user changes nick
- 004 - called when the bot is connected to the network and ready to accept input
The first argument returned for 'PRIVMSG' be a two-element list of the form ["#channel", "text"]. Details on what other types of event return will be added soon.
Here's an example IRC_RAW hook that will make the bot join two password-protected channels, when the bot starts up.
Note the "conn" argument to this hook. That's optional for hooks, and is just there so that conn.send can be run. We'll go into more detail into it, and other arguments below.
from cloudbot import hook
@hook.irc_raw(“004”)
def onready(paramlist, conn):
conn.send("JOIN #channel1 password1")
conn.send("JOIN #channel2 password2")
@hook.sieve()
All sieve hooks loaded are called whenever before other command, event or regex hook is called. Sieves can be used to control, or filter hooks.
Here's an example sieve which won't let any commands be used in the channel '#channel1'.
Note that any method using @hook.sieve, unlike other hooks, must take exactly 3 arguments.
The first argument is 'bot', the second is 'even', and the third is 'plugin'.
If the sieve returns the same event that it was given, the plugin continues normally. If None
is returned, then the
plugin running is canceled, and the command/regex/event is not run.
from cloudbot import hook
@hook.sieve()
def mysieve(bot, event, plugin):
if plugin.type == "command": # if this is a command
if event.chan == "#channel1": # if the channel is #channel1
return None # return None, canceling the action
return event # return event, so that the command will be run
Part of the cool thing with CloudBot plugin hooks, is that what arguments your plugin is given, depends on the names of the arguments.
So if I define a command, def mycommand(text)
, all it's given is the 'text' argument.
If I define, def mycommand(text, bot, chan)
, then it's given the 'text' argument, the 'bot' argument, and the 'chan'
argument.
This can be done for any hook, except sieve hooks. Sieve hook parameters are fixed, but all other hooks can have dynamic arguments like this.
Here are the different arguments you can ask for, and what they do:
Name | Type | What it is | What hooks can use it |
---|---|---|---|
text | String | Arguments to the command | command |
match | Match | Regex match | regex |
chan | String | Channel the command/regex is in | all |
nick | String | Nick of the user using the command/regex | all |
server | String | Server the command/regex is used on | all |
db | SQLAlchemy database connection | Database connection, more info will be added later | all |
event | Event | "Event" object, containing parameters as attributes | all |
conn | BotConnection | Server-specific connection object | all |
bot | CloudBot | Main bot object | all |
There are also a few functions which you can ask for, and get passed as parameters. They are like the above, but are actually functions, and can be called with name(parameters).
Here are some different methods you can use:
Name | Usage | What it does |
---|---|---|
message | message("hi") | Messages the channel |
reply | reply("hi") | Sends a reply to the channel, prefixed with (Nick) |
action | action("something") | Performs an action in the channel, like /me |
ctcp | ctcp("msg", "VERSION", nick) | Sends a CTCP message to the specified user |
notice | notice("Incorrect args") | Notices a user |
has_permission | has_permission("botcontrol") | Checks if the user has a specified permission (bot-specific) |
Here's an example command which uses the 'message' function to raw message something.
from cloudbot import hook
@hook.command()
def mycmd(text, message):
message("Hi people, someone said '" + text + "'")
Sometimes you want to define a command, but don't want just anyone to have access to it.
You can specify a 'permission' which anyone wanting to use your command will need, by adding a
permissions=["permissionname"]
argument to your @hook.command
. For example, @hook.command(permissions=["botcontrol"])
.
Example command requiring the 'botcontrol' permission:
from cloudbot import hook
@hook.command(permissions=["botcontrol"])
def mycmd(text, message):
message(text)
This command just raw messages the input text. This isn't something you want to give to anyone though, so only people with access to botcontrol can use it.
Permissions are mainly controlled in the config, under each connection object. There are predefined groups, like 'admins', which have certain permissions. 'admins' has access to botcontrol by default, so you can add yourself to it to gain access to this command.
There's also a utility command that you can use to add a user to a group, which can be accessed like so:
<Myself> TestBot, adduser Myself!~myself@my.host.example.com admins
This will add the mask Myself!~myself@my.host.example.com
to the group admins
.