girc is a flexible IRC library for Go

Overview

girc, a flexible IRC library for Go

Build Status Coverage Status GoDoc Go Report Card IRC Chat

Status

girc is fairly close to marking the 1.0.0 endpoint, which will be tagged as necessary, so you will be able to use this with care knowing the specific tag you're using won't have breaking changes

Features

  • Focuses on simplicity, yet tries to still be flexible.
  • Only requires standard library packages
  • Event based triggering/responses (example, and CTCP too!)
  • Documentation is mostly complete.
  • Support for almost all of the IRCv3 spec.
    • SASL Auth (currently only PLAIN and EXTERNAL is support by default, however you can simply implement SASLMech yourself to support additional mechanisms.)
    • Message tags (things like account-tag on by default)
    • account-notify, away-notify, chghost, extended-join, etc -- all handled seemlessly (cap.go for more info).
  • Channel and user tracking. Easily find what users are in a channel, if a user is away, or if they are authenticated (if the server supports it!)
  • Client state/capability tracking. Easy methods to access capability data (LookupChannel, LookupUser, GetServerOption (ISUPPORT), etc.)
  • Built-in support for things you would commonly have to implement yourself.

Installing

$ go get -u github.com/lrstanley/girc

Examples

See the examples within the documentation for real-world usecases. Here are a few real-world usecases/examples/projects which utilize girc:

Project Description
nagios-check-ircd Nagios utility for monitoring the health of an ircd
nagios-notify-irc Nagios utility for sending alerts to one or many channels/networks
matterbridge bridge between mattermost, IRC, slack, discord (and many others) with REST API

Working on a project and want to add it to the list? Submit a pull request!

Contributing

Please review the CONTRIBUTING doc for submitting issues/a guide on submitting pull requests and helping out.

License

Copyright (c) 2016 Liam Stanley 
   
    

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

   

girc artwork licensed under CC 3.0 based on Renee French under Creative Commons 3.0 Attributions.

References

