[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>