mirror of
https://github.com/koush/scrypted.git
synced 2026-05-26 14:40:29 +01:00
Merge branch 'main' of github.com:koush/scrypted
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/alexa",
|
||||
"version": "0.0.20",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
"prescrypted-setup-project": "scrypted-package-json",
|
||||
@@ -35,7 +35,7 @@
|
||||
"dependencies": {
|
||||
"@types/node": "^16.6.1",
|
||||
"alexa-smarthome-ts": "^0.0.1",
|
||||
"axios": "^0.24.0",
|
||||
"axios": "^1.3.4",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import axios from 'axios';
|
||||
import sdk, { HttpRequest, HttpRequestHandler, HttpResponse, MixinProvider, ScryptedDevice, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface } from '@scrypted/sdk';
|
||||
import sdk, { HttpRequest, HttpRequestHandler, HttpResponse, MixinProvider, ScryptedDevice, ScryptedDeviceType, ScryptedInterface, Setting, SettingValue, Settings } from '@scrypted/sdk';
|
||||
import { StorageSettings } from '@scrypted/sdk/storage-settings';
|
||||
import { AutoenableMixinProvider } from '@scrypted/common/src/autoenable-mixin-provider';
|
||||
import { isSupported } from './types';
|
||||
@@ -12,16 +12,22 @@ const { systemManager, deviceManager } = sdk;
|
||||
const client_id = "amzn1.application-oa2-client.3283807e04d8408eb44a698c10f9dd13";
|
||||
const client_secret = "bed445e2b26730acd818b90e175b275f6b67b18ff8645e571c5b3e311fa75ee9";
|
||||
|
||||
class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler, MixinProvider {
|
||||
class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler, MixinProvider, Settings {
|
||||
storageSettings = new StorageSettings(this, {
|
||||
tokenInfo: {
|
||||
hide: true,
|
||||
json: true,
|
||||
json: true
|
||||
},
|
||||
syncedDevices: {
|
||||
multiple: true,
|
||||
hide: true,
|
||||
hide: true
|
||||
},
|
||||
apiEndpoint: {
|
||||
title: 'Alexa Endpoint',
|
||||
description: 'This is the endpoint Alexa will use to send events to. This is set after you login.',
|
||||
type: 'string',
|
||||
readonly: true
|
||||
}
|
||||
});
|
||||
|
||||
handlers = new Map<string, AlexaHandler>();
|
||||
@@ -85,6 +91,13 @@ class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler,
|
||||
});
|
||||
}
|
||||
|
||||
getSettings(): Promise<Setting[]> {
|
||||
return this.storageSettings.getSettings();
|
||||
}
|
||||
putSetting(key: string, value: SettingValue): Promise<void> {
|
||||
return this.storageSettings.putSetting(key, value);
|
||||
}
|
||||
|
||||
async getMixin(mixinDevice: any, mixinDeviceInterfaces: ScryptedInterface[], mixinDeviceState: { [key: string]: any; }): Promise<any> {
|
||||
return mixinDevice;
|
||||
}
|
||||
@@ -99,11 +112,41 @@ class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler,
|
||||
deviceManager.requestRestart();
|
||||
}
|
||||
|
||||
readonly endpoints: string[] = [
|
||||
'api.amazonalexa.com',
|
||||
'api.eu.amazonalexa.com',
|
||||
'api.fe.amazonalexa.com'
|
||||
];
|
||||
|
||||
async getAlexaEndpoint() : Promise<string> {
|
||||
if (this.storageSettings.values.apiEndpoint)
|
||||
return this.storageSettings.values.apiEndpoint;
|
||||
|
||||
try {
|
||||
const accessToken = await this.getAccessToken();
|
||||
const response = await axios.get(`https://${this.endpoints[0]}/v1/alexaApiEndpoint`, {
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + accessToken,
|
||||
}
|
||||
});
|
||||
|
||||
const endpoint: string = response.data.endpoints[0];
|
||||
this.storageSettings.values.apiEndpoint = endpoint;
|
||||
return endpoint;
|
||||
} catch (err) {
|
||||
this.console.error(err);
|
||||
|
||||
// default to NA/RoW endpoint if we can't get the endpoint.
|
||||
return this.endpoints[0];
|
||||
}
|
||||
}
|
||||
|
||||
async postEvent(data: any) {
|
||||
const accessToken = await this.getAccessToken();
|
||||
const endpoint = await this.getAlexaEndpoint();
|
||||
const self = this;
|
||||
|
||||
return axios.post('https://api.amazonalexa.com/v3/events', data, {
|
||||
return axios.post(`https://${endpoint}/v3/events`, data, {
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + accessToken,
|
||||
}
|
||||
@@ -267,6 +310,7 @@ class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler,
|
||||
const json = JSON.parse(request.body);
|
||||
const { grant } = json.directive.payload;
|
||||
this.storageSettings.values.tokenInfo = grant;
|
||||
this.storageSettings.values.apiEndpoint = undefined;
|
||||
this.accessToken = undefined;
|
||||
|
||||
const self = this;
|
||||
@@ -274,6 +318,7 @@ class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler,
|
||||
self.console.error(`Failed to handle the AcceptGrant directive because ${reason}`);
|
||||
|
||||
this.storageSettings.values.tokenInfo = undefined;
|
||||
this.storageSettings.values.apiEndpoint = undefined;
|
||||
this.accessToken = undefined;
|
||||
|
||||
response.send(JSON.stringify({
|
||||
@@ -311,6 +356,7 @@ class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler,
|
||||
this.console.error(`AcceptGrant.Response failed because ${error}`);
|
||||
|
||||
this.storageSettings.values.tokenInfo = undefined;
|
||||
this.storageSettings.values.apiEndpoint = undefined;
|
||||
this.accessToken = undefined;
|
||||
throw error;
|
||||
}
|
||||
@@ -455,7 +501,7 @@ class AlexaPlugin extends AutoenableMixinProvider implements HttpRequestHandler,
|
||||
catch (e) {
|
||||
this.console.error(`request failed due to invalid authorization`, e);
|
||||
response.send(e.message, {
|
||||
code: 500,
|
||||
code: 500
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ export class AlexaSignalingSession implements RTCSignalingSession {
|
||||
// this could be a low resolution screen, no way of knowing, so never send a
|
||||
// 1080p+ stream.
|
||||
screen: {
|
||||
devicePixelRatio: 1, // TODO: get this from the device
|
||||
width: 1280,
|
||||
height: 720,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user