The online home of John Pollard

Slack as a General Purpose Notification System

In my last post, I mentioned how the one missing piece in my slightly crazy Alexa->Todoist->IFTTT->Notification Shopping List System was being able to open the specific ‘Alexa Shopping List’ project in Todoist when I’m near the local supermarkets.

Looking through the Todoist API, I realised I can generate a link that will open a specific Todoist project e.g. “todoist://project?id=183977037” where the id parameter is the specific project id.

As far as I can tell the only way of finding the project id is my calling the API to get my project details and inspecting the JSON e.g.

$ curl https://todoist.com/API/v7/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d sync_token='*' \
    -d resource_types='["projects"]'

So now, rather than send an iOS notification from IFTTT, I send a message to Slack containing the Todoist link.

Obviously that means when I get the Slack notification on my phone, I can simply click on the link in the message and go straight to where I want in Todoist.

Happy days!

The idea of using Slack as a universal notification system is really powerful. There are so many easy ways of hooking up applications into Slack (and it’s easy to write your own) and I’ve already got lots of ideas on how I can use this pattern in different ways to send relevant alerts from different services.

My Cool (but completely over-engineered) Shopping List System

As I mentioned before, I’m absolutely loving my Amazon Echo, and am addicted enough to reliable voice input to have added an Echo Dot in my home office.

Probably my favorite use is the Todoist integration that lets you add tasks both your To Do list and your Shopping List into Todoist directly simply by speaking to Alexa.

However there was one flaw in doing this - I kept forgetting to check the shopping list when I was at the supermarket ☹

Now in where I live in Hexham (in North-East England), "going shopping" generally means going to one of the two main supermarkets (Tesco or Waitrose), which luckily for my purposes are pretty close together. Therefore I had the brilliant idea of firing a location-based alert whenever I was near either of the supermarkets to remind me to check the shopping list in Todoist.

I was half-considering writing my own simple iOS app to trigger the location-based notification, but then realised that IFTTT has got the facility to do precisely this!

The steps to set this up are pretty simple …

  1. Install the IFTTT app on my phone
  2. Enable the "iOS Location settings" service on IFTTT
  3. Enable the "Notifications" service on IFTTT
  4. Create an IFTTT applet that triggers at a specific location (i.e. near the supermarkets), and when it does send me an iOS notification reminding me about the shopping list.

Setting the location trigger is a bit fiddly using the web-based interface, but I managed to set it up just right as you can see from the screenshot below:

location trigger

This whole convoluted setup actually works pretty reliably, and every time I get near to either Tesco or Waitrose I get a ping on my watch and phone reminding me to "Check the shopping list" …

Screenshot of IFTTT notification

In an ideal world, I could set the action on the notification to open Todoist in the ‘Alexa Shopping List’ project directly, but maybe IFTTT will enable that in the future?

All in all, clearly this whole Heath Robinson system is slightly over the top, but it works very well for me!

Update (4 Dec 2016): I found a better way to send the notification via Slack

Building an Alexa Skill

I recently bought an Amazon Echo, which I absolutely love. It’s great in the kitchen as a hands-free music player, as the speaker is really good, and has replaced the slightly unreliable Siri completely for setting timers when cooking.

Obviously I wanted to develop my own Alexa skill, so I’ve built one to tell me about the latest Halesowen Town scores and fixtures information. Right now there’s almost certainly an audience of one for it, but it makes me very happy!

Here’s a video showing the exciting things it does …

Technically the easiest way to write a skill is on AWS Lambda, Amazon’s on-demand compute engine. Alexa skills can run on Lambda with minimal setup, and looks a lot easier than running code on your own server.

The Alexa Skills SDK explains pretty well how to get set up - not always a given on Amazon’s platforms in my experience - so I won’t repeat anything here that isn’t covered in detail in the documentation.

In essense, to get your skill running you have to complete the following tasks:

  1. Add a list of intents you want your skill to answer
    • You can add custom content slots for known lists of names (think Enum) e.g. I have a list of teams in Halesowen’s league to match against
  2. Add sample phrases which will match to each of your intents
    • The content slots are used here e.g “FixtureIntent when is the game against {Team}”
  3. Point to where the skill code runs
    • Trivial to do if you are using AWS Lambda, but you can use your own https server with a bit more effort
  4. Upload your skill code in your AWS Lambda functions
    • The code can be written in Python, Java or Javascript/NodeJS - I chose the latter as I prefer the easy extensibility.

