Three weeks ago we took the team on a trip to Budapest, Hungary to play around with our Amazon Echo. We decided to build a Wunderlist Skill, since we are using it ourselves and there seems to be some demand from other users as well. Today the skill finally got approved and you can get it here in German or here in English.
Getting the Skill off the Ground
The trip was limited to three days and we committed to publish the skill by Wednesday noon. We weren’t familiar with the SDKs before the trip, so we had to make sure we can move fast. We’re most comfortable writing Java and Kotlin code. Since Kotlin outpaces Java in terms of developer productivity it was the natural choice. We also wanted to get a better feeling for AWS Lambda, so we chose to deploy the skill there.
Getting started was quite easy. An article by Mark Heckler was helpful in getting to see an entire skill written in Java (thanks Mark!). The initial version was running 2 hours later.
Navigating the SDK and AWS Lambda
The skill can be used in German and English, though it required some effort to implement i18n. We had to learn, that in German a skill can not handle the raw text provided by a user talking to Alexa. For example, telling Alexa to add Streuselkuchen to the shopping list won’t work unless the term has been added manually to a list, which is then matched against the speech input. This was a bummer, since there are so many items one might add to their list, we couldn’t possibly cover them all.
Fortunately there are some builtin lists, and to make things easier we decided to only cover the shopping list use case for the time being. If you think about this limitation, there is another issue we had to solve: which list will the skill use? Using any of the default lists by Wunderlist, such as inbox might drive people crazy. You probably don’t want vegetables showing up in your inbox, along the other important stuff, do you?
So we provided a default list named Alexa shopping, to which all items are added. Most groceries should work with the skill, but we will most likely add more later on, based on your feedback.
We jumped right into building the skill, but did pay little attention to the interaction model. How will users interact with the skill? How to deal with errors? These things should be addressed up front since the audio experience is way more personal than using a browser and having to deal with a stacktrace that’s thrown at you. For example, if Alexa is unable to understand whatever you just said – how often do you expect her(?) to ask again before giving up? So you better think about these questions early on.
Once a user starts invoking the skill, a session is started. This session remains open for as long as the user interacts with the skill. It might end anytime if the user asks Alexa to quit, or if there are issues the skill cannot handle. You can store information for the duration of a session, such as the list currently selected. It worked well for our use case, but more complex skills might benefit from using a persistent storage.
AWS Lambda worked like a charm, deployments required uploading the Java Archive.
We’ve done it using the web interface, though S3 is also supported.
Since we picked Kotlin, the archive also contained the standard lib which made it a bit bigger than plain Java skills – but not much.
In turn we got the benefits of handling
null values in a concise manner.
If user input cannot be matched against a term from the available lists it’s just
null in the SDK and you have to deal with it.
At times we had to debug the skill, which is not that easy using AWS Lambda. The only thing you can do is turn on logging and go from there. But if that is really an issue, you can still deploy the skill somewhere else (as Mark has described in his post).
Once the skill had been submitted for certification, it took a few days until we got feedback. The skill as it was didn’t pass certification – boo. However, Amazon was super helpful pointing out all the issues that prevented the skill from getting accepted. We mostly had to deal with copyright infringement since we were using the term Wunderlist all over the skill. So we had to rename everything and make sure our skill is recognized as not being an official app by 6Wunderkinder.
But the biggest issue we faced was account linking. When you want to use the skill, you have to login to Wunderlist so the skill can make requests on your behalf. This required setting up an application in Wunderlist, which we did. Doing so requires setting a redirect URL, which Wunderlist will redirect back to after authorization has happened. So if you allow example.com as redirect URL but a client sends the return URL example.org as part of the OAuth authorization, then Wunderlist will not allow that (justifiable so).
And this is just what has happened. Requests sent by the skill will contain one of two possible redirect URLs, if the whitelisted one is being used all is good. Otherwise we would run into an error. We don’t have enough insight into why there are two redirect URLs, most likely because for load balancing reasons and dispatching requests closer to where they originated from. Which would make sense, since the skill is available in all countries currently supported.
Onwards. We tried a few approaches to make the account linking work, but failed every so often. We contacted the Wunderlist support (which responded blazing fast and was very helpful). We also raised the question in the Amazon developer forums, but are still waiting for a response.
Eventually, we ended up setting up a simple nginx proxy. Wunderlist only knows the proxy URL, which itself is able to dispatch to either URL provided by Amazon. The proxy is only used during the account linking process and will only perform the routing.
We would be happy to have a better solution in place, but at least it’s working for the time being.
All in all it was a lot of fun to develop a skill and we may publish more skills in the future. If you want to learn more about Alexa skill development or want to discuss related topics, just drop us a line at firstname.lastname@example.org
You can also send us feedback for the Wunderlist skill.