dialect 0.5.1

IRC parsing library

To use this package, run the following command in your project's root directory:

dialect CircleCI Linux/OSX Travis Linux/OSX and documentation Windows GitHub commits since last release

IRC parsing library with support for a wide variety of server daemons.

It uses exceptions to signal errors during parsing, so it's not nothrow. Some parts of it create new strings, so it can't be @nogc. It is however pure and @safe with the default "library" build configuration.

Note that while IRC is standardised, servers still come in many flavours, some of which outright conflict with others. If something doesn't immediately work, generally it's because we simply haven't encountered that type of event before, and so no rules for how to parse it have yet been written.

Used in the kameloso bot.

Please report bugs. Unreported bugs can only be fixed by accident.

What it looks like

API documentation can be found here.

struct IRCEvent
    enum Type { ... }  // *large* enum of IRC event types

    Type type;
    string raw;
    IRCUser sender;
    IRCUser target;
    string channel;
    string content;
    string aux;
    string tags;
    uint num;
    int count;
    int altcount;
    long time;
    string errors;

struct IRCUser
    string nickname;
    string ident;
    string address;
    string account;
    long updated;

struct IRCChannel
    struct Mode { ... }

    string name;
    string topic;
    string modechars;
    Mode[] modes
    bool[string] users;
    string[][char] mods;
    long created;

struct IRCServer
    string address;
    ushort port;

    // More internals

struct IRCClient
    string nickname;
    string user;
    string ident;
    string realName;

struct IRCParser
    IRCClient client;
    IRCServer server;
    this(IRCClient, IRCServer);

    IRCEvent toIRCEvent(const string);  // <--

How to use

This assumes you have a program set up to read from an IRC server. This is not a bot framework; for that you're better off with the full kameloso and writing a plugin that suits your needs.

  • Instantiate an IRCClient and configure its members. (required for context when parsing)
  • Instantiate an IRCServer and configure its members. (it may work without but just give it a host address)
  • Instantiate an IRCParser with your client and server via constructor. Pass it by ref if passed around between functions.
  • Read a string from the server and parse it into an IRCEvent with yourParser.toIRCEvent(string).
IRCClient client;
client.nickname = "...";

IRCServer server;
server.address = "...";

IRCParser parser = IRCParser(client, server);

string fromServer = ":zorael!~NaN@address.tld MODE #channel +v nickname";
IRCEvent event = parser.toIRCEvent(fromServer);

with (event)
    assert(type == IRCEvent.Type.MODE);
    assert(sender.nickname == "zorael");
    assert(sender.ident == "~NaN");
    assert(sender.address == "address.tld");
    assert(target.nickname == "nickname");
    assert(channel == "#channel");
    assert(aux = "+v");

string alsoFromServer = ":cherryh.freenode.net 435 oldnick newnick #d " ~
    ":Cannot change nickname while banned on channel";
IRCEvent event2 = parser.toIRCEvent(alsoFromServer);

with (event2)
    assert(type == IRCEvent.Type.ERR_BANONCHAN);
    assert(sender.address == "cherryh.freenode.net");
    assert(channel == "#d");
    assert(target.nickname == "oldnick");
    assert(content == "Cannot change nickname while banned on channel");
    assert(aux == "newnick");
    assert(num == 435);

// Requires Twitch support via build configuration "twitch"
string fullExample = "@badge-info=subscriber/15;badges=subscriber/12;color=;display-name=SomeoneOnTwitch;emotes=;flags=;id=d6729804-2bf3-495d-80ce-a2fe8ed00a26;login=someoneontwitch;mod=0;msg-id=submysterygift;msg-param-mass-gift-count=1;msg-param-origin-id=49\\s9d\\s3e\\s68\\sca\\s26\\se9\\s2a\\s6e\\s44\\sd4\\s60\\s9b\\s3d\\saa\\sb9\\s4c\\sad\\s43\\s5c;msg-param-sender-count=4;msg-param-sub-plan=1000;room-id=71092938;subscriber=1;system-msg=someoneOnTwitch\\sis\\sgifting\\s1\\sTier\\s1\\sSubs\\sto\\sxQcOW's\\scommunity!\\sThey've\\sgifted\\sa\\stotal\\sof\\s4\\sin\\sthe\\schannel!;tmi-sent-ts=1569013433362;user-id=224578549;user-type= :tmi.twitch.tv USERNOTICE #xqcow"
IRCEvent event4 = parser.toIRCEvent(fullExample);

with (event)
    assert(type == IRCEvent.Type.TWITCH_BULKGIFT);
    assert(sender.nickname == "someoneontwitch");
    assert(sender.displayName == "SomeoneOnTwitch");
    assert(sender.badges == "subscriber/12");
    assert(channel == "#xqcow");
    assert(content == "SomeoneOnTwitch is gifting 1 Tier 1 Subs to xQcOW's community! They've gifted a total of 4 in the channel!");
    assert(aux == "1000");
    assert(count == 1);
    assert(altcount == 4);

See the /tests directory for more example parses.

Unit test generation

Compiling the assertgen dub subpackage builds a command-line tool with which it is easy to generate assert blocks like the one above. These can then be pasted into an according file in /tests, then ideally submitted as a GitHub pull request for upstream inclusion. You can use it to contribute known-good parses and increase coverage of event types.

Simply run dub run :assertgen and follow the on-screen instructions.

Enter daemon [optional daemon literal] (ircdseven): unreal
Enter network (freenode): foobar
Enter server address (irc.freenode.net): irc.server.tld


// Paste a raw event string and hit Enter to generate an assert block. Ctrl+C to exit.

:irc.server.tld PRIVMSG #channel :i am a fish

    immutable event = parser.toIRCEvent(":irc.server.tld PRIVMSG #channel :i am a fish");
    with (event)
        assert((type == IRCEvent.Type.CHAN), Enum!(IRCEvent.Type).toString(type));
        assert((sender.address == "irc.server.tld"), sender.address);
        assert((channel == "#channel"), channel);
        assert((content == "i am a fish"), content);


  • nothing right now, ideas needed

Built with


This project is licensed under the MIT license - see the LICENSE file for details.

  • JR
Sub packages:
0.9.0 2020-Oct-23
0.8.0 2020-Oct-03
0.7.0 2020-Sep-04
0.6.1 2020-Jun-10
0.6.0 2020-May-27
Show all 24 versions
Download Stats:
  • 12 downloads today

  • 126 downloads this week

  • 528 downloads this month

  • 5402 downloads total

Short URL: