This is a modular, plugin-based IRC bot written in Python. Plugins can bedynamically loaded and unloaded at runtime. A design goal is the abillity to develop plugins without being able to crash the bot.
Plugins have a simple, easy to pick up API. All events, commands, and triggers use a simple decorator convention.
Clone with: git clone --recursive https://github.com/jkent/pybot.git
Pybot is designed and tested to run under Python 3. Python 2 is no longer supported. Dependencies are listed in requirements.txt
.
You need to copy config.yaml.example
to config.yaml
and edit it to your liking.
The below examples in the Plugins section assume directed_triggers
is False
. Directed triggers start with the bot's name, followed by a colon or comma, and finally the command and any arguments. The other option, classic triggers, take a ! followed by the command and any arguments. The default option is to use directed triggers, so multiple bots can peacefully coexist.
-
config.yaml:
my_network: host: localhost port: 6667 ssl: false plugins: base: connect_password: null nickname: pybot username: pybot realname: Python IRC bot - http://git.io/M1XRlw nickserv_password: null channels: - '#dev'
Pybot can be run as either a package or using its pybot.py script. It also comes with a shell script, run.sh
that will setup a python virtual environment and dependencies for you.
This plugin will fetch and reply with the og:title or title of a HTML document.
-
Configuration:
anyurl: blacklist: - '^https://www.google.com/.*$'
This plugin handles some of the core behaviors of the bot, such as setting the nick, joining channels, and auto-reconnect. Its required, please don't unload it unless you know what you're doing.
-
Configuration:
base: nickname: pybot channels: - #dev - #UnderGND
A fun yet frustrating plugin that gives random responses.
-
Usage:
should I|<nick> <question>? !choose a or b, c.
This plugin allows configuration reloading. Usage is limited to level 1000.
-
Usage:
!config reload
This plugin prints all IRC traffic and module events while loaded.
-
Usage:
!raw <message> !eval <code>
Raw lets you send a raw IRC message, and requires permission level 900 and up. Eval is a dangerous feature that allows arbitrary execution of python code, and usage requires permission level 1000 and up.
This plugin will show information about GitHub users and repos when a url is linked within a channel. jrspruitt was the original author, rewritten by jkent.
-
Usage:
<url>
The math plugin is a nifty calculator that has support for functions and variables. Its state is saved in a database as workbooks which can be switched out as needed.
-
Usage:
!math [expr] !math var=[expr] !math func([var[, ...]])=[expr] !math workbook [name] !math varlist !math funclist !math describe <funcname> [description]
An offline/delayed message facility.
-
Usage:
!message send <nick> <message> [as dm] [in timespec] !message ack !message del <num> !message list [nick] !message block <nick> !message unblock <nick> !message opt <in | out>
Manage bot permissions. Usage is limited to level 1000.
-
Config:
perms: superuser: me!root@localhost
-
Usage:
!perms list !perms allow [-]<mask> [<plugin>=<n>] !perms deny [-]<mask> [<plugin>=<n>]
Where plugin is the name of a plugin and n is the level to set. Plugin can be the special constant ANY.
Load, unload, reload plugins at runtime. Usage is limited to level 1000.
-
Usage:
!plugin load <name> !plugin reload [!]<name> !plugin unload [!]<name> !plugin list
For reload and unload, the "bang" means force. Use with caution.
Choose a random song from a song database.
-
Usage:
!song !song add <artist> - <title> !song delete !song fix artist <artist> !song fix title <title> !song last !song load <data-file> !song search <query> !song stats !song who !song [youtube|yt] <youtube-url> !song [youtube|yt] delete
Allow users to set the topic with a minimum age.
-
Configuration:
topic: min_age: 24h min_level: 100 bypass_level: 900
-
Usage:
!topic apply !topic set <topic>
If permissions or min_age not met, apply can be used to override and apply the last proposed topic by anyone with bypass_level or higher.
Parse URLs, get latest user tweet, and search keywords on Twitter. Configuration requires Twitter account and application setup:
-
Configuration:
twitter: apikey: <api key> secret: <api secret> auth_token: <auth token> auth_secret: <auth secret>
-
Usage:
<url> !twitter user <@user_id> !twitter search <keyword>
Here's a simple "Hello world" style plugin:
from pybot.plugin import *
class Plugin(BasePlugin):
@hook
def hello_trigger(self, msg, args, argstr):
msg.reply('Hello %s!' % (argstr,))
You would call the trigger on IRC via either:
!hello world
or if directed (conversational) style triggers are enabled:
pybot, hello world
To which the bot would reply:
<pybot> Hello world!
There are five types of hooks:
- event
- command
- trigger
- timestamp
- url
All except for timestamp hooks can be used via the @hook
decorator. @hook
is a smart decorator that uses the naming convention of your method to determine the name and type of the hook. Alternatively, it can be called as @hook(names)
and @hook(type, names)
.
Timestamp hooks can be created 3 different ways: one-shot timeouts, one-shot timers, and repeating intervals. They are discussed in more detail with the Bot class.
Anything that you may need to access should be accessable from the bot class. Plugins get a reference to the bot instance they are running on (self.bot
).
var | description |
---|---|
channels |
A dict with keys being channels, value is a dict with keys 'joined' and 'nicks' |
core |
The core instance the bot is running under |
hooks |
An instance of the HookManager class |
nick |
A string identifying the bot's current nickname |
plugins |
An instance of the PluginManager class |
allow_rules |
Allow rules for the permission system |
deny_rules |
Deny rules for the permission system |
method | description |
---|---|
set_interval(fn, seconds[, owner]) |
Install timestamp hook, calls fn every seconds |
set_timeout(fn, seconds[, owner]) |
Install timestamp hook, calls fn after seconds |
set_timer(fn, timestamp[, owner]) |
Install timestamp hook, calls fn at timestamp |
join(channels[, keys]) |
Convenience method for JOIN |
notice(target, text) |
Convenience method for NOTICE |
part(channels[, message]) |
Convenience method for PART |
privmsg(target, text) |
Convenience method for PRIVMSG |
method | description |
---|---|
bind(fn[, owner]) |
Binds a hook in preparation to install |
method | description |
---|---|
install(hook) |
Install a bound hook |
uninstall(hook) |
Uninstall hook |
call(hooks, *args) |
Call hooks using as many args as possible |
find(model) |
Search for hooks by model hook instance |
modify(hook) |
Context manager for modifying installed hooks |