# Usage Guide ## Running ```bash # From project directory derp # With options derp --config /path/to/derp.toml --verbose ``` ## CLI Flags | Flag | Description | |------|-------------| | `-c, --config PATH` | Config file path | | `-v, --verbose` | Debug logging | | `-V, --version` | Print version | | `-h, --help` | Show help | ## Configuration All settings in `config/derp.toml`: ```toml [server] host = "irc.libera.chat" # IRC server hostname port = 6697 # Port (6697 = TLS, 6667 = plain) tls = true # Enable TLS encryption nick = "derp" # Bot nickname user = "derp" # Username (ident) realname = "derp IRC bot" # Real name field password = "" # Server password (optional) [bot] prefix = "!" # Command prefix character channels = ["#test"] # Channels to join on connect plugins_dir = "plugins" # Plugin directory path [logging] level = "info" # Logging level: debug, info, warning, error ``` ## Built-in Commands | Command | Description | |---------|-------------| | `!ping` | Bot responds with "pong" | | `!help` | List all available commands | | `!help ` | Show help for a specific command | | `!help ` | Show plugin description and its commands | | `!version` | Show bot version | | `!echo ` | Echo back text (example plugin) | | `!cert [...]` | Lookup CT logs for up to 5 domains | | `!load ` | Hot-load a plugin from the plugins directory | | `!reload ` | Reload a plugin, picking up file changes | | `!unload ` | Unload a plugin, removing its handlers | | `!plugins` | List loaded plugins with handler counts | ### Command Shorthand Commands can be abbreviated to any unambiguous prefix: ``` !h -> !help (unique match) !pi -> !ping (unique match) !p -> error: ambiguous (ping, plugins) ``` Exact matches always take priority over prefix matches. ### `!cert` -- Certificate Transparency Lookup Query [crt.sh](https://crt.sh) CT logs to enumerate SSL certificates for domains. Reports totals (expired/valid) and flags domains still serving expired certs. ``` !cert example.com !cert example.com badsite.com another.org ``` Output format: ``` example.com -- 127 certs (23 expired, 104 valid) badsite.com -- 45 certs (8 expired, 37 valid) | live cert EXPIRED broken.test -- error: timeout ``` - Max 5 domains per invocation - crt.sh can be slow; the bot confirms receipt before querying - Live cert check runs only when expired CT entries exist ## Plugin Management Plugins can be loaded, unloaded, and reloaded at runtime without restarting the bot. ``` !load crtsh # Hot-load a new plugin from plugins/ !reload crtsh # Reload a changed plugin !unload crtsh # Remove a plugin and all its handlers !plugins # List loaded plugins with handler counts ``` The `core` plugin cannot be unloaded (prevents losing `!load`/`!reload`), but it can be reloaded. ## Writing Plugins Create a `.py` file in the `plugins/` directory: ```python from derp.plugin import command, event @command("hello", help="Greet the user") async def cmd_hello(bot, message): """Handler receives bot instance and parsed Message.""" await bot.reply(message, f"Hello, {message.nick}!") @event("JOIN") async def on_join(bot, message): """Event handlers fire on IRC events (JOIN, PART, QUIT, etc.).""" if message.nick != bot.nick: await bot.send(message.target, f"Welcome, {message.nick}") ``` ### Plugin API The `bot` object provides: | Method | Description | |--------|-------------| | `bot.send(target, text)` | Send message to channel or nick | | `bot.reply(msg, text)` | Reply to source (channel or PM) | | `bot.action(target, text)` | Send `/me` action | | `bot.join(channel)` | Join a channel | | `bot.part(channel [, reason])` | Leave a channel | | `bot.quit([reason])` | Disconnect from server | The `message` object provides: | Attribute | Description | |-----------|-------------| | `message.nick` | Sender's nickname | | `message.prefix` | Full `nick!user@host` prefix | | `message.command` | IRC command (PRIVMSG, JOIN, etc.) | | `message.target` | First param (channel or nick) | | `message.text` | Trailing text content | | `message.is_channel` | Whether target is a channel | | `message.params` | All message parameters |