Added its own http server for Google Assistant api
This commit is contained in:
parent
9bca47d566
commit
4a31b474c5
5 changed files with 80 additions and 55 deletions
|
|
@ -23,20 +23,44 @@ import java.util.Map;
|
|||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.actions.api.smarthome.*;
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.home.graph.v1.DeviceProto;
|
||||
import com.google.protobuf.Struct;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
import se.hal.HalContext;
|
||||
import se.hal.plugin.assistant.google.endpoint.AuthServlet;
|
||||
import se.hal.plugin.assistant.google.endpoint.AuthTokenServlet;
|
||||
import se.hal.plugin.assistant.google.endpoint.SmartHomeServlet;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.net.http.HttpServer;
|
||||
|
||||
|
||||
public class MySmartHomeApp extends SmartHomeApp {
|
||||
public class SmartHomeImpl extends SmartHomeApp {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static final String PARAM_PORT = "assistant.google.api_port";
|
||||
|
||||
private HttpServer httpServer;
|
||||
|
||||
|
||||
public SmartHomeImpl() {
|
||||
try {
|
||||
GoogleCredentials credentials = GoogleCredentials.fromStream(getClass().getResourceAsStream("assistant_google.conf"));
|
||||
this.setCredentials(credentials);
|
||||
} catch (Exception e) {
|
||||
logger.severe("couldn't load credentials");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
httpServer = new HttpServer(HalContext.getIntegerProperty(PARAM_PORT));
|
||||
httpServer.setPage(AuthServlet.ENDPOINT_URL, new AuthServlet(this));
|
||||
httpServer.setPage(AuthTokenServlet.ENDPOINT_URL, new AuthTokenServlet(this));
|
||||
httpServer.setPage(SmartHomeServlet.ENDPOINT_URL, new SmartHomeServlet(this));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SyncResponse onSync(SyncRequest syncRequest, Map<?, ?> headers) {
|
||||
|
||||
SyncResponse res = new SyncResponse();
|
||||
res.setRequestId(syncRequest.requestId);
|
||||
res.setPayload(new SyncResponse.Payload());
|
||||
|
|
@ -44,7 +68,6 @@ public class MySmartHomeApp extends SmartHomeApp {
|
|||
int numOfDevices = 0;
|
||||
res.payload.devices = new SyncResponse.Payload.Device[numOfDevices];
|
||||
for (int i = 0; i < numOfDevices; i++) {
|
||||
|
||||
SyncResponse.Payload.Device.Builder deviceBuilder =
|
||||
new SyncResponse.Payload.Device.Builder()
|
||||
.setId(device.getId())
|
||||
|
|
@ -41,29 +41,32 @@
|
|||
package se.hal.plugin.assistant.google.endpoint;
|
||||
|
||||
import se.hal.intf.HalJsonPage;
|
||||
import se.hal.plugin.assistant.google.SmartHomeImpl;
|
||||
import zutil.net.http.HttpHeader;
|
||||
import zutil.net.http.HttpPage;
|
||||
import zutil.net.http.HttpPrintStream;
|
||||
import zutil.parser.DataNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class FakeAuthServlet extends HalJsonPage {
|
||||
public class AuthServlet implements HttpPage {
|
||||
public static final String ENDPOINT_URL = "api/assistant/google/auth";
|
||||
|
||||
public AuthServlet(SmartHomeImpl smartHome) {}
|
||||
|
||||
public FakeAuthServlet() {
|
||||
super("api/assistant/google/auth");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataNode jsonRespond(
|
||||
public void respond(
|
||||
HttpPrintStream out,
|
||||
HttpHeader headers,
|
||||
Map<String,Object> session,
|
||||
Map<String,String> cookie,
|
||||
Map<String,String> request) throws Exception {
|
||||
Map<String, Object> session,
|
||||
Map<String, String> cookie,
|
||||
Map<String, String> request) throws IOException {
|
||||
|
||||
StringBuilder redirectURL = new StringBuilder();
|
||||
redirectURL.append(URLDecoder.decode(request.get("redirect_uri"), StandardCharsets.UTF_8));
|
||||
|
|
@ -73,7 +76,5 @@ public class FakeAuthServlet extends HalJsonPage {
|
|||
|
||||
out.setStatusCode(302);
|
||||
out.setHeader("Location", URLEncoder.encode("/login?responseurl=" + redirectURL.toString(), StandardCharsets.UTF_8));
|
||||
|
||||
return new DataNode(DataNode.DataType.Map);
|
||||
}
|
||||
}
|
||||
|
|
@ -40,40 +40,47 @@
|
|||
|
||||
package se.hal.plugin.assistant.google.endpoint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import se.hal.intf.HalJsonPage;
|
||||
import se.hal.plugin.assistant.google.SmartHomeImpl;
|
||||
import zutil.net.http.HttpHeader;
|
||||
import zutil.net.http.HttpPage;
|
||||
import zutil.net.http.HttpPrintStream;
|
||||
import zutil.parser.DataNode;
|
||||
import zutil.parser.json.JSONWriter;
|
||||
|
||||
|
||||
public class FakeTokenServlet extends HalJsonPage {
|
||||
private static int secondsInDay = 86400;
|
||||
public class AuthTokenServlet implements HttpPage {
|
||||
private static final int SECONDS_IN_DAY = 86400;
|
||||
public static final String ENDPOINT_URL = "api/assistant/google/auth_token";
|
||||
|
||||
|
||||
public AuthTokenServlet(SmartHomeImpl smartHome) {}
|
||||
|
||||
public FakeTokenServlet() {
|
||||
super("api/assistant/google/auth_token");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataNode jsonRespond(
|
||||
public void respond(
|
||||
HttpPrintStream out,
|
||||
HttpHeader headers,
|
||||
Map<String,Object> session,
|
||||
Map<String,String> cookie,
|
||||
Map<String,String> request) throws Exception {
|
||||
Map<String, Object> session,
|
||||
Map<String, String> cookie,
|
||||
Map<String, String> request) throws IOException {
|
||||
|
||||
String grantType = request.get("grant_type");
|
||||
|
||||
DataNode jsonRes = new DataNode(DataNode.DataType.Map);
|
||||
jsonRes.set("token_type", "bearer");
|
||||
jsonRes.set("access_token", "123access");
|
||||
jsonRes.set("expires_in", secondsInDay);
|
||||
jsonRes.set("expires_in", SECONDS_IN_DAY);
|
||||
|
||||
if (grantType.equals("authorization_code")) {
|
||||
jsonRes.set("refresh_token", "123refresh");
|
||||
}
|
||||
|
||||
return jsonRes;
|
||||
out.setHeader("Content-Type", "application/json");
|
||||
out.setHeader("Access-Control-Allow-Origin", "*");
|
||||
out.setHeader("Pragma", "no-cache");
|
||||
out.println(JSONWriter.toString(jsonRes));
|
||||
}
|
||||
}
|
||||
|
|
@ -41,68 +41,56 @@
|
|||
package se.hal.plugin.assistant.google.endpoint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.actions.api.smarthome.SmartHomeApp;
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import se.hal.intf.HalJsonPage;
|
||||
import se.hal.plugin.assistant.google.MySmartHomeApp;
|
||||
import se.hal.plugin.assistant.google.SmartHomeImpl;
|
||||
import zutil.io.IOUtil;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.net.http.HttpHeader;
|
||||
import zutil.net.http.HttpPage;
|
||||
import zutil.net.http.HttpPrintStream;
|
||||
import zutil.parser.DataNode;
|
||||
|
||||
/**
|
||||
* Handles request received via HTTP POST and delegates it to your Actions app. See: [Request
|
||||
* handling in Google App
|
||||
* Engine](https://cloud.google.com/appengine/docs/standard/java/how-requests-are-handled).
|
||||
*/
|
||||
public class SmartHomeServlet extends HalJsonPage {
|
||||
public class SmartHomeServlet implements HttpPage {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private final SmartHomeApp actionsApp = new MySmartHomeApp();
|
||||
public static final String ENDPOINT_URL = "api/assistant/google/smarthome";
|
||||
|
||||
{
|
||||
try {
|
||||
GoogleCredentials credentials =
|
||||
GoogleCredentials.fromStream(getClass().getResourceAsStream("/smart-home-key.json"));
|
||||
actionsApp.setCredentials(credentials);
|
||||
} catch (Exception e) {
|
||||
logger.severe("couldn't load credentials");
|
||||
}
|
||||
}
|
||||
private SmartHomeImpl smartHome;
|
||||
|
||||
|
||||
public SmartHomeServlet() {
|
||||
super("api/assistant/google/smarthome");
|
||||
public SmartHomeServlet(SmartHomeImpl smartHome) {
|
||||
this.smartHome = smartHome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected DataNode jsonRespond(
|
||||
public void respond(
|
||||
HttpPrintStream out,
|
||||
HttpHeader headers,
|
||||
Map<String,Object> session,
|
||||
Map<String,String> cookie,
|
||||
Map<String,String> request) throws Exception {
|
||||
Map<String, Object> session,
|
||||
Map<String, String> cookie,
|
||||
Map<String, String> request) throws IOException {
|
||||
|
||||
String body = IOUtil.readContentAsString(headers.getInputStream());
|
||||
logger.info("doPost, body = " + body);
|
||||
|
||||
try {
|
||||
String response = actionsApp.handleRequest(body, request).get();
|
||||
String response = smartHome.handleRequest(body, request).get();
|
||||
|
||||
System.out.println("response = " + asJson);
|
||||
res.getWriter().write(asJson);
|
||||
res.getWriter().flush();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
logger.log(Level.SEVERE, "Failed to handle fulfillment request", e);
|
||||
out.setHeader("Content-Type", "application/json");
|
||||
out.setHeader("Access-Control-Allow-Origin", "*");
|
||||
out.setHeader("Pragma", "no-cache");
|
||||
out.println(response);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Was unable to handle SmartHome request.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"version": 0.1,
|
||||
"name": "Hal-Assistant-Google",
|
||||
"interfaces": [
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue