The Slack API and Extended file attributes

published on 23 Apr 2015, tagged with zsh

Recently my friends and I decided to try out Slack. It's a platform for team communication with a lot of awesome functionality. They have some incredible API functions and you can even activate and use the IRC-protocol for your team! So I decided just to write a lil' something to try out their API, more specifically the Incoming Webhooks function. You can post messages from an external source and it will appear as a BOT within the channel so that there's no confusion of where the message came from.

So I wrote a small script to scrape the contents from this site. Long story short, it's a MOBA game which offers free weekly rotation of heroes so that you can try them out before you decide whether to purchase them or not. The tool of choice for scraping the website since I'm writing a shellscript is sed. The proper solution would be to parse the HTML, but for a small project like this and the fact that it's a shell script, sed just made more sense.

I wanted to add a small feature so that it would appear that one of the heroes from the game posted the current hero rotation to the channel. I used the website heroesnexus.com and borrowed their icons (I hope they don't mind). The code used to scrape and create the array that I later used in the final script:

% echo "typeset -A arr\narr=("
wget -qO- http://www.heroesnexus.com/ | \
  sed -n '/id="champs"/,/<\/ul>/{
              s|.*/346/\([^/]*\).*name">\([^<]*\).*|  \1 "\2"|p
          }' | \
  recode HTML_4.0
echo \)

Oh sed you are so awesome. Basically we find the range where the hero listing occurs and we find the icons. The N command is run three times to append the next few lines so that we get the heroes name into the pattern space before we perform the substitution that will return a numeric id and the hero it's associated with. The pipe to recode is specifically for Anub'Arak and his apostrophe that was written as a html entity. I could just have substituted it in the sed script but who knows, maybe some other hero comes along and breaks my script.

On to the next dilemma! I want to run it in crontab for a couple of hours on tuesday, but I want it to stop after the update has been received and announced to Slack. Guess I could use a file to store a checksum for the last known hero rotation. But what a pain, I have a perfectly fine file holding the contents of the script. Let's make use of extended file attributes and store the checksum of the hero rotation within the script file itself!

I ran into one little problem though, my extended attributes kept disappearing and I couldn't figure out why. Then it struck me, I use vim as my editor and whenever you save a file within vim it will actually parse the contents into a temporary file which it then moves to the location of the file you're working on. So as a workaround I have a specific modeline within the file that disables this behavior. Now I can make changes to the file and my metadata will stay intact.

The final version of the script can be found on my gist (uhm, think I broke the highlight).

This is what it looks like if you view it through the browser (or Slack client):

The Slack Chat