UNPKG

6.1 kBJavaScriptView Raw
1"use strict";
2/**
3 * Copyright 2018 Google Inc. All Rights Reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.smarthome = void 0;
19const assistant_1 = require("../../assistant");
20const common = require("../../common");
21const googleapis_1 = require("googleapis");
22const encoding = 'utf8';
23const homegraphWrapperDeprecationNotice = method => `SmartHomeApp.${method} Home Graph wrapper method is deprecated. Use Google APIs Node.js Client for Home Graph: https://www.npmjs.com/package/@googleapis/homegraph`;
24const makeApiCall = (url, data, jwt) => {
25 const options = {
26 hostname: 'homegraph.googleapis.com',
27 port: 443,
28 path: url,
29 method: 'POST',
30 headers: {},
31 };
32 const apiCall = (options) => {
33 if (jwt && !options.headers.Authorization) {
34 throw new Error('JWT is defined but Authorization header is not defined ' +
35 JSON.stringify(options));
36 }
37 return new Promise((resolve, reject) => {
38 const buffers = [];
39 const req = common.request(options, res => {
40 res.on('data', d => {
41 buffers.push(typeof d === 'string' ? Buffer.from(d, encoding) : d);
42 });
43 res.on('end', () => {
44 const apiResponse = Buffer.concat(buffers).toString(encoding);
45 const apiResponseJson = JSON.parse(apiResponse);
46 if (apiResponseJson.error && apiResponseJson.error.code >= 400) {
47 // While the response ended, it contains an error.
48 // In this case, this should reject the Promise.
49 reject(apiResponse);
50 return;
51 }
52 resolve(apiResponse);
53 });
54 });
55 req.on('error', e => {
56 reject(e);
57 });
58 // Write data to request body
59 req.write(JSON.stringify(data));
60 req.end();
61 });
62 };
63 if (jwt) {
64 return new Promise((resolve, reject) => {
65 // For testing, we do not need to actually authorize
66 if (jwt.client_id === 'sample-client-id') {
67 options.headers = {
68 Authorization: ' Bearer 1234',
69 };
70 resolve(options);
71 return;
72 }
73 // Generate JWT, then make the API call if provided
74 const jwtClient = new googleapis_1.google.auth.JWT(jwt.client_email, undefined, jwt.private_key, ['https://www.googleapis.com/auth/homegraph'], undefined);
75 jwtClient.authorize((err, tokens) => {
76 if (err) {
77 return reject(err);
78 }
79 options.headers = {
80 Authorization: ` Bearer ${tokens.access_token}`,
81 };
82 resolve(options);
83 });
84 }).then(options => {
85 return apiCall(options);
86 });
87 }
88 else {
89 return apiCall(options);
90 }
91};
92/**
93 *
94 * @example
95 * ```javascript
96 *
97 * const app = smarthome({
98 * debug: true,
99 * key: '<api-key>',
100 * jwt: require('./key.json')
101 * });
102 *
103 * app.onSync((body, headers) => {
104 * return { ... }
105 * });
106 *
107 * app.onQuery((body, headers) => {
108 * return { ... }
109 * });
110 *
111 * app.onExecute((body, headers) => {
112 * return { ... }
113 * });
114 *
115 * exports.smarthome = functions.https.onRequest(app);
116 *
117 * ```
118 *
119 * @public
120 */
121const smarthome = (options = {}) => assistant_1.attach({
122 _intents: {},
123 _intent(intent, handler) {
124 this._intents[intent] = handler;
125 return this;
126 },
127 onSync(handler) {
128 return this._intent('action.devices.SYNC', handler);
129 },
130 onQuery(handler) {
131 return this._intent('action.devices.QUERY', handler);
132 },
133 onExecute(handler) {
134 return this._intent('action.devices.EXECUTE', handler);
135 },
136 onDisconnect(handler) {
137 return this._intent('action.devices.DISCONNECT', handler);
138 },
139 async requestSync(agentUserId) {
140 common.warn.log(homegraphWrapperDeprecationNotice('requestSync'));
141 if (this.jwt) {
142 return await makeApiCall('/v1/devices:requestSync', {
143 agent_user_id: agentUserId,
144 }, this.jwt);
145 }
146 if (this.key) {
147 return await makeApiCall(`/v1/devices:requestSync?key=${encodeURIComponent(this.key)}`, {
148 agent_user_id: agentUserId,
149 });
150 }
151 throw new Error('An API key was not specified. ' +
152 'Please visit https://console.cloud.google.com/apis/api/homegraph.googleapis.com/overview');
153 },
154 async reportState(reportedState) {
155 common.warn.log(homegraphWrapperDeprecationNotice('reportState'));
156 if (!this.jwt) {
157 throw new Error('A JWT was not specified. ' +
158 'Please visit https://console.cloud.google.com/apis/credentials');
159 }
160 return await makeApiCall('/v1/devices:reportStateAndNotification', reportedState, this.jwt);
161 },
162 key: options.key,
163 jwt: options.jwt,
164 async handler(body, headers, metadata = {}) {
165 const { intent } = body.inputs[0];
166 const handler = this._intents[intent];
167 return {
168 status: 200,
169 headers: {},
170 body: await handler(body, headers, metadata),
171 };
172 },
173}, options);
174exports.smarthome = smarthome;
175//# sourceMappingURL=smarthome.js.map
\No newline at end of file