Event-based stateful IRC client framework for Go.

Overview

Build Status

GoIRC Client Framework

Acquiring and Building

Pretty simple, really:

go get github.com/fluffle/goirc/client

There is some example code that demonstrates usage of the library in client.go. This will connect to freenode and join #go-nuts by default, so be careful ;-)

See fix/goirc.go and the README there for a quick way to migrate from the old go1 API.

Using the framework

Synopsis:

package main

import (
	"crypto/tls"
	"fmt"

	irc "github.com/fluffle/goirc/client"
)

func main() {
	// Creating a simple IRC client is simple.
	c := irc.SimpleClient("nick")

	// Or, create a config and fiddle with it first:
	cfg := irc.NewConfig("nick")
	cfg.SSL = true
	cfg.SSLConfig = &tls.Config{ServerName: "irc.freenode.net"}
	cfg.Server = "irc.freenode.net:7000"
	cfg.NewNick = func(n string) string { return n + "^" }
	c = irc.Client(cfg)

	// Add handlers to do things here!
	// e.g. join a channel on connect.
	c.HandleFunc(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) { conn.Join("#channel") })
	// And a signal on disconnect
	quit := make(chan bool)
	c.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	// Tell client to connect.
	if err := c.Connect(); err != nil {
		fmt.Printf("Connection error: %s\n", err.Error())
	}

	// With a "simple" client, set Server before calling Connect...
	c.Config().Server = "irc.freenode.net"

	// ... or, use ConnectTo instead.
	if err := c.ConnectTo("irc.freenode.net"); err != nil {
		fmt.Printf("Connection error: %s\n", err.Error())
	}

	// Wait for disconnect
	<-quit
}

The test client provides a good (if basic) example of how to use the framework. Reading client/handlers.go gives a more in-depth look at how handlers can be written. Commands to be sent to the server (e.g. PRIVMSG) are methods of the main *Conn struct, and can be found in client/commands.go (not all of the possible IRC commands are implemented yet). Events are produced directly from the messages from the IRC server, so you have to handle e.g. "332" for RPL_TOPIC to get the topic for a channel.

The vast majority of handlers implemented within the framework deal with state tracking of all nicks in any channels that the client is also present in. These handlers are in client/state_handlers.go. State tracking is optional, disabled by default, and can be enabled and disabled by calling EnableStateTracking() and DisableStateTracking() respectively. Doing this while connected to an IRC server will probably result in an inconsistent state and a lot of warnings to STDERR ;-)

Misc.

Sorry the documentation is crap. Use the source, Luke.

Feedback on design decisions is welcome. I am indebted to Matt Gruen for his work on go-bot which inspired the re-organisation and channel-based communication structure of *Conn.send() and *Conn.recv(). I'm sure things could be more asynchronous, still.

This code is (c) 2009-15 Alex Bramley, and released under the same licence terms as Go itself.

Contributions gratefully received from:

And thanks to the following for minor doc/fix PRs:

