feat: initial implementation
Asyncio IRC bot with decorator-based plugin system. Zero external dependencies, Python 3.11+. - IRC protocol: message parsing, formatting, async TCP/TLS connection - Plugin system: @command and @event decorators, file-based loading - Bot orchestrator: connect, dispatch, reconnect, nick recovery - CLI: argparse entry point with TOML config - Built-in plugins: ping, help, version, echo - 28 unit tests for parser and plugin system
This commit is contained in:
97
docs/USAGE.md
Normal file
97
docs/USAGE.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# 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 <cmd>` | Show help for a specific command |
|
||||
| `!version` | Show bot version |
|
||||
| `!echo <text>` | Echo back text (example plugin) |
|
||||
|
||||
## 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 |
|
||||
Reference in New Issue
Block a user