~/home/blogs/write-an-irc-bot.md

Write an IRC Bot

I automated greeting users in IRC. It started with a HexChat plugin.

- Raul G.
2021-01-18

Once I was able to connect to Twitch using IRC, I realized I could automate a ton of stuff.

To learn about connecting to Twitch using IRC, check out my other blog post, linked here.

Where did I start?


Once I had connected to Twitch chat using my HexChat client, I realized that I could see when people join a twitch chat, as they join. 

Out of habit, I started greeting people as they come in to the twitch chat. This lead me to research the HexChat API and then to figure out the best and easiest way to automate some of this behavior. I decided that a lua script would be the easiest way to start.

Further research on the scripting API lead to me to understand that HexChat has a "hook" system. So, you simply write a callback function and assign it to the corresponding hook.

Hooks

I used the hexchat.hook_print function to listen for "Join" events. I had a hard time learning how to use the hook_print function. I didn't understand what options were available for "event". After some further reading, I realized that the events being referenced here were the events listed under HexChat's "Settings" > "Text Events" menu.


  local function on\_join(hook\_info)
    -- Code Here
  end

  hexchat.hook\_print("Join", on\_join)

Remembering Users

I noticed that often times, users would join and leave frequently. I don't know whether this was genuinely a disconnect/reconnect issue or just the Twitch IRC servers bugging out. I figured I shouldn't auto greet users that I've greeted previously, so I decided to store a file with the channel name and the chatter's username.

This would allow me to effectively remember whether this combination of channel-user has been greeted before. Unfortunately, Lua has limited file system support so I kept it rather dumb and moved on to building this in Ruby.

LUA CODE:


hexchat.register("auto-greeter", "0.1", "Welcomes new members to chat channels ")

local greetings = {
   "Enjoy your stay!",
   "Thanks for joining!",
   "We're happy to have you!",
   "One of us... One of us... gooble gobble",
   ""
}

local function file\_exists(name)
   local f=io.open(name,"r")
   if f~=nil then io.close(f) return true else return false end
end

local function touch\_file(path)
   new\_file = io.open(path, "w")
   new\_file:close()
end

local function on\_join(info)
   local nick = info[1]
   local chan = info[2]

   local file\_dir = "C:\\Users\\Raul\\AppData\\Roaming\\HexChat\\" .. chan .. "\_" .. nick .. ".mem"
   local isMet = file\_exists(file\_dir)

   if isMet == false then
      touch\_file(file\_dir)

      -- Random Greeting
      local rand\_num = math.random(#greetings)
      local rand\_greeting = greetings[rand\_num]

      -- Reply to Message
      hexchat.command("MSG " .. chan .. " " .. "Welcome, " .. nick .. "! " .. rand\_greeting)
   end

   -- Allow this Event to trigger other responses
   return hexchat.EAT\_NONE
end

hexchat.hook\_print("Join", on\_join)

-- Debug Message. Lets you know this function was hooked.
hexchat.print("Auto-Greeter Has Been Hooked!!")

(For flair, I randomly pick a greeting message)

Loading Into HexChat

Once the code was written, we simply had to load it into HexChat. The easiest way of doing that is to type: 


/load "file\_path.lua"

into HexChat. This will load the lua script to HexChat. The downside to this is that you will need to do this every time you open hexchat. If you want to load it automatically, you can add it to your HexChat addons folder. I believe that is found in your %AppData% folder on Windows. 

Going headless!


There were a few issues with the HexChat plugin. Some could be solved by using the Python API rather than the Lua API. Could also install a lua file system library. I, however, am more comfortable with Ruby, and I realize that IRC is a very old protocol, so most languages should support scripting for IRC servers.

At this point, I decided to port the code above to a Ruby script. This way, I:

  1. Do not rely on HexChat
  2. Have full control over the IRC input/output
  3. Can container-ize my script and run it headlessly
    1. Specifically, using one of my Raspberry Pis

This means that I'll be able to automate my account even if my laptop or desktop is offline.

The Code

Github Link Here

I made a few changes to the HexChat script.

  • No Longer Triggers on "Join"
    • I received some criticism for disturbing the twitch lurkers.
    • If you are unfamiliar, a twitch lurker is a viewer that joins to watch your stream, but they do not interact with the chatroom.
    • It now triggers when it receives a message event, instead.
  • It recognizes when you've returned
    • We use a different array of phrases when a user returns

Just like before, it "remembers" users by creating a directory/file in the "./met" directory. We're able to use the file system to determine when the file was originally created, and therefore how long it's been since we last greeted them. 

My next blog post will detail how I used C# and some spreadsheets to generate the cards printout for Potato, the card game!

I hope you found something in this blog post helpful :)

Thanks for reading!

Share this post