Comments
  • RFC: Split messages exceeding maximum length

    RFC: Split messages exceeding maximum length

    This is a preliminary implementation of message splitting as proposed in #41. The implementation is far from finished and has bugs all over the place. I just experimented a bit with implementing message splitting and this is what I came up with so far. Consider this a super experimental proof of concept design proposal.

    Let me know if you have any thoughts on this. I also have the feeling that implementing this algorithm correctly is super difficult. As such, this definitely needs some extensive unit tests. I only implemented splitting of PRIVMSG events so far and did some very very basic tests with my own girc-based IRC client and it seems to work a bit (at least).

    opened by nmeum 18
  • Support quit messages through type Config, c.Cmd.Quit(), or a c.Close() wrapper

    Support quit messages through type Config, c.Cmd.Quit(), or a c.Close() wrapper

    How about we add a struct field QuitMessage to type Config and use this quit message upon graceful exit?

    Are there any ways to do this currently, as in quit with a specified quit message whenever (for example when handling signals)?

    enhancement 
    opened by bmeh 8
  • Use of struct{} instead of string where value is ignored

    Use of struct{} instead of string where value is ignored

    I have stumbled upon the code here, where you are using string (as in map[string][]string) and nil, instead of struct{} and struct{}{}. From a quick glance I cannot see you using the value anywhere, and using struct{} would communicate this intent better, therefore making the codebase slightly cleaner, and additionally it would consume less memory, but this memory consumption is negligible either way.

    From:

    var possibleCap = map[string][]string{
      "account-notify": nil,
    [...]
    }
    

    to:

    var possibleCap = map[string]struct{}{
      "account-notify": struct{}{},
    [...]
    }
    

    You may also like to compare the assembly output: https://go.godbolt.org/z/4IMjlE

    opened by bmeh 7
  • Fix pretty printing of kick messages

    Fix pretty printing of kick messages

    Perhaps the extra colon could be omitted when no reason is given.

    https://github.com/lrstanley/girc/blob/a5d4d6aadaa1cbf635cbc213818c39529a1c3ce2/event.go#L390..L392

    if e.Command == KICK && len(e.Params) == 2 {
      if len(e.Trailing) > 0 {
        return fmt.Sprintf("[%s] *** %s has kicked %s: %s", e.Params[0], e.Source.Name, e.Params[1], e.Trailing), true
      } else {
        return fmt.Sprintf("[%s] *** %s has kicked %s", e.Params[0], e.Source.Name, e.Params[1]), true
      }
    }
    
    enhancement 
    opened by bmeh 6
  • initial work towards moving away from Event.Trailing (closes #5)

    initial work towards moving away from Event.Trailing (closes #5)

    Closes: https://github.com/lrstanley/girc/issues/35 Closes: https://github.com/lrstanley/girc/issues/19 See also: https://github.com/lrstanley/girc/pull/15#issuecomment-413845482


    From: https://modern.ircdocs.horse/

    Here are some examples of messages and how the parameters would be represented as JSON lists:

      :irc.example.com CAP * LIST :         ->  ["*", "LIST", ""]
    
      CAP * LS :multi-prefix sasl           ->  ["*", "LS", "multi-prefix sasl"]
    
      CAP REQ :sasl message-tags foo        ->  ["REQ", "sasl message-tags foo"]
    
      :[email protected] PRIVMSG #chan :Hey!  ->  ["#chan", "Hey!"]
    
      :[email protected] PRIVMSG #chan Hey!   ->  ["#chan", "Hey!"]
    

    As the last two examples show, a trailing parameter (a parameter prefixed with ':') is another regular parameter. Once the ':' is stripped, software MUST just treat it as another param.


    Essentially, Event.Trailing is now just an additional entry in the Event.Params slice.

    I'm still opting to have the concept of Trailing as a semantic wrapper (and has nothing to do with the rfc's use of "trailing"). Event.Trailing(), which now just returns the last parameter/argument (from Event.Params directly), which will help as it is much more frequent to get the last element, than any other element (and Event.Params[len(Event.Params)-1] is very verbose). The other benefit is it defaults to an empty string. Maybe I'll rename it to Last?

    This probably has bugs in it. Tests run fine, did some initial connections to servers, but I'd like some contributors to test this out before I merge into master:

    • @nmeum
    • @42wim
    • @puffrfish
    • @bmeh
    • @Bevinsky
    • @Kethsar

    Also, @qaisjp, this has that spelling correction.

    opened by lrstanley 5
  • Don't store RFC 1459 compliant nick in User struct

    Don't store RFC 1459 compliant nick in User struct

    The problem with performing ToRFC1459() on the nick before storing it in the User struct is that (among other things) capitalization is lost. So function like client.UserList always return all nicks in lowercase.

    I am personally using the values return by channel.UserList for tab completions and to me it is kind of annoying that the capitalization of nicks as shown by event.Pretty() differs from the one suggested by the tab completions I have implemented.

    I would suggest that nicks are not stored in an RFC 1459 compliant format since any nick can be made RFC 1459 compliant using the ToRFC1459 function on demand but converting it back to its original format isn't possible.

    opened by nmeum 5
  • WebIRC

    WebIRC

    I currently use https://github.com/thoj/go-ircevent/ where I implemented WebIRC support in https://github.com/thoj/go-ircevent/pull/96.

    I am interested in girc and would like to add WebIRC support.

    Is this fine?

    opened by qaisjp 4
  • pretty print invite command

    pretty print invite command

    Somehow, there is currently no if-statement for the invite message in the Pretty() function of the Event type. Thus causing the message to be discarded when invoking Pretty().

    This commit adds this missing if-statement to the function.

    opened by nmeum 4
  • Allow extra characters

    Allow extra characters

    Somewhat related to https://github.com/lrstanley/girc/projects/1#card-6997933

    Functions like IsValidNick and IsValidUser exist: https://github.com/lrstanley/girc/blob/51b8e096d398e4c5991dcbc073988218d4e94751/format.go#L214-L241 https://github.com/lrstanley/girc/blob/51b8e096d398e4c5991dcbc073988218d4e94751/format.go#L243-L286

    It would be useful if we could abstract this into an interface NickValidator.

    My particular use-case is that we have a customised IRC server that allows certain users to use the tilde (~) character — discord puppets have a ~d suffix. See qaisjp/go-discord-irc.

    Would you be willing to accept a pull request that implements this?

    (This would prevent the need to fork your repo.)

    opened by qaisjp 3
  • Special treatment of 'trailing' argument in commands is incorrect

    Special treatment of 'trailing' argument in commands is incorrect

    The IRC RFC says this about the format of commands:

    <params>   ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
    
    <middle>   ::= <Any *non-empty* sequence of octets not including SPACE
                   or NUL or CR or LF, the first of which may not be ':'>
    <trailing> ::= <Any, possibly *empty*, sequence of octets not including
                     NUL or CR or LF>
    

    and

      2)    After extracting the parameter list, all parameters are equal,
            whether matched by <middle> or <trailing>. <Trailing> is just
            a syntactic trick to allow SPACE within parameter.
    

    In essence, there is no semantic difference between an argument parsed as a 'middle' or one as a 'trailing'. Trailing is simply a syntactic specification to allow the last argument in a command to contain spaces, if so desired.

    However, girc doesn't follow this footnote and explicitly encodes 'trailing' as some special kind of command parameter. This is incorrect; if a command has a 'trailing' parameter, this is simply the last parameter of the command. There is no special meaning to it.

    This makes the library cumbersome to use at best (since special care must be taken in regards to 'empty trailing', which should not be necessary at all), and broken at worst (since IRCds are within their rights to send commands for which you would 'expect' a trailing argument without one, such as PRIVMSG, or send commands with a trailing argument which you would not expect to have one).

    This is IMHO a very huge flaw in the library and should be fixed before it goes 1.0.

    bug 
    opened by Bevinsky 3
  • Make CTCP handlers optional

    Make CTCP handlers optional

    The default CTCP handlers are currently registered unconditionally in client.New. The CTCP handlers disclose quite a few things, e.g. current Time (through handleCTCPTime) and operating system, architecture and girc version (through handleCTCPVersion).

    IMHO it would be nice if these handlers could be disabled. For instance through a new Config option.

    opened by nmeum 3
  • bug: newlines are removed instead of changed to a space

    bug: newlines are removed instead of changed to a space

    🌧 Describe the problem

    When calling Cmd.Message() with a message containing a newline, the newline is stripped, which smashes words together.

    ⛅ Expected behavior

    The newline should be replaced with a space, instead of just stripped

    🔄 Minimal reproduction

    Call Cmd.Message("#foo", "example\nmessage") and observe that the resulting message is "examplemessage" instead of "example message"

    💠 Version: girc

    v0.0.0-20220410132120-49de39aea653

    🖥 Version: Operating system

    linux/other

    ⚙ Additional context

    I'm using girc via https://github.com/RITlug/teleirc . When a telegram message contains a newline, the resulting IRC message has this problem. It could be worked around in TeleIRC, but it seemed like girc would be a better place to fix it for everyone.

    I'm not sure the best way to handle \r or \r\n - ideally collapsing runs of either to just one space?

    🤝 Requirements

    bug 
    opened by half-duplex 2
  • execLoop and sendLoop not getting closed if network connection is low-quality

    execLoop and sendLoop not getting closed if network connection is low-quality

    It appears that if a low-quality network connection (e.g. being behind a Whonix Tor transproxy) is being used, the execLoop and/or sendLoop goroutines aren't reliably being closed properly after a disconnect.

    Originally reported at https://github.com/42wim/matterbridge/issues/1743 (detailed logs are in that issue) ; @42wim suggested that I report it here. I'm happy to help with trying to narrow down the bug, e.g. by collecting more detailed logs, but my ability to help may be limited since I'm not the author of the affected software. In any event please let me know what I can do to help get this fixed.

    bug 
    opened by JeremyRand 19
  • Split messages

    Split messages

    Followup to #42.

    /CC @nmeum @robbyoconnor @jwflory


    Still a few TODOs:

    • Handle colors when splitting
    • Special treatment for URLs in word-boundary splitting
    • Prevent unneeded whitespace truncation in word-boundary splitting (i.e. don't collapse multiple whitespace into one) (and a few other minor things)
    • Tests
    enhancement 
    opened by lrstanley 2
  • Implement splitting of long messages?

    Implement splitting of long messages?

    From RFC 2812:

    IRC messages are always lines of characters terminated with a CR-LF (Carriage Return - Line Feed) pair, and these messages SHALL NOT exceed 512 characters in length, counting all characters including the trailing CR-LF.

    As I understand it, this is a restriction which applies to messages sent by the server. The client needs to make sure that sent client messages do not result in server messages which exceed this limit. This requires some heuristics to determine the length of the resulting server message for a given client message. Which, in turn, requires calculating the maximum nick and host length et cetera. I personally think that this is a major defect of the IRC protocol itself as it requires implementing "dodgy hacks for every single command" which may exceed this message length. As such, this has also been discussed by the IRv3 working group [1].

    Short-term it would nice to implement splitting of messages which exceed this limit. For instance, if a PRIVMSG exceeds it, it has to be split into two PRIVMSG commands. I started working on such an implementation in my own IRC client, which uses girc, however I personally think that message splitting would be best implemented in girc itself. What are your thoughts on this?

    Existing "message splitting" implementations:

    • The irssi implementation: https://github.com/irssi/irssi/blob/6933134352fdd4f53bc2de14b782a743f1290526/src/irc/core/irc-servers.c#L200
    • The weechat implementation: https://github.com/weechat/weechat/blob/0d9b7ec95499de6dd0ab981411416be6707b9f25/src/plugins/irc/irc-message.c#L997

    Maybe it would make sense to start with an implementation of message splitting for PRIVMSGs and maybe extend it to other commands afterwards?

    enhancement 
    opened by nmeum 2
  • integration with ircdef

    integration with ircdef

    Once I've solidified how I want https://github.com/lrstanley/ircdef to look, may want to look at moving to it for girc. Would definitely be a big change.

    enhancement 
    opened by lrstanley 1
Owner
Liam Stanley
Avid, enthusiastic, computer programming & operations nerd. Hardware hobbyist.
Liam Stanley
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
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 5.4k Jan 4, 2023
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 Nov 26, 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. 10 Dec 27, 2022
Gmqtt is a flexible, high-performance MQTT broker library that fully implements the MQTT protocol V3.1.1 and V5 in golang

中文文档 Gmqtt News: MQTT V5 is now supported. But due to those new features in v5, there area lots of breaking changes. If you have any migration problem

null 817 Jan 5, 2023
An easy-to-use, flexible network simulator library in Go.

ns-x An easy-to-use, flexible network simulator library for Go. Feature Programmatically build customizable and scalable network topology from basic n

Bytedance Inc. 106 Dec 13, 2022
A standalone Web Server developed with the standard http library, suport reverse proxy & flexible configuration

paddy 简介 paddy是一款单进程的独立运行的web server,基于golang的标准库net/http实现。 paddy提供以下功能: 直接配置http响应 目录文件服务器 proxy_pass代理 http反向代理 支持请求和响应插件 部署 编译 $ go build ./main/p

fangyousong 5 Oct 18, 2022
A flexible configuration manager for Wireguard networks

Drago A flexible configuration manager for WireGuard networks Drago is a flexible configuration manager for WireGuard networks which is designed to ma

Seashell 1k Jan 7, 2023
Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core network solution.

Connecting the Next Billion People Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core

Magma 1.5k Dec 31, 2022
Go network programming framework, supports multiplexing, synchronous and asynchronous IO mode, modular design, and provides flexible custom interfaces

Go network programming framework, supports multiplexing, synchronous and asynchronous IO mode, modular design, and provides flexible custom interfaces。The key is the transport layer, application layer protocol has nothing to do

rick.wu 11 Nov 7, 2022
A library for the MIGP (Might I Get Pwned) protocolA library for the MIGP (Might I Get Pwned) protocol

MIGP library This contains a library for the MIGP (Might I Get Pwned) protocol. MIGP can be used to build privacy-preserving compromised credential ch

Cloudflare 23 Dec 3, 2022
A library to simplify writing applications using TCP sockets to stream protobuff messages

BuffStreams Streaming Protocol Buffers messages over TCP in Golang What is BuffStreams? BuffStreams is a set of abstraction over TCPConns for streamin

Sean Kelly 252 Dec 13, 2022
DNS library in Go

Alternative (more granular) approach to a DNS library Less is more. Complete and usable DNS library. All Resource Records are supported, including the

Miek Gieben 6.7k Jan 8, 2023
🚀Gev is a lightweight, fast non-blocking TCP network library based on Reactor mode. Support custom protocols to quickly and easily build high-performance servers.

gev 中文 | English gev is a lightweight, fast non-blocking TCP network library based on Reactor mode. Support custom protocols to quickly and easily bui

徐旭 1.5k Jan 6, 2023
golibwireshark - Package use libwireshark library to decode pcap file and analyse dissection data.

golibwireshark Package golibwireshark use libwireshark library to decode pcap file and analyse dissection data. This package can only be used in OS li

Xiaoguang Wang 28 Nov 26, 2022
An SNMP library written in GoLang.

gosnmp GoSNMP is an SNMP client library fully written in Go. It provides Get, GetNext, GetBulk, Walk, BulkWalk, Set and Traps. It supports IPv4 and IP

Go SNMP 929 Jan 7, 2023
A library for working with IP addresses and networks in Go

IPLib I really enjoy Python's ipaddress library and Ruby's ipaddr, I think you can write a lot of neat software if some of the little problems around

Chad Robinson 98 Dec 20, 2022
A Crypto-Secure, Production-Grade Reliable-UDP Library for golang with FEC

Introduction kcp-go is a Production-Grade Reliable-UDP library for golang. This library intents to provide a smooth, resilient, ordered, error-checked

xtaci 3.5k Dec 28, 2022