Sunday, June 9, 2013

Steam Chat Bot

I'm going to keep this ball rolling and actually write a blog post about a project before moving on to my next one. I just finished this one yesterday so it's still very fresh in my mind, but I don't think there is too much to say about it so this post will be shorter than my last one.

For this project I made a chat bot for a Steam group chat room that I've been going to for a while. I got the idea to make this because some sort of bot started joining the chat room a while ago, I'm still not sure what its purpose is, but almost every day it will come into the chat room, say "hi" and then leave a few minutes later. After seeing that happen for a while, I was linked to another bot called Dota 2 Dispenser which was made as a way for people to share the Dota 2 invites that hang around uselessly in their inventory. Seeing that the Dota bot uses a Node.js library, I thought back to days I used to go to a few IRC chat rooms and I remembered that there were a few pretty hilarious bots around so I figured that making a chat bot for Steam would be a neat little project to work on. It started as just a bot that says a few in-jokes randomly, but it has expanded a bit as I found a few really useful Node.js modules. Right now it automatically responds to various messages, it is an interface into Cleverbot so that it can communicate in some sort of intelligent way, it searches YouTube or Wolfram Alpha and spits out the result to the chat room, and it automatically posts links to a Tumblr page.

The code is up on GitHub and the package is published on npm, so take a look if you're interested. The basic outline of the code is that there is a bot class that handles the connection to Steam and intercepts the messages that are provided by the steam node package. This bot has a set of trigger objects, which are notified of things like chat messages and they can choose to respond by calling a "send message" function on the bot. Each of the triggers had its own set of challenges, but many of them are basically just a wrapper around another node package, e.g. cleverbot-node, wolfram, tumblr.js, and youtube-feeds. I think the most interesting part of the implementation is the factory I made to create the triggers, but I'll leave the details of that to another post since I couldn't find another good description of how to do this online (although I'm sure it's been done before).

I decided to use plain JavaScript and Sublime Text as an editor for this project, and the main lesson I learnt was that I much prefer the TypeScript & Visual Studio combination. I was writing code a bit faster since I didn't need to worry about syntax as much, but this came at the expense of having annoying bugs pop up. After I had spent an hour trying to work out why something wasn't working, only to discover that I had misspelled a variable name, I started wishing I was writing TypeScript again. I did like using Sublime Text, but its code completion functionality can't compete with Visual Studio's Intellisense.

So that's another project done! It feels pretty good to actually be finishing projects now rather than spending months on them and then leaving them unfinished.

3 comments:

  1. can something like this be used to post something at regular intervals ?
    Lets say post a set of rules in a dota2 chatroom ?

    ReplyDelete
    Replies
    1. Yep should be possible by doing something like this:

      var ChatBot = require('steam-chat-bot').ChatBot;

      var bot = new ChatBot('username', 'password', { autoConnect: true, autoReconnect: true });

      bot.addTriggers([{
      name: 'AcceptChatInvite',
      type: 'AcceptChatInviteTrigger',
      options: { chatrooms: ['groupid'], autoJoinAfterDisconnect: true }
      }]);

      var printRules = function() {
      bot.sendMessage('groupid', 'rules');
      };

      setTimeout(printRules, 10*1000); // First time after 10 seconds so bot can connect
      setInterval(printRules, 60*60*1000); // Repeat every hour


      The bot will auto-join the room when you invite it and it should rejoin if it gets disconnected but not if you kick it. You could also do it just using the steam node package if you don't want the auto-join functionality.

      Delete
    2. Thanks , this helps a lot.

      Delete