Skip to Content
Technical Articles

SAP Conversational AIへWebhookでReplyを設定

SAP Cloud SDK for JavaScriptを使ってアプリを作成してSAP Cloud Foundry Application Runtimeへデプロイする方法のメモです。

Node.jsとSAP Cloud SDK for JavaScriptについては、別記事「SAP Cloud SDK for JavaScriptを使ってSAP CP CFへアプリをデプロイ」を参照ください。

Node.jsプログラムはGitHubに置いています。

開発環境

以下の環境で実行しています。

  • OS: Ubuntu18.04.01 LTS
  • Node.js: 12.14.1
  • npm: 6.13.4
  • CF cli: 6.49.0+d0dfa93bb.2020-01-07
  • SAP Cloud SDK for JavaScript:1.16

 

手順

1. Node.js開発

1.1. プロジェクト作成

以下のコマンドでProjectフォルダが作成される。

途中project nameを入れ、anonymous usage analyticsはNo

# Node.jsのプロジェクトを管理したいディレクトリから
$ sap-cloud-sdk init node-sdk-chat
This folder does not contain a `package.json`.
Should a new `nest.js` project be initialized in this folder? (y|n): y
Building application scaffold... done
Enter project name (for use in manifest.yml) [node-sdk-chat]: node-sdk-chat
Do you want to provide anonymous usage analytics to help us improve the SDK? (y|n): n
  ✔ Creating files
  ✔ Modifying test config
  ✔ Adding dependencies to package.json
  ✔ Installing dependencies
  ✔ Modifying `.gitignore`

+--------------------------------------------------------------+
 ✅ Init finished successfully. 
  
 🚀 Next steps: 
 - Run the application locally (`npm run start:dev`) 
 - Deploy your application (`npm run deploy`) 
  
 🔨 Consider setting up Jenkins to continuously build your app. 
 Use `sap-cloud-sdk add-cx-server` to create the setup script. 
+--------------------------------------------------------------+

1.2. プロジェクト作成確認

プロジェクトディレクトリに移動し、nodeを起動します。

# プロジェクトディレクトリに移動しstart:devを実行
$ cd node-sdk-chat && npm run start:dev

1:23:58 AM - Starting compilation in watch mode...

11:24:02 AM - Found 0 errors. Watching for file changes.
[Nest] 64793   - 02/13/2020, 11:24:02 AM   [NestFactory] Starting Nest application...
[Nest] 64793   - 02/13/2020, 11:24:02 AM   [InstanceLoader] AppModule dependencies initialized +15ms
[Nest] 64793   - 02/13/2020, 11:24:02 AM   [RoutesResolver] AppController {/}: +4ms
[Nest] 64793   - 02/13/2020, 11:24:02 AM   [RouterExplorer] Mapped {/, GET} route +2ms
[Nest] 64793   - 02/13/2020, 11:24:02 AM   [NestApplication] Nest application successfully started +2ms

CURLでリクエスト送り、正常にレスポンスを受け取れることを確認

$ curl localhost:3000
Hello World!

1.3. コントローラ作成

nest cliでchatのコントローラ生成。

$ nest g controller chat
CREATE /src/chat/chat.controller.spec.ts (479 bytes)
CREATE /src/chat/chat.controller.ts (97 bytes)
UPDATE /src/app.module.ts (322 bytes)

chat.cotroller.tsを変更します(拙いコードで失礼します)。出力フォーマットは公式ヘルプを参考にしています。

import { Controller, Get, Req, Post, Param } from '@nestjs/common';
import { Request } from 'express';

