Google Assistant broadcast api remotely – Home security automation done right pt3
I have 7 Google assistant devices in my house, I was an Amazon Echo fan early on but ran both side by side and went with Google. One of the things I use a lot on the Google devices is music playback from Spotify. It can synchronise playback on several or all of the devices using Speaker Groups.
The Problem
So the Google Assistant API doesn’t allow you to initiate commands. I want to initiate Spotify to play on several devices at a certain volume, automatically via API.
Eg. I can from my Google home device say “hey Google turn on all the lights” or remotely from my phone I can manually start a broadcast of “turn off all my lights”. What I’m unable to do it from a 3rd party system (eg Stringify or Logic Apps) is call the API and issue the commands.
Workarounds?
There isn’t really many viable workarounds for this either, I’ve “googled” this one pretty hard. I think the best option is having a device positioned near a Google assistant that will play a recording of my voice issuing a command… Which isn’t ideal by any means, but does work.
However I do have the complications of choosing the right device that can be remotely initiated reliably for this specific purpose.
Hardware
So focussing on the hardware constraint, I need something reliable and ideally something I already own that won’t cost a fortune to run. I happen to have a spare PAYG phone SIM card lying around in an old Windows Mobile 640 device – good enough.
I recorded my voice onto the device with an app in the Windows App store, set it as my text notification tone and sent it a text. The result, it worked great. However, although I don’t use this number much I still get odd texts from spammers.
I need a dedicated way to play the audio clip. Now if this was Android, I’d use Tasker and would be finished already. Windows Mobile presents some problems, I don’t want to write an app that would poll so it needs to use a sms or a phone call to play the audio clip. Windows Mobile prevents developers that aren’t telecoms providers from reading sms messages on the phone, but I am able to assign a specific ringtone to a specific contact…. 😉
I now need to acquire a dedicated phone number to automatically call my phone from, in order to play this specific ringtone. Introducing Twillio. It will allow me to programmatically sent sms or do clever stuff with telephony. My use case is simple, initiate an outbound call to a specific number.
Twilio Integration
The first thing to do, is to register for Twilio, and pay for a number (this is $1 a month, and I can’t see another way around the problem). I then have to write some code to talk to the Twilio API in order to initiate the phone call.
Here’s the Azure Function I’ve written, you can find it in GitHub here: https://github.com/Gordonby/OutgoingPhoneCall
using Twilio; using Twilio.Rest.Api.V2010.Account; using Twilio.Types; namespace TwilioFunctions { public static class TwilioOutgoing { /// <summary> /// Initiates a simple outgoing phone call to a number. /// </summary> [FunctionName("SimpleOutgoing")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { //Acquire number to call from querystring/body string number = req.Query["number"]; string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); number = number ?? data?.number; log.LogInformation(number); //Get Twilio account specific info from Environment Variables string accountSid = Environment.GetEnvironmentVariable("TwilioAccountSID"); string authToken = Environment.GetEnvironmentVariable("TwilioAuthToken"); string fromNumber = Environment.GetEnvironmentVariable("TwilioFromNumber"); //Init Twilio TwilioClient.Init(accountSid, authToken); PhoneNumber to = new PhoneNumber(number); PhoneNumber from = new PhoneNumber(fromNumber); var call = CallResource.Create(to, from, url: new Uri("http://demo.twilio.com/docs/voice.xml")); log.LogInformation(call.Sid); return number != null ? (ActionResult)new OkObjectResult(call.Sid) : new BadRequestObjectResult("Please pass a number to call on the query string or in the request body"); } } }
From an HTTP request, I can now have remote access to my Google Assistant at home 🙂
This post is part of a series of posts in my home automation journey, check out the rest here;
https://gordon.byers.me/azure/home-security-automation-done-right-blog-series/