The example skill code for Lambda is pretty easy to understand and adapt as necessary. Note you can either update the code directly in the browser-based Lambda console, or upload a ZIP file containing your code. The latter is much preferable if you have any node modules you want to include in your solution.

My code simply loads existing JSON data from my server used in the iPhone/Android apps for the fixtures, results and latest score, parses it appropriately based on the user’s intent, and then returns a string which the Echo reads back to the user.

The voice recognition accuracy isn’t too bad - I suspect it struggles because of the slightly obscure names of some of the teams in the Northern Premier League!

All in all, it was pretty easy to knock together something based on existing data, and it’s really cool to be able to ask Alexa what the latest Halesowen score is. I look forward to be able to do this on Siri in about 3 years time at Apple’s currently glacial pace of opening up their systems.

The code is all available on Github at https://github.com/bravelocation/yeltzland-alexa/ which hopefully makes things a little clearer if you want to dive in and take a look.

Building an iMessage app

Now that iOS10 is out I thought it was about time I built an iMessage app for Count The Days Left.

To be honest, it took very little time once I’d written a script to generate all the “progress images” I needed i.e. 100 images that show the percentage completed in the progress bar.

The UI is just a standard Storyboard + UIViewController for layout, and then hooking up an event handler to a ‘Send Message’ button (see below for details).

    @IBAction func sendMessageTouchUp(sender: AnyObject) {
        if let conversation = self.activeConversation {
            let now: NSDate = NSDate()
            let model: DaysLeftModel = DaysLeftModel()
            
             // Make a new layout object
            let layout = MSMessageTemplateLayout()

            // Set the caption on the layout
            layout.caption = model.FullDescription(now)
            
            // Set the correct image on the layout
            let percentageDone: Float = (Float(model.DaysGone(now)) * 100.0) / Float(model.DaysLength)
            let intPercentageDone: Int = Int(percentageDone)            
            let imageName = String(format: "progress%d", intPercentageDone)
            layout.image = UIImage(imageLiteral:imageName)
            
            // Make a new message and set its' layout
            let message = MSMessage()
            message.layout = layout
            
            // Insert the message into the conversation
            conversation.insertMessage(message, completionHandler: { (error: NSError?) in
                print(error)
            })
        }
    }

Other than the usual fun with making everything look OK with Storyboards and Auto Layout at the different screen sizes, it all worked out pretty well as you can see from the screenshot below:

Count The Days left iMessage app screenshot

I’m not sure how useful this will be, but it was very easy to build and I’m pleased with the result.

Getting Ready For iOS 10 Widgets

It’s summer, which means updating all the Brave Location apps for the new version of iOS.

Thankfully this year the UI changes weren’t too big, and the real work was because of how the Today widgets are changed in iOS 10.

In iOS 9, the widgets are on a dark background, so it makes sense for the text to be generally white. Here’s how my stunning well-designed widgets look in the Today section on my iPad running iOS9 …

iOS9 Today widget

Now in iOS 10, the widgets are much more accessible - can be accessed directly by right swiping even on the lock screen - but the design has also fundamentally changed. The background is now a light, semi-transparent color by default, on which obviously the white text of the existing widget design is basically unreadable.

Now I didn’t want to have an iOS10 only release ready, as all of my apps currently target iOS 9.0 and above and I want to keep it that way for a while.

So what I do at runtime is detect whether we are iOS 10.0 or above by the following code snippet:

let ios10AndAbove:Bool = NSProcessInfo.processInfo().isOperatingSystemAtLeastVersion( NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0) )

I can then set the background and text colors of the widgets to appropriate for iOS 10 when necessary, buy keep the “traditional” look and feel on what will soon be legacy versions.

Quite happy with the way it’s turned out, even though I say it myself.

iOS10 Today widget

Updates are should all be in the App Store shortly (in case anyone else is running the iOS10 beta), and for everyone else in September I assume!