Well, the very topic of ChatOps has already been discussed at length by many people, so I am gonna jump to my very first ChatOps with Hubot right away.

First : the motivation.

I discovered Anki quite a while ago, it has been helping me to expand and improve my English vocabulary - and my kid’s Chinese vocabulary as well. It comes with a mobile app (only the Android version is free, but I am sure Apple fanboys won’t mind to pay extra for their beloved iPhone) which is handy, but still whenever I wanted to add a new word that I bumped into during my reading, it does not feel that convenient: You know what I mean if you have ever tried to manually add a new word to Anki.

Enter anki-sync-server.

In short, it is a private Anki sync server, and most beautifully, it comes with a super cool (but badly documented) RESTful API which makes automation possible. And being a lazy engineer, I love to automate things.

Well, to be fair, the document is not that bad if you read the code very carefully. Here’s what I’ve figured out.

  1. Collection - the name is kind of miss leading in my opinion. Actually, the collection name is just your user name.
  2. All requests must be sent as POST.
  3. Anki manages words by using notes: a note is where you put your new word and its explanation etc. You only add note but not card, the latter is generated by Anki automatically to reflect on side of the note (remember you can have reversed card).

Use wget to try some quick examples.

List all decks:

wget --post-data='{}'  --header "Accept: application/json" http://127.0.0.1:27701/collection/username/list_deck

List all models (card types):

wget --post-data='{}'  --header "Accept: application/json" http://127.0.0.1:27701/collection/username/list_models

Finally, my goal : add a new word as note

wget --post-data='{"model":"English","fields":{"Word":"exasperate","Meaning":"irritate intensely; infuriate","Phonetic":"/ɪɡˈzasp(ə)reɪt,ɛɡ-/","Reverse":"y"}}'  --header "Accept: application/json" http://127.0.0.1:27701/collection/username/add_note

Next: the goal.

With the logistics being sorted out, here’s the deal : next time when a new word finds me, I will paste it to my slack channel where my bot is waiting for commands, and I want my bot to figure out the new word’s meaning, pronunciation, along with examples, and add them to my private Anki server automatically. All I need to do later is to sync my Anki app with the server.

Obviously my bot would need a dictionary, and lucky for him the Longman dictionary API is free for up to 4,000,000 calls per month (Thank you! Pearson Inc !!).

Again, a quick wget dry run:

wget --header "Accept: application/json" http://api.pearson.com/v2/dictionaries/ldoce5/entries?headword=exasperate

ldoce5 is the ID of Longman Dictionary of Contemporary English. Note GET is used. Multiple results will be returned as a JSON object. So that’s everything we need to automate the task, let’s teach my bot the trick.

My bot is a Hubot, commissioned by GitHub (who, by the way, also coined the term ChatOps). I am pretty sure the original author must be one of those front-end guys who just invaded the back-end territory, because the language he or she chose to write Hubot is CoffeeScript, which is not only a bad name play of JavaScript, but also compiled to JavaScript.

The bot uses adapter to listen command (which is basically a string of text), then it launches scripts you write to parse the command, and executes the corresponding logic if the command is recognized. I will teach my bot two commands :

  • dict <word> when the bot sees this command, it will
    1. use <word> to query the dictionary API
    2. parse the results
    3. group the answers(there could be more than one) into explanations, pronunciations and examples
    4. show the answers.
  • anki <word> same as dict, but the answer will also be added to my private Anki sync server.

Please refer to this little CoffeeScript for the implementation. Please note this is the virgin piece of CoffeeScript of mine, I have every right to be lousy and clumsy :)

What’s left is to connect my bot with Slack and join my team (called Under Lu’s Roof, it’s obviously meant for family business). This is no-brainer as people in the Hubot community have contributed all sorts of adapters including Hubot Slack. It has some limits : the bot cannot receive direct message ; and it has to be invited into a channel first, etc. but manageable.

Finally, let’s put it action:

Bot in Slack

Added ! Then I sync in the Anki app:

Anki app

Isn’t that neat !?

Oh, did I mention that Anki is also being used to help my kid with his Chinese vocabulary? I couldn’t find a good online source to look for Chinese character’s pronunciation (namely Pinyin), so I wrote a small Python script to do the trick: it outputs pinyin with tune, and the traditional Chinese form if there is any. Will teach my bot this trick for sure !