I wanted to be able to wake up PC on my Lan using voice commands. To achieve that, I did implement a solution using Google Assistant, IFTTT and a php web page hosted on my NAS.
Click to Read More
Regarding IFTTT, you must have an account. Then,
- Create a new applet,
- Choose the service "Google Assistant"
- Choose a trigger, ex.: "Say a phrase with a text ingredient"
- Type a phrase in "What do you want to say?" such as "Wake up my PC $" ($ is the symbol to be used for the "ingredient")
- Type a phrase in "What do you want the Assistant to say in response?" such as "Ok, I will wake up $"
- Choose next an action service "Webhooks" (to "make a web request")
- Type the url of your web page: http://<public Ip of your NAS>/<some path>/action.php?do=wakeup¶m={{TextField}} ({{TextField}} will take the value of the ingredient)
- Chose the "method": GET
- Chose the "content type": text/plain
Regarding the php web page (action.php), I had to do some fine tuning... So, I started with a page logging all information received from IFTTT:
</pre> <?php // https://gist.github.com/magnetikonline/650e30e485c0f91f2f40 class DumpHTTPRequestToFile { public function execute($targetFile) { $boby = json_decode(file_get_contents('php://input') , true); $data = sprintf("<h2><u>IFTTT call at %s on %s</u></h2><h3>Method:</h3>", date('h:i:s') , date('d/m/Y')); $data .= sprintf("<blockquote>%s (%s): %s </blockquote><h3>HTTP headers:</h3><ul>", $_SERVER['REQUEST_METHOD'], $_SERVER['SERVER_PROTOCOL'], htmlentities($_SERVER['REQUEST_URI'])); foreach ($this->getHeaderList() as $name => $value) { $data .= "<li><b>" . $name . '</b>: ' . $value . "</li>"; } $data .= "</ul><h3>Post:</h3><ul>"; foreach ($_POST as $key => $value) $data .= "<li>" . $key . '=' . $value . '</li>'; $bodyhtml = $this->jsonToTable($boby); $data .= "</ul><h3>Request body:</h3><blockquote>$bodyhtml</blockquote>"; $action = trim(strtolower($_GET['action'])); $action = preg_replace('/^ *de +/', '', $action); $action = preg_replace('/^ *d *\' +/', '', $action); $param = trim(strtolower($_GET['param'])); $param = preg_replace('/^ *de +/', '', $param); $param = preg_replace('/^ *d *\' +/', '', $param); $data .= "<h3>Requested Action:</h3><blockquote>$action: $param</blockquote>"; similar_text(strtolower($param) , "zeus", $percent); $data .= "Zeus: $percent %<br>"; similar_text(strtolower($param) , "chaos", $percent); $data .= "Chaos: $percent %<br>"; file_put_contents($targetFile, $data . file_get_contents($targetFile) . "\n"); echo (nl2br($data)); } private function getHeaderList() { $headerList = []; foreach ($_SERVER as $name => $value) { if (preg_match('/^HTTP_/', $name)) { // convert HTTP_HEADER_NAME to Header-Name $name = strtr(substr($name, 5) , '_', ' '); $name = ucwords(strtolower($name)); $name = strtr($name, ' ', '-'); // add to list $headerList[$name] = $value; } } return $headerList; } private function jsonToTable($data) { $table = "<table class='json-table' width='100%'>"; foreach ($data as $key => $value) { $table .= "<tr valign='top'>"; if (!is_numeric($key)) { $table .= " <td> <strong>" . $key . ":</strong> </td> <td> "; } else { $table .= " <td colspan='2'> "; } if (is_object($value) || is_array($value)) { $table .= jsonToTable($value); } else { $table .= $value; } $table .= " </td> </tr> "; } $table .= "</table>"; return $table; } } (new DumpHTTPRequestToFile)->execute('./action.html'); ?> <pre>
The log is stored in a html page "log.html".
Notes:
- I notice that Google was not good at recognizing the name of my PC (IMO because I use French sentences). So I am using a php command "similar_text" to evaluate the "ingredient". But this is really far from effective.
- I tried to use a "POST" method instead of "Get" and a Content Type "application/json", it works. But when I add a Body like {“token”:”mseries”,”command”: “<<<{{TextField}}>>>”, ”test”: “data”}, I don't see it received by my php page
- If Google Assistant does not call correcly IFTTT, look at you voice command history to be sure it understood you order: https://myactivity.google.com/myactivity?restrict=vaa&utm_source=help
- If Google Assistant understood correctly your command, but IFTTT didn't call your web page, look at your IFTTT activity: https://ifttt.com/activity
A log for a call using a GET method will look like:
IFTTT call at 11:32:29 on 25/09/2018
Method: GET (HTTP/1.1): /ifttt/action.php?action=wakeup¶m=CARROS
HTTP headers:
X-Newrelic-Transaction: PxQGUlECCwFRBVEEVQAAAlQTGlUDChAHHEAJVA1cAgMKA1gEVFNVUVUHFU1EAQACBV1UBlUTag==
X-Newrelic-Id: VwAOU1RRGwAFUFZUAwQE
Content-Type: text/plain
Content-Length: 74
Connection: close
Host: olympe.letroye.be
X-Real-Port: 55748
X-Port: 80
X-Real-Ip: 54.164.110.125
X-Forwarded-By: 192.168.0.200
Post:
Request body:
Requested Action: wakeup: CARROS
Zeus: 20 %
Chaos: 72.727272727273 %
A log for a call using a POST method with application/json content-type will look like:
IFTTT call at 11:41:14 on 25/09/2018
Method: POST (HTTP/1.1): /ifttt/action.php?action=wakeup¶m=Kaos
HTTP headers:
X-Newrelic-Id: VwAOU1RRGwAFUFZUAwQE
Content-Type: application/json
Content-Length: 77
Connection: close
Host: olympe.letroye.be
X-Real-Port: 59892
X-Port: 80
X-Real-Ip: 54.211.16.53
X-Forwarded-By: 192.168.0.200
Post:
Request body:
Requested Action: wakeup: kaos
Zeus: 25 %
Chaos: 66.666666666667 %