Skip to content

Commit

Permalink
feat(interactions): Interactions category (#1042)
Browse files Browse the repository at this point in the history
  • Loading branch information
elorzafe committed Jun 16, 2018
1 parent 848b5cd commit befb336
Show file tree
Hide file tree
Showing 13 changed files with 748 additions and 2 deletions.
343 changes: 343 additions & 0 deletions packages/aws-amplify/__tests__/Interactions/Interactions-unit-test.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/aws-amplify/src/Common/Amplify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default class Amplify {
static I18n = null;
static Cache = null;
static PubSub = null;
static Interactions = null;

static Logger = null;
static ServiceWorker = null;
Expand Down
3 changes: 2 additions & 1 deletion packages/aws-amplify/src/Common/Facet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ import * as Pinpoint from 'aws-sdk/clients/pinpoint';
import * as Kinesis from 'aws-sdk/clients/kinesis';
import * as MobileAnalytics from 'aws-sdk/clients/mobileanalytics';
import * as CognitoHostedUI from 'amazon-cognito-auth-js';
import * as LexRuntime from 'aws-sdk/clients/lexruntime';

export {AWS, S3, Cognito, Pinpoint, MobileAnalytics, Kinesis, CognitoHostedUI };
export {AWS, S3, Cognito, Pinpoint, MobileAnalytics, Kinesis, CognitoHostedUI, LexRuntime };
113 changes: 113 additions & 0 deletions packages/aws-amplify/src/Interactions/Interactions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
import { InteractionsOptions, InteractionsProviders, InteractionsResponse, InteractionsProvider } from './types';
import { ConsoleLogger as Logger } from '../Common/Logger';
import { AWSLexProvider } from './Providers';
const logger = new Logger('Interactions');

export default class Interactions {

private _options: InteractionsOptions;

private _pluggables: InteractionsProviders;

/**
* Initialize PubSub with AWS configurations
*
* @param {InteractionsOptions} options - Configuration object for Interactions
*/
constructor(options: InteractionsOptions) {
this._options = options;
logger.debug('Interactions Options', this._options);
this._pluggables = {};
}

/**
*
* @param {InteractionsOptions} options - Configuration object for Interactions
* @return {Object} - The current configuration
*/
configure(options: InteractionsOptions) {
const opt = options ? options.Interactions || options : {};
logger.debug('configure Interactions', { opt });
this._options = { bots: {}, ...opt, ...opt.Interactions };

const aws_bots_config = this._options.aws_bots_config;
const bots_config = this._options.bots;

if (!Object.keys(bots_config).length && aws_bots_config) {
// Convert aws_bots_config to bots object
if (Array.isArray(aws_bots_config)) {
aws_bots_config.forEach(bot => {
this._options.bots[bot.name] = bot;
});
}
}

// Check if AWSLex provider is already on pluggables
if (!this._pluggables.AWSLexProvider && bots_config &&
Object.keys(bots_config).
map(key => bots_config[key]).
find(bot => !bot.providerName || bot.providerName === 'AWSLexProvider')) {
this._pluggables.AWSLexProvider = new AWSLexProvider();
}

Object.keys(this._pluggables).map(key => {
this._pluggables[key].configure(this._options.bots);
});

return this._options;
}

public addPluggable(pluggable: InteractionsProvider) {
if (pluggable && pluggable.getCategory() === 'Interactions') {
if (!this._pluggables[pluggable.getProviderName()]) {
pluggable.configure(this._options.bots);
this._pluggables[pluggable.getProviderName()] = pluggable;
return;
} else {
throw new Error('Bot ' + pluggable.getProviderName() + ' already plugged');
}
}
throw new Error('Bot ' + pluggable.getProviderName() + ' has wrong category');
}

public async send(botname: string, message: string | Object) {
if (!this._options.bots[botname]) {
throw new Error('Bot ' + botname + ' does not exist');
}

const botProvider = this._options.bots[botname].providerName || 'AWSLexProvider';

if (!this._pluggables[botProvider]) {
throw new Error('Bot ' + botProvider +
' does not have valid pluggin did you try addPluggable first?');
}
return await this._pluggables[botProvider].sendMessage(botname, message);

}

public async onComplete(botname: string, callback: (err, confirmation) => void) {
if (!this._options.bots[botname]) {
throw new Error('Bot ' + botname + ' does not exist');
}
const botProvider = this._options.bots[botname].providerName || 'AWSLexProvider';

if (!this._pluggables[botProvider]) {
throw new Error('Bot ' + botProvider +
' does not have valid pluggin did you try addPluggable first?');
}
return this._pluggables[botProvider].onComplete(botname, callback);

}
}
101 changes: 101 additions & 0 deletions packages/aws-amplify/src/Interactions/Providers/AWSLexProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/

import { AbstractInteractionsProvider } from './InteractionsProvider';
import { InteractionsOptions, InteractionsResponse } from '../types';
import { ConsoleLogger as Logger, LexRuntime, AWS } from '../../Common';
import { registerHelper } from 'handlebars';
import Auth from '../../Auth';

const logger = new Logger('AWSLexProvider');

export class AWSLexProvider extends AbstractInteractionsProvider {

private aws_lex: LexRuntime;
private _botsCompleteCallback: object;


constructor(options: InteractionsOptions = {}) {
super(options);
this.aws_lex = new LexRuntime({ region: this._config.region });
this._botsCompleteCallback = {};
}

getProviderName() { return 'AWSLexProvider'; }

sendMessage(botname: string, message: string | Object): Promise<object> {
return new Promise(async (res, rej) => {
if (!this._config[botname]) {
return rej('Bot ' + botname + ' does not exist');
}
const credentials = await Auth.currentCredentials();
if (!credentials) { return rej('No credentials'); }
AWS.config.update({
credentials
});

this.aws_lex = new LexRuntime({ region: this._config[botname].region, credentials });
// TODO: Implement for content
if (typeof message === 'string') {
const params = {
'botAlias': this._config[botname].alias,
'botName': botname,
'inputText': message,
'userId': credentials.identityId
};
logger.debug('postText to lex', message);

this.aws_lex.postText(params, (err, data) => {
if (err) {
throw err;
} else {
// Check if state is fulfilled to resolve onFullfilment promise
if (data.dialogState === 'ReadyForFulfillment') {
logger.debug('ReadyForFulfillment');
if (typeof this._botsCompleteCallback[botname] === 'function') {
this._botsCompleteCallback[botname](null, { slots: data.slots });
}

if (this._config && typeof this._config[botname].onComplete === 'function') {
this._config[botname].onComplete(null, { slots: data.slots });
}
}

if (data.dialogState === 'Failed') {

if (typeof this._botsCompleteCallback[botname] === 'function') {
this._botsCompleteCallback[botname]({ err: 'Bot conversation failed' });
}

if (this._config && typeof this._config[botname].onComplete === 'function') {
this._config[botname].onComplete('Bot conversation failed');
}
}

res(data);
}
});
} else {
rej("Not implemented yet");
}
});
}

onComplete(botname: string, callback) {
if (!this._config[botname]) {
throw new ErrorEvent('Bot ' + botname + ' does not exist');
}
this._botsCompleteCallback[botname] = callback;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/

import { InteractionsProvider, InteractionsOptions, InteractionsResponse } from '../types';

import { ConsoleLogger as Logger } from '../../Common';

const logger = new Logger('AbstractInteractionsProvider');

export abstract class AbstractInteractionsProvider implements InteractionsProvider {

protected _config: InteractionsOptions;

constructor(options: InteractionsOptions = {}) {
this._config = options;
}

configure(config: InteractionsOptions = {}): InteractionsOptions {
this._config = { ...this._config, ...config };

logger.debug(`configure ${this.getProviderName()}`, this._config);

return this.options;
}

getCategory() { return 'Interactions'; }

abstract getProviderName(): string;

protected get options(): InteractionsOptions { return { ...this._config }; }

public abstract sendMessage(botname: string, message: string | Object): Promise<object>;

public abstract onComplete(botname: string, callback: (err: any, confirmation: InteractionsResponse) => void );
}
14 changes: 14 additions & 0 deletions packages/aws-amplify/src/Interactions/Providers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
export * from './AWSLexProvider';
export * from './InteractionsProvider';
31 changes: 31 additions & 0 deletions packages/aws-amplify/src/Interactions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
import InteractionsClass from './Interactions';

import { ConsoleLogger as Logger, Amplify } from '../Common';

const logger = new Logger('Interactions');

let _instance: InteractionsClass = null;

if (!_instance) {
logger.debug('Create Interactions Instance');
_instance = new InteractionsClass(null);
}

const Interactions = _instance;
Amplify.register(Interactions);

export default Interactions;

export * from './Providers/AWSLexProvider';
15 changes: 15 additions & 0 deletions packages/aws-amplify/src/Interactions/types/Interactions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
export interface InteractionsOptions {
[key: string]: any,
}
34 changes: 34 additions & 0 deletions packages/aws-amplify/src/Interactions/types/Provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
import { InteractionsOptions } from './Interactions';
import { InteractionsResponse } from './Response';

export interface InteractionsProvider {
// configure your provider
configure(config: object): object;

// return 'Interactions'
getCategory(): string;

// return the name of your provider
getProviderName(): string;

sendMessage(botname: string, message: string | Object): Promise<object>;

onComplete(botname: string, callback: (err: any, confirmation: InteractionsResponse) => void );

}

export interface InteractionsProviders {
[key: string]: InteractionsProvider,
}
15 changes: 15 additions & 0 deletions packages/aws-amplify/src/Interactions/types/Response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright 2017-2018 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file 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.
*/
export interface InteractionsResponse {
[key: string]: any,
}

0 comments on commit befb336

Please sign in to comment.