问题描述
我目前正在尝试构建自己的Google家用设备。
我正在使用本教程:https://codelabs.developers.google.com/codelabs/smarthome-washer#0。如果我将代码部署到firebase,它会很好地工作,但是我想在自己的服务器上运行它。因此,我重写了代码以在正常的nodejs环境中工作。身份验证和令牌部分可以正常工作,但是如果google home应用调用“ / smarthome”(实现网址“输入用于处理智能家居意图的webhook。”,在google action控制台中设置),则正文和查询对象为空的。至少应该有requestId。如果我在firebase中运行它,身体看起来会很好。
在firebase中有效的代码:
exports.smarthome = functions.https.onRequest((req,res) => {
functions.logger.info(req.body.requestId);
});
我重写的代码(整个身体都是空的):
app.all("/smarthome",urlencodedParser,function(req,res){
console.log(req.body);
console.log(req.query);
console.log(req.body.requestId);
});
现在我的问题是:我做错什么了吗?还是根本不可能在另一台服务器上完成任务。
/**
* copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License,Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,software
* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const functions = require('firebase-functions');
const {smarthome} = require('actions-on-google');
const {google} = require('googleapis');
const util = require('util');
const admin = require('firebase-admin');
// Initialize Firebase
admin.initializeApp();
const firebaseRef = admin.database().ref('/');
// Initialize Homegraph
const auth = new google.auth.GoogleAuth({
scopes: ['https://www.googleapis.com/auth/homegraph'],});
const homegraph = google.homegraph({
version: 'v1',auth: auth,});
// Hardcoded user ID
const USER_ID = '123';
exports.login = functions.https.onRequest((request,response) => {
functions.logger.log('Requesting login page');
if (request.method === 'GET') {
functions.logger.log('Requesting login page');
response.send(`
<html>
<Meta name="viewport" content="width=device-width,initial-scale=1">
<body>
<form action="/login" method="post">
<input type="hidden"
name="responseurl" value="${request.query.responseurl}" />
<button type="submit" style="font-size:14pt">
Link this service to Google
</button>
</form>
</body>
</html>
`);
} else if (request.method === 'POST') {
// Here,you should validate the user account.
// In this sample,we do not do that.
const responseurl = decodeURIComponent(request.body.responseurl);
functions.logger.log(`Redirect to ${responseurl}`);
return response.redirect(responseurl);
} else {
// Unsupported method
response.send(405,'Method Not Allowed');
}
});
exports.fakeauth = functions.https.onRequest((request,response) => {
const responseurl = util.format('%s?code=%s&state=%s',decodeURIComponent(request.query.redirect_uri),'xxxxxx',request.query.state);
functions.logger.log(`Set redirect as ${responseurl}`);
return response.redirect(
`/login?responseurl=${encodeURIComponent(responseurl)}`);
});
exports.faketoken = functions.https.onRequest((request,response) => {
const grantType = request.query.grant_type ?
request.query.grant_type : request.body.grant_type;
const secondsInDay = 86400; // 60 * 60 * 24
const HTTP_STATUS_OK = 200;
functions.logger.log(`Grant type ${grantType}`);
let obj;
if (grantType === 'authorization_code') {
obj = {
token_type: 'bearer',access_token: '123access',refresh_token: '123refresh',expires_in: secondsInDay,};
} else if (grantType === 'refresh_token') {
obj = {
token_type: 'bearer',};
}
response.status(HTTP_STATUS_OK)
.json(obj);
});
const app = smarthome();
app.onSync((body,headers) => {
return {};
});
const queryFirebase = async (deviceid) => {
const snapshot = await firebaseRef.child(deviceid).once('value');
const snapshotVal = snapshot.val();
// Todo: Define device states to return
return {};
};
// eslint-disable-next-line
const queryDevice = async (deviceid) => {
const data = await queryFirebase(deviceid);
// Todo: Define device states to return
return {};
};
app.onQuery((body) => {
// Todo: Implement QUERY response
return {};
});
const updateDevice = async (execution,deviceid) => {
// Todo: Add commands to change device states
};
app.onExecute((body) => {
// Todo: Implement EXECUTE response
return {};
});
app.ondisconnect((body,headers) => {
functions.logger.log('User account unlinked from Google Assistant');
// Return empty response
return {};
});
//exports.smarthome = functions.https.onRequest(home); normal method (deactivated for testing)
exports.smarthome = functions.https.onRequest((req,res) => {
functions.logger.info(req.body.requestId);
});
exports.requestsync = functions.https.onRequest(async (req,res) => {
res.set('Access-Control-Allow-Origin','*');
functions.logger.info(`Request SYNC for user ${USER_ID}`);
try {
const res = await homegraph.devices.requestSync({
requestBody: {
agentUserId: USER_ID,},});
functions.logger.info('Request sync response:',res.status,res.data);
res.json(res.data);
} catch (err) {
functions.logger.error(err);
res.status(500).send(`Error requesting sync: ${err}`);
}
});
/**
* Send a REPORT STATE call to the homegraph when data for any device id
* has been changed.
*/
exports.reportstate = functions.database.ref('{deviceid}').onWrite(
async (change,context) => {
functions.logger.info('Firebase write event triggered Report State');
// Todo: Get latest state and call HomeGraph API
});
我的整个代码:
const hostname = '0.0.0.0';
const port = 8080;
var https = require("https");
const util = require('util');
var express = require('express');
var bodyParser = require('body-parser')
const {google} = require('googleapis');
const {smarthome} = require('actions-on-google');
var app = express();
var jsonParser = bodyParser.json()
var urlencodedParser = bodyParser.urlencoded({ extended: false })
const USER_ID = '123';
const auth = new google.auth.GoogleAuth({
scopes: ['https://www.googleapis.com/auth/homegraph'],});
const homegraph = google.homegraph({
version: 'v1',});
app.get('/login',res) {
console.log('login_get');
res.send(`
<html>
<Meta name="viewport" content="width=device-width,initial-scale=1">
<body>
<form action="/login" method="post">
<input type="hidden"
name="responseurl" id="responseurl" value="${req.query.responseurl}" />
<button type="submit" style="font-size:14pt">
Link this service to Google
</button>
</form>
</body>
</html>
`);
});
app.post("/login",res){
console.log('login_post');
const responseurl = decodeURIComponent(req.body.responseurl);
return res.redirect(responseurl);
});
app.all('/auth',res) {
console.log('auth');
const responseurl = util.format('%s?code=%s&state=%s',decodeURIComponent(req.query.redirect_uri),req.query.state);
return res.redirect(
`/login?responseurl=${encodeURIComponent(responseurl)}`);
});
app.all('/token',res) {
console.log('token');
const grantType = req.query.grant_type ?
req.query.grant_type : req.body.grant_type;
const secondsInDay = 86400; // 60 * 60 * 24
const HTTP_STATUS_OK = 200;
let obj;
if (grantType === 'authorization_code') {
obj = {
token_type: 'bearer',};
} else if (grantType === 'refresh_token') {
obj = {
token_type: 'bearer',};
}
res.status(HTTP_STATUS_OK)
.json(obj);
});
app.all('/requestsync',async function(req,res) {
console.log("requestsync");
res.set('Access-Control-Allow-Origin','*');
try {
const res = await homegraph.devices.requestSync({
requestBody: {
agentUserId: USER_ID,});
console.log('Request sync response:',res.data);
res.json(res.data);
} catch (err) {
console.log(err);
res.status(500).send(`Error requesting sync: ${err}`);
}
});
const home = smarthome();
home.onSync((body,headers) => {
console.log("onSync");
return {};
});
home.onQuery((body) => {
console.log("onQuery");
return {};
});
home.onExecute((body) => {
console.log("onExecute");
return {};
});
home.ondisconnect((body,headers) => {
console.log("ondisconnect");
return {};
});
//exports.smarthome = home;
//exports.smarthome = https.onRequest(home);
app.all("/smarthome",res){
console.log(req.body);
console.log(req.query);
console.log(req.body.requestId);
home(req,res);
});
app.listen(port,hostname,() => {
console.log(`Server running at http://${hostname}:${port}/`);
});
请分享一些想法。 乔纳斯(Jonas)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)