Erlang IRC bot for #hspbp @ IRCnet
Table of contents
Overview
List of components
Name | Purpose | Source code | |
Erlang IRC bot | IRC connectivity, plugin management | GitHub repo | |
Topic generator | Generate channel topic | GitHub repo | |
G3mails | Get Google Groups mails | GitHub repo | |
Atomizer | Parse Atom feeds | GitHub repo | |
Erlsom | Parse XML documents | Sourceforge | |
GitHub module | Reacts to GitHub URLs | GitHub gist | |
Erlang RFC4627 | Parses JSON | GitHub repo | |
Leet module (inactive) | Announces leet time 13:37 | GitHub gist |
Information flow between components
Component: Erlang IRC bot
Overview
The erlang IRC bot is responsible for communication with the IRC server. It manages the lifecycle of the plugins by starting them after the connection is established, and sends them a quit message, when the bot is about to shut down. The bot handles only the core IRC-related functionality, such as startup, responding to keep-alive messages (PING) from the server, and shutting down when receiving the appropriate command from an authorized source.
Plugin lifecycle
After startup the bot iterates through the list of plugins and initializes them via their ircmain function. It passes them a Pid and a list of plugin-specific parameters supplied by the user. This Pid can be used to interact with the IRC connection, such as sending channel messages or chaning the topic. The ircmain function returns a Pid, to which the bot sends a quit message when the bot is about to shut down.
Messages exchanged between the plugin and the bot
Message | From | To | Purpose |
quit | bot | plugin | to signal the plugin that it must stop functioning because of being killed or the bot is about to shut down (note: there is no guarantee, that the IRC connection is alive even in case of immediate reception) |
{announce, Msg} | plugin | bot | to send the message contained in the string Msg to the channel |
{topic, Topic} | plugin | bot | to change the topic to the value of string Topic |
{raw, Data} | plugin | bot | send Data directly to the IRC server |
{subscribe, Pid} | plugin | bot | subscribes Pid to be notified of every incoming TCP data |
{incoming, Data} | bot | plugin | notifies a subscribed plugin about incoming TCP data in Data |
{getmods, Pid} | plugin | bot | requests the list of module PIDs to be sent to Pid |
{mods, List} | bot | plugin | contains a list of currently loaded module PIDs in List |
{killmod, ModPid, RespPid} | plugin | bot | kill the module identified by ModPid and notify RespPid of the result |
{killmod, Msg} | bot | plugin | notifies the plugin about the result of a killmod message in a textual format in Msg |
{insmod, ModName, Params, Pid} | plugin | bot | load the module identified by ModName, start it with the parameter list in Params, and notify Pid of the result |
{insmod, Msg} | bot | plugin | notifies the plugin about the result of an insmod message in a textual format in Msg |
Component: Topic generator
Overview
The topic generator is responsible for generating the channel topic based on the state of HackSense and the hsbp.org wiki. After startup, it spawns a process, which monitors the aforementioned sources, and if any of them changes, it constructs the topic (only if both of them returned valid information at least once), and send it in a topic message to the bot. The plugin exits from this loop when it receives a quit message.
HackSense monitoring
The hacksense module handles the extraction of data from the HackSense REST API, and parses the state information in CSV format. This module is also responsible for converting it into a human-readable string format.
hsbp.org wiki monitoring
The event module handles the extraction of data from the hsbp.org wiki via a Python script. Python was selected for this sole task, because the BeautifulSoup module could easily parse invalid markups as well. Later, the BS parser was replaced with LXML because of its performance, simplicity and "well-maintainedness". The event.py script returns the next event via standard output, which is read in the event module already in a convenient string format. If something goes wrong in the Python script, the following things can happen:
- If the problem occured inside the Python script, nothing is written to the standard output.
- If the problem occured before the Python script even started, the standard output remains silent, because the standard error is redirected to /dev/null.
Because of these circumstances, the string will be non-empty if and only if the Python script ran and parsed the events successfully.
Fault tolerance
Both the HackSense and hsbp.org wiki queries are done in separate processes, so if anything goes wrong, it doesn't affect the bot nor the plugin.