@Controller('chat')
export class ChatController {
  @Get()
  Reply(@Req() request: Request) {
    //console.log(request)
    console.log('Receive Get Request!!!!')
    console.log('-----body-----')
    console.log(request.body)

    const test = {
      "replies": [
        {
          "type": "quickReplies",
          "content": {
            "title": "Select Message Type",
            "buttons": [
              {
                "title": "Button",
                "value": "Show Buttonnest"
              },
              {
                "title": "Picture",
                "value": "Show Picture"
              }
            ]
          }
        }]
      }
    ;

    return test
    //return this.chatService.Reply();
  };
  @Post(':type')
  ReplyPost(@Req() request: Request, @Param('type') type: string) {
    console.log(type)
    console.log('Receive Post Request!!!!')
    console.log('-----body-----')
    console.log(request.body)
    var reply = { "replies": [] }
    switch (type) {
      case 'pict':
        reply.replies.push(
          {
            "type": "picture",
            "content": "https://www.sap.com/dam/application/shared/logos/sap-logo-svg.svg.adapt.svg/1493030643828.svg",
          }
        );
        break;
      case 'button':
        reply.replies.push(
            {
              "type": "buttons",
              "content": {
                "title": "BUTTON_TITLE",
                "buttons": [
                  {
                    "title": "BUTTON_TITLE",
                    "type": "BUTTON_TYPE",
                    "value": "BUTTON_VALUE"
                  }
                ]
              }
            });
        break;
    }
    return reply
  }
}

 

curlで確認します。

$ curl localhost:3000/chat
{"replies":[{"type":"quickReplies","content":{"title":"Select Message Type","buttons":[{"title":"Button","value":"Show Buttonnest"},{"title":"Picture","value":"Show Picture"}]}}]}

$ curl -X POST -H "Content-Type: application/json" -d '{"key": "value"}' localhost:3000/chat/pict
{"replies":[{"type":"picture","content":"https://www.sap.com/dam/application/shared/logos/sap-logo-svg.svg.adapt.svg/1493030643828.svg"}]}

1.4. CFへデプロイ

CFにデプロイする前にいくつか調整ごとをします。

1.4.1 package.json変更

まずはpackage.jsonを変更。”scripts”以下ににあるci-packageの中身を変更。CFへアップロードする元の”deployment”フォルダにnode_modulesがコピーされてしまうので削除します(node_modulesが重いくせに何もしていない気がする)。

"ci-package": "sap-cloud-sdk package && rm -r -f deployment/node_modules",

1.4.2. manifest.yml変更

manifest.ymlを少し変更します。random_routeを削除し、routeを固定します(<route>部分を変更)。試行錯誤していく中で、routeをcfのquotaに対して使い切ってしまったので、固定にしました。

applications:
  - name: node-sdk-chat
    path: deployment/
    buildpacks:
      - nodejs_buildpack
    memory: 256M
    command: npm run start:prod
    routes: 
    - route: <route>.eu10.hana.ondemand.com

1.4.3.CFにデプロイ

あとはコマンド”npm run depoy”で、ビルドとパッケージ、cf pushを一気にやってしまいます。具体的にdeployが何をしているかは、package.jsonに定義されています。

$ npm run deploy

2. SAP Conversational AI

Botの作成部分は省略します。英語で登録しています。特別な設定はありません。

2.1. インテント登録

“start-api-test”というインテントを登録。こんな感じのexpression。

2.2. エンティティ

エンティティとして登録した”type”の一覧。

2.3. スキル”test”

スキル”test”を登録。

2.3.1. Trigger

Triggerは先程登録したインテント。

2.3.2. Requirement

Requirementにtypeを入れます。

typeがなかった場合にWebhookを使います(今回は権限なし)。

2.3.3. Action

今度はActionです。

type.valueが”picture”の場合のWebhookです。先程と違ってhttpメソッドはPOSTにして、URLの最後のパスをpictにしています。

ほぼ同じでpictureがbuttonに変わっただけです。

 

最後に条件なしでメモリ情報を出し、メモリをすべてクリアします。これでCAI側も完成です。

実装イメージ

チャットのテストをします。

“run api”とすると、メッセージタイプを選択させるquick repliesが動きます。

“Button”ボタンを押すことでButtonのサンプルを出します。Buttonの選択を待たずして、次のメモリ情報も表示されます。

 

メモリをクリアしていきなり”show picture”とすると、メッセージタイプ選択をせずに画像表示まで一気に行きます。

Be the first to leave a comment
You must be Logged on to comment or reply to a post.