An async IRC bot framework for Rust powered by Tokio and procedural macros.
use ircbot::{bot, Context, User, Result};
#[bot]
impl MyBot {
#[command("ping")]
async fn ping(&self, ctx: Context) -> Result {
ctx.reply("Pong!")
}
#[on(message = "you are *")]
async fn praise_me(&self, ctx: Context) -> Result {
ctx.say("Correct.")
}
#[on(event = "JOIN")]
async fn welcome(&self, ctx: Context, user: User) -> Result {
ctx.say(format!("Welcome, {}!", user.nick))
}
#[on(cron = "0 0 9 * * MON-FRI", target = "#general")]
async fn morning(&self, ctx: Context) -> Result {
ctx.say("Good morning!")
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
MyBot::new("mybot", "localhost:6667", ["general"])
.await?
.main_loop()
.await
}- Proc-macro API — annotate methods with
#[command]or#[on];#[bot]wires everything up. - Typed state —
#[bot(state = MyState)]adds apub statefield your handlers can read; mutate it through interior mutability (Mutex/atomics). Seeexamples/stateful_bot.rs. - Flexible triggers — commands (
!ping), glob patterns ("you are *"), raw IRC events, mention detection, cron schedules — all with optional target-channel and regex filters. - Reply helpers —
ctx.reply(),ctx.say(),ctx.action(),ctx.notice(),ctx.whisper(). - Channel control —
ctx.join()andctx.part()to make the bot enter or leave channels from a handler. - Raw escape hatch —
ctx.raw()sends any IRC line the helpers don't wrap (MODE,INVITE, …), still sanitized. - Moderation —
ctx.set_topic()andctx.kick()act on the channel the message arrived in. - Message accessors —
ctx.nick(),ctx.is_from_self(),ctx.mentions_me()to inspect who sent a message and what it says. - Keepalive & auto-reconnect — periodic
PING/PONGmonitoring; reconnects and re-joins on drop. If the configured nick is already in use, the bot automatically retries with a suffixed alternative (bot,bot_, …). - Hot reload (Unix) —
SIGHUPexecs the new binary with the live TCP socket inherited; no reconnect, no missed messages. - Flood protection — token-bucket rate limiter (default: burst 4, 1 msg / 500 ms).
- Auto message splitting — long messages are word-wrapped and split within the 512-byte IRC limit.
- Output sanitization —
\r,\n,\0stripped from every outgoing message. - Unit-testable —
ircbot::testing::TestContextlets you test handlers without a live server. - Structured logging — diagnostics are emitted through
tracing; you pick the subscriber, level, and format. Raw IRC traffic is available opt-in on theircbot::protocoltarget.
Full API reference: docs.rs/ircbot
[dependencies]
ircbot = "0.2"
tokio = { version = "1", features = ["full"] }See the basic_bot example and the docs for the complete API, hot-reload guide, testing helpers, and lower-level State / internal APIs.
The framework emits structured tracing events and
installs no subscriber of its own, so verbosity, format, and destination are
yours to configure. Raw IRC traffic is available opt-in on the ircbot::protocol
target.
See the logging module docs
for subscriber setup and the raw-protocol opt-in.
MIT
This project was written primarily by AI, orchestrated, supervised and reviewed by a human (me). Feel free to use any AI tool for contributions to this project.