LoginSignup
5
7

More than 3 years have passed since last update.

Bot Framework v4 (node.js) をイチから学ぶ (1) オウム返しができるまで

Last updated at Posted at 2020-08-05

今更ながら、Bot Framework v4 (node.js) を やりたいこと を実装できることを目標に、イチから学んでみることにしました。

執筆時点のバージョン:

  • Bot Framework (javascript): v4.9.3
  • node.js: v12.16.3
  • npm: v6.14.4

※ Bot Framework SDK (C#) はある程度触っている & node.js はそれほど詳しくないため、分かりにくいところや間違っているところあればご指摘ください。(プルリク的に模範解答を添えて修正依頼をくださると助かります)

Bot Framework v4 (node.js) をイチから学ぶ シリーズ

必要なコード

EchoBot
+- bot.js          // Chatbot としての挙動
+- index.js        // API としての基本動作
+- package.json    // 必要なライブラリーや依存関係など
+- .env       // 環境変数を設定

Bot Framework の Bot Builder Samples にある EchoBot から上記ファイルをダウンロードするなどして入手、編集するベースとすれば OK です。

手順

チャットボットの稼働に必要なライブラリーやファイルを確認する

node.js の実行ファイルとして index.js が設定されていますので、こちらで必要なライブラリーやファイルを確認しておきます。(※編集作業ナシ)

ライブラリーはBot Framework を使う上で必要となる botbuilder の他、restify, dotenv, path が必要です。
Azure Bot Service の公開に必要な ID などは .env で設定します。
チャットボットの挙動を記述する EchoBot (ファイル名は bot.js) を読み込んでいます。

index.js
const path = require('path');
const restify = require('restify');

// Import required bot services.
// See https://aka.ms/bot-services to learn more about the different parts of a bot.
const { BotFrameworkAdapter } = require('botbuilder');

// This bot's main dialog.
const { EchoBot } = require('./bot');

// Read environment variables from .env file
const dotenv = require('dotenv');
// Import required bot configuration.
const ENV_FILE = path.join(__dirname, '.env');
dotenv.config({ path: ENV_FILE });

// Create adapter.
// See https://aka.ms/about-bot-adapter to learn more about how bots work.
const adapter = new BotFrameworkAdapter({
    appId: process.env.MicrosoftAppId,
    appPassword: process.env.MicrosoftAppPassword
});

 :
(後略)

チャットボット本体は Web API で、ローカルで実行した場合は localhost:3978/api/messages で待ち受けます。
EchoBot から bot インスタンスを作成し、HTTP リクエストがあった場合に作動します。

index.js
(前略)
 :

// Create HTTP server
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
    console.log(`\n${ server.name } listening to ${ server.url }`);
    console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
    console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
});

 :
(中略)
 :

// Create the main dialog.
const bot = new EchoBot();

// Listen for incoming requests.
server.post('/api/messages', (req, res) => {
    adapter.processActivity(req, res, async (context) => {
        // Route to main dialog.
        await bot.run(context);
    });
});

 :
(後略)

チャットボットを起動する

コマンドラインから npm install で必要なライブラリーをインストールします。
その後、 node index.js、Package.json をサンプルからそのままで使っている場合は npm start で index.js が起動します。

01.jpg

Bot Framework Emulator から https://localhost:3978/api/messages にアクセスして挙動を確認します。

02.jpg

EchoBot をそのまま使っている場合は、以下のように初期メッセージと、ユーザー入力に対するオウム返しが返答されます。

03.jpg

ユーザーからメッセージが来たら返信する

ユーザーからのメッセージ (HTTPリクエスト) に対する動作は EchoBot (ファイル名は bot.js) に記述します。

  • Activity: ユーザーの接続やメッセージの受信&返信を含む、すべての動作(アクティビティ)
  • TurnContext: ボットの制御(とその情報)。ユーザーとの受信、返信の内容を履歴として保持しています

ユーザーの動作は Activity で取得することができ、メッセージを受信したときは ActivityHander.onMessage が参照されます。
ActivityHander で onMessage を検知したとき、TurnContext.sendActivity メソッドで返信することができます。

ここではユーザーからメッセージを受信したとき、「hello!」と返信する処理のみを記述するように、既存の bot.js を修正します。next() でユーザーからの受信を待ちます;

bot.js
const { ActivityHandler } = require('botbuilder');

class EchoBot extends ActivityHandler {
    constructor() {
        super();
        // メッセージを受信したとき
        this.onMessage(async (turnContext, next) => {
            // 返信して返答を待つ
            await turnContext.sendActivity('hello!');
            await next();
        });
    }
}

module.exports.EchoBot = EchoBot;

起動して Emulator から動作を確認します。

11.jpg

ユーザーからのメッセージ内容を取得する

TurnContext にユーザーとの受信、返信情報を保持しており、直前のユーザーからのメッセージは TurnContext.activity プロパティから取得できます。text(テキストメッセージ) または attatchment((あれば)添付ファイル) が取得できます。
取得したメッセージをそのままオウム返しするように記述します。

bot.js
const { ActivityHandler } = require('botbuilder');

class EchoBot extends ActivityHandler {
    constructor() {
        super();
        this.onMessage(async (turnContext, next) => {
            // ユーザーのメッセージ内容を取得して、おうむ返し(Echo)の返答を送信する
            const replyText = turnContext.activity.text + 'って言ったね!';
            await turnContext.sendActivity(replyText);
            await next();
        });
    }
}

module.exports.EchoBot = EchoBot;

12.jpg

Welcome メッセージを送信する

ActivityHander.onMembersAdded でユーザーが接続したことを検出できるので、その際にメッセージを送信する動作を追加します。(※接続したユーザークライアントによりできない場合アリ)

bot.js
const { ActivityHandler } = require('botbuilder');

class EchoBot extends ActivityHandler {
    constructor() {
        super();
        this.onMembersAdded(async (turnContext, next) =>{
            await turnContext.sendActivity('はじめまして!');
            await next();
        });
        this.onMessage(async (turnContext, next) => {
            const replyText = turnContext.activity.text + 'って言ったね!';
            await turnContext.sendActivity(replyText);
            await next();
        });
    }
}

module.exports.EchoBot = EchoBot;

13.jpg

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7