Skip to content

Commit

Permalink
Used rawEvent and added more types
Browse files Browse the repository at this point in the history
  • Loading branch information
omenocal committed Sep 4, 2018
1 parent f7bf27b commit 369644e
Show file tree
Hide file tree
Showing 16 changed files with 229 additions and 123 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"coveralls": "^3.0.1",
"mocha": "^4.0.1",
"mocha-jenkins-reporter": "^0.3.9",
"nock": "^9.6.1",
"nyc": "^11.4.1",
"portfinder": "^1.0.13",
"rimraf": "^2.6.2",
Expand Down
2 changes: 0 additions & 2 deletions src/VoxaEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ export abstract class IVoxaEvent {
public requestToIntent: ITypeMap = {};
public requestToRequest: ITypeMap = {};
public platform!: string;
public alexa: any;
public google: any;

constructor(event: any, context: any) {
this.rawEvent = _.cloneDeep(event);
Expand Down
19 changes: 13 additions & 6 deletions src/platforms/alexa/AlexaEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ import { Lists } from "./apis/Lists";

export class AlexaEvent extends IVoxaEvent {
public intent!: IVoxaIntent;
public alexa: {
customerContact: CustomerContact,
deviceAddress: DeviceAddress,
deviceSettings: DeviceSettings,
isp: InSkillPurchase,
lists: Lists,
};

public requestToIntent: any = {
"AlexaSkillEvent.SkillDisabled": "AlexaSkillEvent.SkillDisabled",
Expand All @@ -38,7 +45,7 @@ export class AlexaEvent extends IVoxaEvent {
"PlaybackController.PreviousCommandIssued": "PlaybackController.PreviousCommandIssued",
};

constructor(event: RequestEnvelope , context?: any) {
constructor(event: RequestEnvelope, context?: any) {
super(event, context);
this.session = (_.cloneDeep(event.session) || {}) as IVoxaSession;
this.session.outputAttributes = {};
Expand All @@ -59,11 +66,11 @@ export class AlexaEvent extends IVoxaEvent {
this.platform = "alexa";

this.alexa = {
customerContact: new CustomerContact(event),
deviceAddress: new DeviceAddress(event),
deviceSettings: new DeviceSettings(event),
isp: new InSkillPurchase(event),
lists: new Lists(event),
customerContact: new CustomerContact(this.rawEvent),
deviceAddress: new DeviceAddress(this.rawEvent),
deviceSettings: new DeviceSettings(this.rawEvent),
isp: new InSkillPurchase(this.rawEvent),
lists: new Lists(this.rawEvent),
};
}

Expand Down
12 changes: 6 additions & 6 deletions src/platforms/alexa/apis/ApiBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ const alexalog: debug.IDebugger = debug("voxa:alexa");
export class ApiBase {
public errorCodeSafeToIgnore: number = 0; // the code error to ignore on checkError function
public tag: string = ""; // the class reference for error logging
public voxaEvent: any; // the event as sent by the service
public rawEvent: RequestEnvelope; // the event as sent by the service

constructor(event: RequestEnvelope) {
this.voxaEvent = _.cloneDeep(event);
this.rawEvent = _.cloneDeep(event);
}

protected getResult(path = "", method = "GET", body = {}): any {
protected getResult(path = "", method = "GET", body = {}) {
const options = {
body,
headers: {
Expand All @@ -25,7 +25,7 @@ export class ApiBase {
uri: `${this.getEndpoint()}/${path}`,
};

return rp(options);
return Promise.resolve(rp(options));
}

protected checkError(err: any) {
Expand All @@ -40,10 +40,10 @@ export class ApiBase {
}

protected getToken() {
return _.get(this.voxaEvent, "context.System.apiAccessToken");
return _.get(this.rawEvent, "context.System.apiAccessToken");
}

protected getEndpoint() {
return _.get(this.voxaEvent, "context.System.apiEndpoint");
return _.get(this.rawEvent, "context.System.apiEndpoint");
}
}
8 changes: 4 additions & 4 deletions src/platforms/alexa/apis/CustomerContact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,30 @@ export class CustomerContact extends ApiBase {
/*
* Gets user's email address
*/
public getEmail() {
public getEmail(): Promise<string> {
return this.getResult("v2/accounts/~current/settings/Profile.email");
}

/*
* Gets user's given name
*/
public getGivenName() {
public getGivenName(): Promise<string> {
return this.getResult("v2/accounts/~current/settings/Profile.givenName")
.catch((err: any) => this.checkError(err));
}

/*
* Gets user's name
*/
public getName() {
public getName(): Promise<string> {
return this.getResult("v2/accounts/~current/settings/Profile.name")
.catch((err: any) => this.checkError(err));
}

/*
* Gets user's phone number
*/
public getPhoneNumber() {
public getPhoneNumber(): Promise<any> {
return this.getResult("v2/accounts/~current/settings/Profile.mobileNumber");
}

Expand Down
6 changes: 4 additions & 2 deletions src/platforms/alexa/apis/DeviceAddress.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { services } from "ask-sdk-model";

import { DeviceBase } from "./DeviceBase";

export class DeviceAddress extends DeviceBase {
/*
* Gets the full address associated with the device specified by deviceId.
* https://developer.amazon.com/docs/custom-skills/device-address-api.html#getAddress
*/
public getAddress() {
public getAddress(): Promise<services.deviceAddress.Address> {
return this.getResult(`v1/devices/${this.deviceId}/settings/address`);
}

Expand All @@ -14,7 +16,7 @@ export class DeviceAddress extends DeviceBase {
* specified by deviceId. The endpoint is case-sensitive.
* https://developer.amazon.com/docs/custom-skills/device-address-api.html#getCountryAndPostalCode
*/
public getCountryRegionPostalCode() {
public getCountryRegionPostalCode(): Promise<services.deviceAddress.ShortAddress> {
return this.getResult(`v1/devices/${this.deviceId}/settings/address/countryAndPostalCode`);
}
}
6 changes: 3 additions & 3 deletions src/platforms/alexa/apis/DeviceSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class DeviceSettings extends DeviceBase {
* Gets distance unit associated to device settings
* https://developer.amazon.com/docs/smapi/alexa-settings-api-reference.html#get-the-distance-measurement-unit
*/
public getDistanceUnits() {
public getDistanceUnits(): Promise<string> {
return this.getResult(`v2/devices/${this.deviceId}/settings/System.distanceUnits`)
.catch((err: any) => this.checkError(err));
}
Expand All @@ -23,7 +23,7 @@ export class DeviceSettings extends DeviceBase {
* Gets temperature unit associated to device settings
* https://developer.amazon.com/docs/smapi/alexa-settings-api-reference.html#get-the-temperature-measurement-unit
*/
public getTemperatureUnits() {
public getTemperatureUnits(): Promise<string> {
return this.getResult(`v2/devices/${this.deviceId}/settings/System.temperatureUnits`)
.catch((err: any) => this.checkError(err));
}
Expand All @@ -32,7 +32,7 @@ export class DeviceSettings extends DeviceBase {
* Gets the timezone specified in device settings
* https://developer.amazon.com/docs/smapi/alexa-settings-api-reference.html#get-the-timezone
*/
public getTimezone() {
public getTimezone(): Promise<string> {
return this.getResult(`v2/devices/${this.deviceId}/settings/System.timeZone`)
.catch((err: any) => this.checkError(err));
}
Expand Down
41 changes: 22 additions & 19 deletions src/platforms/alexa/apis/InSkillPurchase.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { RequestEnvelope } from "ask-sdk-model";
import { RequestEnvelope, services } from "ask-sdk-model";
import * as _ from "lodash";
import * as rp from "request-promise";

import { ConnectionsSendRequest } from "../directives";

export class InSkillPurchase {
public static buy(productId: string, token: string) {
public static buy(productId: string, token: string): ConnectionsSendRequest {
const payload: any = {
InSkillProduct: {
productId,
Expand All @@ -15,7 +15,7 @@ export class InSkillPurchase {
return new ConnectionsSendRequest("Buy", payload, token);
}

public static cancel(productId: string, token: string) {
public static cancel(productId: string, token: string): ConnectionsSendRequest {
const payload: any = {
InSkillProduct: {
productId,
Expand All @@ -25,7 +25,7 @@ export class InSkillPurchase {
return new ConnectionsSendRequest("Cancel", payload, token);
}

public static upsell(productId: string, upsellMessage: string, token: string) {
public static upsell(productId: string, upsellMessage: string, token: string): ConnectionsSendRequest {
const payload: any = {
InSkillProduct: {
productId,
Expand All @@ -36,53 +36,56 @@ export class InSkillPurchase {
return new ConnectionsSendRequest("Upsell", payload, token);
}

public voxaEvent: any; // the event as sent by the service
public rawEvent: RequestEnvelope; // the event as sent by the service

constructor(event: RequestEnvelope) {
this.voxaEvent = _.cloneDeep(event);
this.rawEvent = _.cloneDeep(event);
}

public isAllowed() {
const ALLOWED_ISP_ENDPOINTS = {
"en-US": "https://api.amazonalexa.com",
};

const locale: string = this.voxaEvent.request.locale;
const endpoint: string = _.get(this.voxaEvent, "context.System.apiEndpoint");
const locale: string = this.rawEvent.request.locale;
const endpoint: string = _.get(this.rawEvent, "context.System.apiEndpoint");

return _.get(ALLOWED_ISP_ENDPOINTS, locale) === endpoint;
}

public async buyByReferenceName(referenceName: string, token: string) {
const product: any = await this.getProductByReferenceName(referenceName);
public async buyByReferenceName(referenceName: string, token: string): Promise<ConnectionsSendRequest> {
const product: services.monetization.InSkillProduct | object =
await this.getProductByReferenceName(referenceName);

return InSkillPurchase.buy(_.get(product, "productId"), token);
}

public async cancelByReferenceName(referenceName: string, token: string) {
const product: any = await this.getProductByReferenceName(referenceName);
public async cancelByReferenceName(referenceName: string, token: string): Promise<ConnectionsSendRequest> {
const product: services.monetization.InSkillProduct | object =
await this.getProductByReferenceName(referenceName);

return InSkillPurchase.cancel(_.get(product, "productId"), token);
}

public async upsellByReferenceName(referenceName: string, upsellMessage: string, token: string) {
const product: any = await this.getProductByReferenceName(referenceName);
public async upsellByReferenceName(referenceName: string, upsellMessage: string, token: string): Promise<ConnectionsSendRequest> {
const product: services.monetization.InSkillProduct | object =
await this.getProductByReferenceName(referenceName);

return InSkillPurchase.upsell(_.get(product, "productId"), upsellMessage, token);
}

public async getProductByReferenceName(referenceName: string) {
const result: any = await this.getProductList();
public async getProductByReferenceName(referenceName: string): Promise<services.monetization.InSkillProduct | object> {
const result: services.monetization.InSkillProductsResponse = await this.getProductList();

return _.find(result.inSkillProducts, { referenceName });
return _.find(result.inSkillProducts, { referenceName }) || {};
}

public getProductList() {
const { apiEndpoint, apiAccessToken } = this.voxaEvent.context.System;
const { apiEndpoint, apiAccessToken } = this.rawEvent.context.System;

const options: any = {
headers: {
"Accept-Language": this.voxaEvent.request.locale,
"Accept-Language": this.rawEvent.request.locale,
"Authorization": `Bearer ${apiAccessToken}`,
"Content-Type": "application/json",
},
Expand Down
Loading

0 comments on commit 369644e

Please sign in to comment.