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:
[php]</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>[/php]
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 %