Creating an iOS Shortcut for Sonos

Steve Hall
5 min readJun 27, 2020

I have music playing most of the day. Not just music in the background, but music specific to what I’m doing at the time. Having coffee? Maybe some indie singer/songwriter. Cooking Italian? Opera…of course. Working out? Not Chopin. But Sonos doesn’t make it quick and easy to get to your music. It can take 12–16 (or more) gestures for me to unlock my phone, navigate to the Sonos app, run it, select the room, select favorites, tap in to see all favorites, and scroll to the one I want to play.

Navigating to Sonos favorites…way too many gestures.

Oh sure, I could try and use Siri/Alexa, but let’s face it, trying to remember the exact playlist name, or having that service confuse Al di Meola with Aldo Nova, makes it problematic.

I recently completed a project here, putting a Raspberry Pi into an antique-style phone in order to control my Sonos with touch tones, voice (using Alexa), and imaging. You can see a shaky-cam video of it here. That project uses a Node API to talk to Sonos. I use that same API for the iOS Shortcut I’ll describe below.

In order for this iOS Shortcut to work, you’ll need to have the Node API running on a machine 24 x 7. A Raspberry Pi works great, but could also be your Windows, Mac, or Linux box. It also must be on your local network.

Building the Shortcut

The Node API provides a number of features in order for us to be able to control and get info from your Sonos system. We are going to use three of those features:

  1. Get all Sonos zones (rooms)
  2. Retrieves all Sonos Favorites
  3. Play a Favorite in a particular zone/room

Getting Zone Info

I will assume you have the Node API configured and running, and that you have its IP address.

Open up the Shortcuts app on your iPhone/iPad and create a new Shortcut.

Add a Network step from the Web->Web Requests actions called “Get Contents of URL”. Add your IP address, port number and the API command “zones”. It should look like this:

Sonos Zones info

When this command is called, it returns all of the info about your Sonos units. Their names, what they are playing, whether they are playing or paused, etc. There’s a lot of info, so we need to pare it down and only retrieve what’s important to us. The room names.

Add a Get Dictionary Value step from Scripting->Dictionaries. Configure it so your Shortcut appears as follows:

Iterate Through Zones/Rooms

Now let’s grab all of the room names. Add a Repeat With Each action from Scripting->Control Flow. Inside that loop, add a Get Dictionary Value and an Add to Variable action from Scripting->Variables. Configure as follows:

Loop to grab all of the rooms in your Sonos system

Choose Zone

Now that we have all of the zones stored in the variable Zones, let’s ask the user to choose one.

Add a Choose from List action from Scripting->Lists. Choose from the Zones variable. Next, add a Set Variable action from Scripting->Variables and set a variable Room to the Chosen Item.

Prompt user to choose from the Zones list

Fantastic! Let’s run this!

If all goes well, you should get a list of all of your Sonos zones to choose from like below:

Retrieving Favorites

Next, we want to perform a similar set of actions for retrieving favorites. Favorites can be added anytime using the Sonos app and they are stored on the Sonos units themselves.

Getting Sonos Favorites from the Node API

The above step is nearly identical to how we retrieved zone information, we are now just asking for favorites instead. This command doesn’t return as much information as the zones command, but unfortunately it is formatted horribly for our use. We have to perform some creative editing in order to use the information.

We’ll use the Replace Text action in Documents->Text Editing group to get rid of some characters in this response. It will be very important to add these correctly in order to get the text formatted the way we will need it.

In the first replace, we want to search for a left-bracket and a quote. ( [“ ). We want replace this with nothing. In the Shortcut editor, nothing appears as World. We’ll take a similar action by replacing ( “] ) with nothing as well.

Finally, we want to remove all other quotes by searching for ( ) and replacing with nothing again.

Sequence of steps for preparing favorites

Next, we want to split this text into a list at each comma. Add a Split action from Documents->Text Editing as follows, and set it to a variable called Favs:

Let’s again allow the user to select from a list, this time we’ll have them select from Favs.

Prompt user to choose from Favs

Go ahead and run this for another test. We are so close now!

Have Sonos Play Favorite

We have two steps left. The first is to encode the data we want to send to Sonos. In essence, we have to take any characters that URLs do not typically like and encode them into something that’s acceptable. For instance, spaces aren’t typically allowed so they are replaced by “%20”. For all of the nitty-gritty, refer to this write-up.

Add the URL Encode action from Scripting->X-Callback, and also a Get Contents of URL action from Web->Web Requests as in previous steps. Configure as follows:

Send play favorite request to Sonos

That’s it! Finished. Try it out, give it a name, icon and color and add it to your home screen. Now, when you want to play a Sonos Favorite, just select the shortcut and in two quick taps you are playing one of your favorites!

--

--