IRC¶
The IRC provider uses ergochat/irc-go for connecting to IRC servers.
Installation¶
Configuration¶
import "github.com/plexusone/omnichat/providers/irc"
p, err := irc.New(irc.Config{
Server: "irc.libera.chat:6697",
Nick: "mybot",
Password: "nickserv-password", // Optional
Channels: []string{"#channel1", "#channel2"},
UseTLS: true,
Logger: slog.Default(),
})
Config Options¶
| Field | Type | Required | Description |
|---|---|---|---|
Server |
string |
Yes | IRC server address (e.g., irc.libera.chat:6697) |
Nick |
string |
Yes | Bot nickname |
User |
string |
No | Username (defaults to Nick) |
RealName |
string |
No | Real name field (defaults to Nick) |
Password |
string |
No | NickServ password for authentication |
Channels |
[]string |
No | Channels to join on connect |
UseTLS |
bool |
No | Use TLS encryption (default: true) |
Logger |
*slog.Logger |
No | Logger instance |
IRC Networks¶
Common public IRC networks:
| Network | Server | TLS Port | Website |
|---|---|---|---|
| Libera.Chat | irc.libera.chat |
6697 | libera.chat |
| OFTC | irc.oftc.net |
6697 | oftc.net |
| EFnet | irc.efnet.org |
6697 | efnet.org |
| IRCnet | open.ircnet.net |
6697 | ircnet.org |
Usage¶
Basic Setup¶
package main
import (
"context"
"log/slog"
"os"
"github.com/plexusone/omnichat/provider"
"github.com/plexusone/omnichat/providers/irc"
)
func main() {
logger := slog.Default()
p, err := irc.New(irc.Config{
Server: "irc.libera.chat:6697",
Nick: "mybot",
Password: os.Getenv("IRC_PASSWORD"),
Channels: []string{"#mychannel"},
UseTLS: true,
Logger: logger,
})
if err != nil {
panic(err)
}
router := provider.NewRouter(logger)
router.Register(p)
router.OnMessage(provider.All(), func(ctx context.Context, msg provider.IncomingMessage) error {
return router.Send(ctx, "irc", msg.ChatID, provider.OutgoingMessage{
Content: "Hello from IRC!",
})
})
ctx := context.Background()
router.ConnectAll(ctx)
defer router.DisconnectAll(ctx)
select {}
}
Sending Messages¶
// Send to channel
router.Send(ctx, "irc", "#mychannel", provider.OutgoingMessage{
Content: "Hello, channel!",
})
// Send direct message
router.Send(ctx, "irc", "username", provider.OutgoingMessage{
Content: "Hello via DM!",
})
Joining Channels¶
Channels specified in config are joined automatically on connect. You can also join dynamically:
// Type assertion to access IRC-specific methods
if ircProvider, ok := p.(*irc.Provider); ok {
if err := ircProvider.JoinChannel("#newchannel"); err != nil {
log.Printf("failed to join channel: %v", err)
}
if err := ircProvider.PartChannel("#oldchannel", ""); err != nil {
log.Printf("failed to leave channel: %v", err)
}
}
Message Mapping¶
| IRC | OmniChat |
|---|---|
| Target (channel/nick) | ChatID |
| Timestamp (nanoseconds) | ID |
| Sender nick | SenderID, SenderName |
| Message text | Content |
| Channel (#prefix) | ChatType = ChatTypeChannel |
| Private message | ChatType = ChatTypeDM |
Event Handling¶
The provider handles these IRC events:
Messages (PRIVMSG)¶
router.OnMessage(provider.All(), func(ctx context.Context, msg provider.IncomingMessage) error {
// msg.ChatID is "#channel" for channels, "nick" for DMs
// msg.ChatType is ChatTypeChannel or ChatTypeDM
// msg.Content is the message text
return nil
})
Join/Part Events¶
router.OnEvent(func(ctx context.Context, event provider.Event) error {
switch event.Type {
case provider.EventTypeMemberJoined:
nick := event.Data["nick"].(string)
log.Printf("%s joined %s", nick, event.ChatID)
case provider.EventTypeMemberLeft:
nick := event.Data["nick"].(string)
reason := event.Data["reason"].(string)
log.Printf("%s left %s: %s", nick, event.ChatID, reason)
}
return nil
})
NickServ Authentication¶
Most IRC networks support NickServ for nickname registration:
Register a Nickname (Manual)¶
Connect with a regular IRC client and register:
Configure Password¶
p, err := irc.New(irc.Config{
Server: "irc.libera.chat:6697",
Nick: "registeredbot",
Password: os.Getenv("IRC_PASSWORD"),
// ...
})
The provider sends the password during connection for NickServ identification.
TLS Configuration¶
TLS is enabled by default. To disable (not recommended):
p, err := irc.New(irc.Config{
Server: "irc.example.com:6667", // Non-TLS port
Nick: "mybot",
UseTLS: false,
})
Standard ports:
- TLS: 6697
- Unencrypted: 6667
Message Length Limits¶
IRC has line length limits (~512 bytes including protocol overhead). The provider automatically splits long messages at word boundaries.
Environment Variables¶
IRC_SERVER=irc.libera.chat:6697
IRC_NICK=mybot
IRC_PASSWORD=nickserv-password
IRC_CHANNELS=#channel1,#channel2
Troubleshooting¶
Connection refused¶
- Verify server address and port
- Check if TLS is required (most networks require TLS on port 6697)
- Ensure no firewall blocking
Nickname already in use¶
- Choose a different nickname
- If you own the nickname, configure NickServ password
Cannot join channel¶
- Channel may be invite-only (+i)
- Channel may require registration (+r)
- Contact channel operators
Messages not received¶
- Verify bot has joined the channel
- Check channel modes
- Review logs for errors
Limitations¶
- No message editing or deletion (IRC protocol limitation)
- No threading or replies
- No native media support
- No read receipts or typing indicators
- Message length limits (~400 characters per line)