Issues
  • client/connection: keep information in disconnected event, revert #43

    client/connection: keep information in disconnected event, revert #43

    Revert of https://github.com/fluffle/goirc/commit/3fdd17a2b88b167b0a9ae6d219375bc47cc91f04 of #43. Context: https://github.com/StalkR/goircbot/issues/9

    It's important to keep information on the current connection before dispatching the disconnected event, so that event receivers can make informed decisions about the disconnection, such as saving the current list of channels.

    The original problem encountered by @sztanpet is how to reconnect the bot from the event handler. As replied by @fluffle, don't reconnect at this point, instead send the information back to the main loop with a channel. For examples, see sp0rkle (https://github.com/fluffle/sp0rkle/blob/master/bot/serverset.go#L35) and goircbot (https://github.com/StalkR/goircbot/blob/master/bot/bot.go#L104).

    opened by StalkR 13
  • data race in state tracking

    data race in state tracking

    Nick isn't safe for concurrent access https://github.com/fluffle/goirc/blob/master/state%2Fnick.go#L15

    An example of this issue was reported in https://github.com/StalkR/goircbot/issues/8 where there is a goroutine that checks bot Channels() (a read on Nick), meanwhile the state handling using addChannel (a write on Nick).

    I was thinking we could add a mutex in that struct, then protect access to the members (lock/defer unlock). Thoughts?

    opened by StalkR 13
  • Soft protection against IRC command injection

    Soft protection against IRC command injection

    Hi,

    Command injection on IRC is when a string being sent to the IRC server (nick, privmsg, topic, etc.) contains a "\r" or "\n" followed by another command. This can happen on an IRC client if a user-controlled, not sanitized input is passed to the IRC library. Example: a bot reading URLs, getting page, parsing <title> and displaying it on IRC using Privmsg. A malicious user could forge a web page with <title>test\rNICK owned</title> to send Privmsg with "test" followed by the arbitrary IRC command "NICK owned" so the bot changes nick.

    It would be nice if the library protects against IRC command injection by default. Two solutions: either fail hard (do not send anything) or fail soft (by stripping bad characters \r or \n). I prefer soft in this case and added it in every command except Raw() where we don't want to restrict anything.

    Going further, we could add more checks for instance require channel/nicks to have no space, but not more otherwise we fall into IRC servers implementation differences and it's not the place. This change doesn't do that but let me know if you would be interested.

    Cheers, StalkR

    opened by StalkR 10
  • Support IRCv3 capability negotiation during registration.

    Support IRCv3 capability negotiation during registration.

    http://ircv3.net/specs/core/capability-negotiation-3.1.html http://ircv3.net/specs/core/capability-negotiation-3.2.html

    TL;DR: We need to send a CAP LS before USER and NICK. Not too sure of a final design yet, but one easy way to do it could be to add a []string of capabilities to try and request if the server supports them to the Config struct.

    CAP tls and STARTTLS would require different handling, I'll file a different issue for that.

    opened by fluffle 8
  • Add logic for verifying PONGS from server

    Add logic for verifying PONGS from server

    This will (optionally) check that the PONGs that we get back contain the message that we sent.

    Most (all?) IRCd servers will return the text of your PING back to you in the PONG. This helps in establishing that you have two-way communication with the IRC server.

    Example of successful pings:

    I0530 17:50:58.204800   13341 connection.go:458] Current outstanding pings: 0/3
    I0530 17:50:58.205028   13341 connection.go:537] -> PING :1496166658204835562
    I0530 17:50:58.350480   13341 connection.go:438] <- :rajaniemi.freenode.net PONG rajaniemi.freenode.net :1496166658204835562
    I0530 17:50:58.350625   13341 connection.go:477] Processing Pong: 1496166658204835562
    I0530 17:52:58.204800   13341 connection.go:458] Current outstanding pings: 0/3
    I0530 17:52:58.205012   13341 connection.go:537] -> PING :1496166778204837692
    I0530 17:52:58.350588   13341 connection.go:438] <- :rajaniemi.freenode.net PONG rajaniemi.freenode.net :1496166778204837692
    I0530 17:52:58.350736   13341 connection.go:477] Processing Pong: 1496166778204837692
    I0530 17:54:58.204839   13341 connection.go:458] Current outstanding pings: 0/3
    I0530 17:54:58.205076   13341 connection.go:537] -> PING :1496166898204887198
    I0530 17:54:58.350742   13341 connection.go:438] <- :rajaniemi.freenode.net PONG rajaniemi.freenode.net :1496166898204887198
    I0530 17:54:58.350833   13341 connection.go:477] Processing Pong: 1496166898204887198
    

    Example of failed pings:

    I0530 18:32:58.204795   13341 connection.go:458] Current outstanding pings: 0/3
    I0530 18:32:58.204939   13341 connection.go:537] -> PING :1496169178204836420
    I0530 18:34:58.204774   13341 connection.go:458] Current outstanding pings: 1/3
    I0530 18:34:58.204893   13341 connection.go:537] -> PING :1496169298204803849
    I0530 18:36:58.204881   13341 connection.go:458] Current outstanding pings: 2/3
    I0530 18:36:58.205016   13341 connection.go:537] -> PING :1496169418204910266
    I0530 18:38:58.204813   13341 connection.go:458] Current outstanding pings: 3/3
    I0530 18:38:58.204855   13341 connection.go:571] irc.Close(): Disconnected from server.
    E0530 18:38:58.205027   13341 connection.go:430] irc.recv(): read tcp [2600:3c00::f03c:91ff:fe6e:3a69]:56410->[2001:708:40:2001::f5ee:d0de]:6697: use of closed network connection
    

    This change is Reviewable

    opened by sadbox 7
  • TestPing is unstable...

    TestPing is unstable...

    ...for the reason you expected yourself according to your comments, the 49-51ms window to check for your ping is too tight.

    go test github.com/fluffle/...
    ok      github.com/fluffle/goevent/event        0.578s
    ?       github.com/fluffle/goirc        [no test files]
    --- FAIL: TestPing (0.21s)
            connection_test.go:426: Line not output after another 2ms.
            connection_test.go:440: Line output after ping stopped.
    FAIL
    FAIL    github.com/fluffle/goirc/client 0.313s
    ?       github.com/fluffle/goirc/logging        [no test files]
    ?       github.com/fluffle/goirc/logging/glog   [no test files]
    ok      github.com/fluffle/goirc/state  0.025s
    

    So I'm creating the issue as detailed in the comments (connection_test.go l.422)

    opened by Egojard 7
  • Invalid/expired certificate

    Invalid/expired certificate

    When trying to connect to an IRC server with SSL, I get the following error:

    Connection error x509: certificate has expired or is not yet valid: current time 2022-02-02T23:01:43-05:00 is after 2022-02-01T07:44:35Z

    I suspect the issue might be with the library? I compiled my program, which uses goirc, on two, different operating systems, and I still get the error.

    Any guidance would be appreciated.

    opened by ZG92cnlkCg 6
  • NewNick handler needs a max length check

    NewNick handler needs a max length check

    If you use the NewNick handler and return a nick with a length that's longer than 16 chars, the whole lib breaks, in particular the NAMES/353 responses no longer work and you get ghosts in your code.

    Ask me how I know...

    There should be a doc patch to mention this, and probably some sort of error propagation in here.

    It's possible that 16 is a server specific limit-- I just found this empirically when using Freenode.

    HTH's someone else.

    opened by purpleidea 6
  • Handler timeout

    Handler timeout

    This will (optionally) set an upper limit on fgHandlers and intHandlers so that if something breaks in one of them the IRC client won't hang indefinitely waiting for the DISCONNECTED event.


    This change is Reviewable

    opened by sadbox 6
  • Add IRCv3 tag parsing and CAP command

    Add IRCv3 tag parsing and CAP command

    I needed this for a Twitch bot I'm working on. This adds the CAP command (needed to enable tags), as well as the tag parsing into a map[string]string.

    If a line doesn't have the tag section, then the map is nil as to not have to change other struct initializers in other parts of the code. I didn't add any functions to access the map, as I'm assuming any user would do this themselves, though it would be nice to have some GetTag() function that can check if the map is nil, but anything that uses the library could probably implement that themselves.

    The Cap function takes a subcommand, and an optional list of capabilities. I haven't added any extra constants for things like REQ or LS or similar (should they be added?).

    I also added a few tests for the tagging, and it works in my own tests (connecting to a twitch channel and detecting if someone's a sub or not, etc).

    Let me know if you have any suggestions. This is all I personally need, anyway.

    http://ircv3.net/specs/core/capability-negotiation-3.1.html http://ircv3.net/specs/core/message-tags-3.2.html

    opened by jakebailey 6
  • Fix TestSTRaces panics

    Fix TestSTRaces panics

    since GetNick returns nil, calling methods on it will generate runtime panics (same with GetChannel vs. NewChannel). This might defeat the purpose of the test, in which case it should be changed in a more fundamental way.

    opened by soul9 6
  • disconnect event delay too much

    disconnect event delay too much

    when i reconnect my wifi, after about 260 seconds, another irc client see goirc deamon timeout. but the goirc daemon emit disconnect event after about 15 minutes. want to known is this normal?

    opened by kitech 2
  • Allow rate limiting code to be changed.

    Allow rate limiting code to be changed.

    The rate limit code is hard-coded for hybrid's algorithm currently. Other servers probably use different algorithms. Twitch's "IRC" server won't let you send more than 20 messages in 30 seconds, for example, amusingly this is less conservative than hybrid!

    opened by fluffle 2
  • Support STARTTLS (and CAP tls requesting).

    Support STARTTLS (and CAP tls requesting).

    Many servers support upgrading a plaintext connection to be encrypted by using the STARTTLS command before registration. This client ought to support that.

    opened by fluffle 0
  • Allow registering a global handler

    Allow registering a global handler

    I'm working on a bot plugin framework and it would be useful to register a handler which gets all events so I can dispatch the events with a different handler type (so my own Bot object is available).

    opened by belak 1
ircflu is an IRC bot written in Go

ircflu ircflu is an IRC bot written in Go with a flexible message- & command-handler. Among its advanced features are a cat-server which allows you to

Christian Muehlhaeuser 18 Apr 26, 2021
Golang Framework for writing Slack bots

hanu - Go for Slack Bots! The Go framework hanu is your best friend to create Slack bots! hanu uses allot for easy command and request parsing (e.g. w

Sebastian Müller 136 Jun 15, 2022
An XMPP client with OTR support

xmpp-client setup go get github.com/agl/xmpp-client (If you don't have Go already installed then see below.) xmpp-client use xmpp-client is a simple

Adam Langley 365 Jun 26, 2022
Simple TCP-based chat server

hub-server Simple TCP-based chat server. Client can be found: https://github.com/alankritjoshi/hub-client Setup go run server.go 1234 How it works Use

Alankrit Joshi 0 Oct 25, 2021
🛅 Backup your Kubernetes Stateful Applications

Stash Stash by AppsCode is a cloud-native data backup and recovery solution for Kubernetes workloads. If you are running production workloads in Kuber

Stash by AppsCode 1.1k Jun 29, 2022
K8s local storage sync for stateful set's using microk8s-hostpath storage classe

Local Storage Sync for microk8s-hostpath The goal is to be able to sync stateful sets between the different nodes of a cluster to allow the data to be

Paulo Ferreira 0 Jan 7, 2022
Govent is an event bus framework for DDD event source implement

Govent is an event bus framework for DDD event source implement. Govent can also solve the package circular dependency problem.

Michaelyn 2 Jan 28, 2022
KEDA is a Kubernetes-based Event Driven Autoscaling component. It provides event driven scale for any container running in Kubernetes

Kubernetes-based Event Driven Autoscaling KEDA allows for fine-grained autoscaling (including to/from zero) for event driven Kubernetes workloads. KED

KEDA 5.1k Jun 20, 2022
go irc client for twitch.tv

go-twitch-irc This is an irc client for connecting to twitch. It handles the annoying stuff like irc tag parsing. I highly recommend reading the docum

gempir 237 Jun 25, 2022
Build event-driven and event streaming applications with ease

Commander ?? Commander is Go library for writing event-driven applications. Enabling event sourcing, RPC over messages, SAGA's, bidirectional streamin

Jeroen Rinzema 60 Jun 13, 2022
gevent imply go-event which tries to make event handling easier.

gevent imply go-event which tries to make event handling easier. What does gevent want to do Async execute jobs safely without too many go routines. S

null 7 Nov 10, 2021
Go-serverless-eth-event-listener - Go serverless, ethereum contract event listener with a sample contract

go-serverless-eth-event-listener This repository is for showing how to listen sm

Emre Ceylan 4 May 19, 2022
Event-planning-go - GRAPHQL Project for Event Planning

About The Project GRAPHQL Project for Event Planning Building the project with l

Muhamad Hilmi Hibatullah 2 Mar 13, 2022
IRC, Slack, Telegram and RocketChat bot written in go

go-bot IRC, Slack & Telegram bot written in Go using go-ircevent for IRC connectivity, nlopes/slack for Slack and Syfaro/telegram-bot-api for Telegram

null 744 Jun 18, 2022
The Tenyks IRC bot.

Tenyks is a computer program designed to relay messages between connections to IRC networks and custom built services written in any number of languages.

Kyle Terry 171 Jun 15, 2022
IRC bot written in Go

GoRobot Yet Another IRC robot. Features: Multiple servers, multiple channels, conversations, flood control Administration via a specific set of IRC ch

Sébastien Rannou 14 Sep 26, 2019
ircflu is an IRC bot written in Go

ircflu ircflu is an IRC bot written in Go with a flexible message- & command-handler. Among its advanced features are a cat-server which allows you to

Christian Muehlhaeuser 18 Apr 26, 2021
A modern IRC server (daemon/ircd) written in Go.

Oragono is a modern IRC server written in Go. Its core design principles are: Being simple to set up and use Combining the features of an ircd, a serv

Oragono 1.5k Jun 20, 2022
A reverse proxy implementing IRC-over-WebSockets

webircproxy webircproxy is a reverse proxy that accepts IRCv3-over-WebSocket connections, then forwards them to a conventional ircd that speaks the no

Ergo.Chat 3 Dec 22, 2021
This is my first IRC bot for launch ddos attack, Write on Go language.

This is my first IRC bot for launch ddos attack, Write on Go language. For education purpose only. Please test it on your lab, And i create this for join university in the future not for attack anyone server with out any permission!!!

null 0 Oct 24, 2021
IRC bot for launch ddos attack, Mainly of scan target are IoT device that run linux and open default SSH port

IRC bot for launch ddos attack, Mainly of scan target are IoT device that run linux and open default SSH port

R4bin 3 Nov 10, 2021
IRC bot for launch ddos attack, Mainly of scan target are IoT device that run linux and open default SSH port

This is my first IRC bot for launch ddos attack, Mainly of scan target are IoT device that run linux and open default SSH port, This bot is write on Go language. For education purpose only. Please test it in your lab. And i create this for join university in the future not for attack anyone server with out any permission!!!

Bozer 0 May 10, 2022
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API

bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API (mattermost not required!)

Wim 5k Jun 28, 2022
girc is a flexible IRC library for Go

girc, a flexible IRC library for Go Status girc is fairly close to marking the 1.0.0 endpoint, which will be tagged as necessary, so you will be able

Liam Stanley 74 May 21, 2022
Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Gabriel Iggy N. 9 May 21, 2022
An inline buildpack for deploying a mattermost-irc bridge

Matterbridge-Heroku An inline buildpack for hosting Matterbridge on Heroku. Heroku is a platform for easily deploying applications. A buildpack provid

Christopher DeCairos 11 May 17, 2022
Jaken - A general purpose IRC bot featuring user acls and arbitrary plugins

Design principles This bot is based on the premise of a loosely coupling between

Lex van Roon 1 Feb 4, 2022
🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go./ gnet 是一个高性能、轻量级、非阻塞的事件驱动 Go 网络框架。

English | ???? 中文 ?? Introduction gnet is an event-driven networking framework that is fast and lightweight. It makes direct epoll and kqueue syscalls

Andy Pan 6.6k Jun 20, 2022
High-performance, non-blocking, event-driven, easy-to-use networking framework written in Go, support tls/http1.x/websocket.

High-performance, non-blocking, event-driven, easy-to-use networking framework written in Go, support tls/http1.x/websocket.

lesismal 697 Jun 21, 2022