19 Day 3: Make it useful
Jake Gaylor edited this page 2015-04-23 21:12:43 -05:00

Today I built some new commands that begin to provide the value of StatBot. The real key to StatBot's value proposition is getting critical data in a situation where there is time pressure. The first command that I implemented was stats <summoner_name> [<champion_name>]. The idea was to provide the client with information regarding a summoner's skill in general and optionally in respect to a particular champion. The stats command required a couple of new data sources from RiotGames' api.

Knowing that StatBot's success was going to depend on the community adopting it, I reached out to the person I trust most in regards to all thing community, @stephen-cernota. We had a couple of discussions recently that resulted in new commands as well as some critical insights to how to leverage the website and support the influx of users. A major break through came when Stephen had the idea to let users tell the bot to send requests to their friends. Before, I had contemplated how to do out of game referrals but knew it to be impossible to send an unsolicited message to another summoner, but I hadn't thought about sending a friend request. (Note from the future: a significant number of referrals were sent; one for every 10 users). Stephen's input also let directly to the summary block at the bottom of the help message and the bots need to help people even when not asked directly.

When searching for a client library to access Riot's api server, I wasn't very thorough. I found Irelia, and it appeared to be complete and it had a nice api so I went with it. It turns out that Irelia has no mechanism for accessing the static api endpoints, and it wasn't written in a way that I could easily extend it to support these endpoints. When I saw that it wasn't going to be trivial to fix Irelia, I did a more thorough search for node.js clients to access Riot's api server and came across LeagueJS. I still had to patch LeagueJS in order to use the new season codes but I was able to get the application migrated very quickly. I'm still waiting to hear back from claudiowilson about merging my changes.

Some time during the development of the data sources which depended on the Riot api I realized that I was having issues matching two strings because they had different casings. To fix this I just lower cased everything, but the proper thing to do might have been to compare the strings in a manner that wasn't case sensitive.

Bot commands were getting out of control, so I knew I needed a more robust solution for parsing them. Hubot uses regex to determine if a handler should be called. I attempted to follow this convention to parse the commands using positional arguments. This quickly fell apart when I needed to support optional arguments. I chose to approach this like I would a CLI and imported an option parser. I didn't need a whole lot in the option parser so I grabbed minimist on a recommendation from a strange on the internet ;). I rewrote all the commands to parse the message text using minimist once the handler triggered via regex. I moved most of the positional arguments to flag based options and added documentation for the changes.

I enhanced the counter <champion_name> command today. Previously, it only returned a link to the championselect page specific to the champion named. Now it scrapes that page for the information requested. Using Zombie.js, a headless browser intended for testing, I grabbed the data and cached it. To process the results, I used cheerio which is a server side implementation of jQuery's core.

As a result of keeping so much data in a memory store and needing a large amount of ram to process requests quickly, I quickly outgrew my 512mb DigitalOcean droplet and upgraded to the 1gb instance. (View from the future: I had to scale all the way the the 8gb instance for the ram I needed but never exceeded 7% processor usage on that node. I definitely could have laid out the infrastructure more efficiently.)

I also decided to push off launch for a couple of days. I am worried that the tool is not ready enough for people to want to share with others, that it is so unpolished that people will walk away frustrated without figuring out how to use it, and that the bot can't scale to hundreds of users. I am not pushing back long though. I just want to knock out 80% of the problems for 20% of the work. I'll come back and make it pretty once I validate that people want it :)

Below is a snapshot of the help readout for posterity

[4:15] StatBot: Help:
counter - Reply with a url to championselect.net

free - Reply with a list of free champions from NA

free <region> - Reploy with a list of free champions for a given region. Valid regions include br, eune, euw, kr, lan, las, na, oce, ru, tr

help - Displays all of the help commands that StatBot knows about.

help <query> - Displays all help commands that match <query>.

links <champion_name> - Reply with useful urls

ping - Reply with pong

rules - Make sure StatBot still knows the rules.

stats <handle> [<champion>] - return the win/loss ratio for a player [and champion]. 
Options:
  --season: one of [2015, 2014, 3]
  --region: country code

All available commands: 
counter, free, help, links, ping, rules, stats