[Angular] Make a chatbot with DialogFlow
Register a account on https://console.dialogflow.com/api-client/
"Creat a intent" -- you can custom your message here.
"Small Talks" -- the default message from the DialogFlow.
Install:
yarn add api-ai-javascript
Put your API token to the app.
Create a servie:
import {Injectable} from '@angular/core'; import {environment} from '../../../environments/environment'; import {ApiAiClient} from 'api-ai-javascript'; import {Message} from '../models/bot-message'; import {BehaviorSubject} from 'rxjs/BehaviorSubject'; @Injectable() export class ChatbotService { readonly token = environment.dialogFlow.bot; readonly client = new ApiAiClient({accessToken: this.token}); conversation = new BehaviorSubject<Message[]>([]); constructor() { } // Adds message to the source update(msg: Message) { this.conversation.next([msg]); } // Send and receives message via DialogFlow converse(msg: string) { const userMessage = new Message(msg, 'user'); this.update(userMessage); this.client.textRequest(msg) .then((res) => { const speech = res.result.fulfillment.speech; const botMessage = new Message(speech, 'bot'); this.update(botMessage); }).catch((err) => { console.error(err); }); } }
Component:
import {Component, OnInit} from '@angular/core'; import {ChatbotService} from '../../services/chatbot.service'; import {Observable} from 'rxjs/Observable'; import {Message} from '../../models/bot-message'; import 'rxjs/add/operator/scan'; @Component({ selector: 'chat-dialog', templateUrl: './chat-dialog.component.html', styleUrls: ['./chat-dialog.component.scss'] }) export class ChatDialogComponent implements OnInit { messages$: Observable<Message[]>; formValue: string; constructor(private chatService: ChatbotService) { } ngOnInit() { this.messages$ = this.chatService.conversation .asObservable() .scan((acc, curr) => acc.concat(curr)); } sendMessage() { if (!this.formValue) { return; } this.chatService.converse(this.formValue); this.formValue = ''; } }
Template:
<mat-card> <mat-card-title class="title"> Umi </mat-card-title> <hr /> <mat-card-content class="content"> <div fxLayout="column"> <ng-container *ngFor="let message of messages$ | async"> <div class="message" [ngClass]="{'from': message.sentBy === 'bot', 'to': message.sentBy === 'user'}"> {{message.content}} </div> </ng-container> </div> </mat-card-content> <mat-card-actions> <div fxLayout="row" fxLayoutAlign="space-between"> <mat-form-field fxFlex="auto"> <textarea matInput type="textarea" placeholder="What you want to say?..." [(ngModel)]="formValue" (keyup.enter)="sendMessage()"></textarea> </mat-form-field> <div fxLayout="column" fxLayoutAlign="center center"> <button color="primary" class="send-btn" mat-mini-fab [disabled]="!formValue" (click)="sendMessage()"> <mat-icon> send </mat-icon> </button> </div> </div> </mat-card-actions> </mat-card>