Skip to content

Commit

Permalink
Merge pull request #2 from jeroenouw/speech
Browse files Browse the repository at this point in the history
Speech
  • Loading branch information
jeroenouw authored Nov 5, 2017
2 parents 64f9c5b + f371db0 commit 9fb6b4c
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 40 deletions.
18 changes: 5 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,11 @@ A small AI application containing [Angular 5](https://angular.io), [Material](ht
* Dialogflow AI
* Chatbot

## Example sentences
* Can you get smarter?
* You're boring
* Who is your boss?
* You are funny
* Are we friends?
* I'll be back
* You're wrong
* Nice to see you!
* What's up?
* I don't want to talk
* Today is my birthday
* I need an advice
## Sentences
[A couple of example sentences to get you start talking](https://github.com/jeroenouw/AngularAI/blob/master/docs/SENTENCES.md)

## Developing
[Quick starting and development](https://github.com/jeroenouw/AngularAI/blob/master/docs/DEVELOPING.md)

## Contributing
Want to file a bug, contribute some code, or improve documentation? Feel free to place an [issue](https://github.com/jeroenouw/AngularAI/issues).
Expand Down
35 changes: 35 additions & 0 deletions docs/DEVELOPING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Quick start
First clone this repo: `git clone https://github.com/jeroenouw/AngularAI.git`.
Change directory to this project
Run `npm install` to install all the dependencies.
Run `npm start` to run this project. This will run with the AoT Compiler.
Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.

## Development
For own projects please use different token `src/environment/environment.prod.ts` and `src/environment/environment.ts`:
``` dialogflow: { ```
``` [CHOOSE_A_NAME]': '[YOUR_TOKEN]' ```
``` }```

Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.

To build the development environment, run `npm run dist`.

## Production
To build the default production environment, run `npm run prod`. This will run with the AoT Compiler.
To build the production environment with reduced file size, run `npm run prod:opt` (Takes extra time to build with build optimizer).

## Speech Options
Available speech recognition options in `src/app/service/ai.service.ts`

Choose if the API needs to look for further words:
`this.speechRecognition.continuous = false;`

Show interim results or just final results:
`this.speechRecognition.interimResults = false;`

Select your speech language:
`this.speechRecognition.lang = 'en-us';`

Choose the quantity of alternative available matches:
`this.speechRecognition.maxAlternatives = 0;`
13 changes: 13 additions & 0 deletions docs/SENTENCES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Example sentences
* Can you get smarter?
* You're boring
* Who is your boss?
* You are funny
* Are we friends?
* I'll be back
* You're wrong
* Nice to see you!
* What's up?
* I don't want to talk
* Today is my birthday
* I need an advice
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"name": "ngx-ai",
"version": "1.0.1",
"version": "1.0.2",
"author": "Jeroen Ouwehand",
"description": "Angular 5 AI",
"keywords": [
"angular",
"dialogflow",
"web speech api",
"google",
"material",
"chatbot",
Expand Down
15 changes: 11 additions & 4 deletions src/app/components/ai/ai.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ <h1 class="mat-display-1">Angular 5 AI</h1>
</div>
</mat-card-content>

<mat-input-container>
<input matInput [(ngModel)]="formInput" min="2" placeholder="Your Message..." (keyup.enter)="sendMessageToBot()" type="text">
</mat-input-container>
<div class="message-container">
<mat-card-actions class="voice-button">
<button mat-icon-button (click)="startTalkingToBot()">
<mat-icon>keyboard_voice</mat-icon>
</button>
</mat-card-actions>
<mat-input-container>
<input matInput [(ngModel)]="formInput" min="2" placeholder="Your Message..." (keyup.enter)="sendMessageToBot()" type="text">
</mat-input-container>
</div>

<mat-card-actions class="button center">
<button mat-raised-button (click)="sendMessageToBot()">Send</button>
</mat-card-actions>

</mat-card>
18 changes: 18 additions & 0 deletions src/app/components/ai/ai.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
word-wrap: break-word;
}

.message-container {
display: flex;
flex-direction: row;
justify-content: center;
}

.message.to {
background-color: $darkblue;
color: $white;
Expand All @@ -32,7 +38,19 @@
display: inline;
}

.mat-form-field {
width: 100%;
}

.mat-raised-button {
background-color: $darkblue;
color: $white;
}

.voice-button {
border-radius: 50%;
width: 40px;
height: 40px;
line-height: 24px;
padding: 8px 20px 8px 8px;
}
59 changes: 42 additions & 17 deletions src/app/components/ai/ai.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, OnDestroy } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/scan';
Expand All @@ -11,21 +11,46 @@ import { Message } from '../../model/message';
templateUrl: './ai.component.html',
styleUrls: ['./ai.component.scss']
})
export class AiComponent implements OnInit {
allMessages: Observable<Message[]>;
formInput: string;

constructor(public ai: AiService) {
}

ngOnInit() {
this.allMessages = this.ai.conversation.asObservable()
.scan((acc, val) => acc.concat(val) );
}

sendMessageToBot() {
this.ai.converse(this.formInput);
this.formInput = '';
}
export class AiComponent implements OnInit, OnDestroy {
allMessages: Observable<Message[]>;
formInput: string;

constructor(public ai: AiService) {
this.formInput = '';
}

ngOnInit() {
this.allMessages = this.ai.conversation.asObservable()
.scan((acc, val) => acc.concat(val) );
}

ngOnDestroy() {
this.ai.destroyVoiceConversation();
}

sendMessageToBot() {
this.ai.textConversation(this.formInput);
this.formInput = '';
}

startTalkingToBot() {
this.ai.voiceConversation()
.subscribe(
(value) => {
this.formInput = value;
console.log(value);
},
(err) => {
console.log(err);
if (err.error) {
// console.log("Talking error");
this.startTalkingToBot();
}
},
() => {
// console.log("Talking complete");
this.startTalkingToBot();
});
}
}

4 changes: 4 additions & 0 deletions src/app/interface/Iwindow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface IWindow extends Window {
webkitSpeechRecognition: any;
SpeechRecognition: any;
}
56 changes: 53 additions & 3 deletions src/app/service/ai.service.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import { Injectable } from '@angular/core';
import { Injectable, NgZone } from '@angular/core';
import { environment } from '../../environments/environment';
import * as lodash from "lodash";

import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import { ApiAiClient } from 'api-ai-javascript';
import { Message } from '../model/message'
import { IWindow } from '../interface/iwindow'

@Injectable()
export class AiService {
readonly token = environment.dialogflow.angularAIBot;
readonly client = new ApiAiClient({ accessToken: this.token });

speechRecognition: any;
conversation = new BehaviorSubject<Message[]>([]);

constructor() {
constructor(private zone: NgZone) {
}

converse(msg: string) {
textConversation(msg: string) {
const userMessage = new Message(msg, 'user');
this.update(userMessage);
return this.client.textRequest(msg)
Expand All @@ -31,4 +34,51 @@ export class AiService {
update(msg: Message) {
this.conversation.next([msg]);
}

voiceConversation(): Observable<string> {
return Observable.create(observer => {
const { webkitSpeechRecognition }: IWindow = <IWindow>window;
this.speechRecognition = new webkitSpeechRecognition();
this.speechRecognition.continuous = false;
this.speechRecognition.interimResults = false;
this.speechRecognition.lang = 'en-us';
this.speechRecognition.maxAlternatives = 0;

this.speechRecognition.onresult = speech => {
let sentence: string = "";
if (speech.results) {
var result = speech.results[speech.resultIndex];
var transcript = result[0].transcript;
if (result.isFinal) {
if (result[0].confidence < 0.1) {
console.log("Unrecognized result - Please try again");
}
else {
sentence = lodash.trim(transcript);
console.log("Did you said? -> " + sentence + " , If not then say something else...");
}
}
}
this.zone.run(() => {
observer.next(sentence);
});
};

this.speechRecognition.onerror = error => {
observer.error(error);
};

this.speechRecognition.onend = () => {
observer.complete();
};

this.speechRecognition.start();
// console.log("I'm listening...");
});
}

destroyVoiceConversation() {
if (this.speechRecognition)
this.speechRecognition.stop();
}
}
1 change: 0 additions & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">

<link href="styles.scss" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
</head>
Expand Down

0 comments on commit 9fb6b4c

Please sign in to comment.