IRCTk

Use of the TCL module to write extensions
Login

Use of the TCL module to write extensions

Introduction

IRCTk is written in TCL so, it was natural to provide an official module to write extensions in it.

The module is distributed with the IRCTk installation, located, generally, in the same directory of the IRCTk source code. The main purpose of the module, is to do all basic work of setting up the environment for you, from the basic handshake, to fetching the messages as they arrive on the process standard input. In essence, you, as a programmer, need only to provide the related callbacks the module should call, for any specific message type.

For detailed documentation about the module's available commands, please refer to the irctk-ext-sdk(n) man page.

Here, we are going to write a simple "hello world!" extension, where the extension itself understands the irc "hello" command and answer with a PRIVMSG, containing the answer "world!".

Using the module

First, we need to source the module. IRCTk places it in an environment variable for you when the extension is started:

source $::env(IRCTK_TCL_SDK)

After that, generally, you should set a couple of variables. In particular, the name and the version of the extension.

It's not mandatory, but it's good code hygiene to do so:

set name "Hello"
set version 0.1

Then, comes the callback declarations plus any additional commands you may want to use in your extension. Of course, it's possible to define TCL events, too:

proc helloworld {msg} {
	set network [dict get $msg network]
	set channel [dict get $msg channel]

	::irctk::ircsend $network $channel PRIVMSG "world!"
}

Any callback receives a message dictionary as an argument, whose details are defined in the module's man page.

In this case, the command will send back a simple message with the text "world!" to the network and channel it came from. The module takes care of all the I/O for you.

After this initial part, you initialize the extension:

::irctk::init $name $version {} {}

The module will register the extension name and version, and run the handshake for you. The third argument represent a list of IRCv3 capabilities your extension may be able to manage, while the fourth argument is a default callback, used to handle any message not part of any defined filter. It's generally left empty ({}). However, there may be cases where handling a particular situation is required. A default handler is, then, the appropriate solution for that. As for any other callback, the default handler receives a dictionary containing the message details as an argument.

If a default callback is specified, and no filters are defined, IRCTk will relay messages of any type to the extension and they will be managed by the default handler.

Of course, a well-written extension should ask IRCTk to send messages for one or more specific type or command:

::irctk::filter irc {}
::irctk::filter hello helloworld

In this case, you are asking IRCTk: "please, I want to receive messages of the type irc, and from that type, only messages related for the hello command".

When you define the filter for the "hello" command, you should provide a callback (helloworld). The callback is defined earlier in the code. If, instead, you want the extension to receive any message of type IRC, and process those with a callback, the following single filter does it:

::irctk::filter irc helloworld

Now, you can start the main extension's loop:

::irctk::loop

That's it! Nothing more complicated than this. As mentioned, your extension may define additional events on top of what the module does. In the end, the module is just a layer on top of the tcl's vwait command, so any additional event will be handled without issues, too.

For examples of real-world extensions using the TCL module, please refer to the extensions directory.