無料で手早く作る:Teams で動く FAQ bot 開発 [後編] (QnA Maker, Azure Bot Services, C#)

12 min read読了の目安(約11000字 3

前編の記事 では、QnA Maker でのナレッジベース作成まで完了しましたね。
この後半の記事ではクライアント (bot) のコードをガリガリ書いていきます。

  1. 事前準備
  2. Azure で bot ホスト先を用意
  3. QnA Maker でナレッジベースを作る ← ここまで完了
  4. bot クライアント開発 (Visual Studio で) ← ここから
  5. Teams と繋げる

3: bot クライアント開発

3-1: Visual Studio に Botframework テンプレート

Visual Studio 2019 の拡張機能から Bot Framework v4 SDK Templates for Visual Studio を入れます。詳しく手順を示します。

まず VS2019 を開いて、「Continue without code」をクリック。(私は VS の言語を英語にしているので、日本語にしている方は適宜読み替えてください)

メニューバーから Extentions (拡張機能) → Manage Extentions

左のタブの「Online」を選択した状態で検索バーに Bot Framework v4 SDK Templates を入力しましょう。

クエリが走り、一番 上の「Bot Framework v4 SDK Templates for Visual Studio」を Download したら、VS2019 を再起動します。

3-2: プロジェクト作成

Visual Studio 2019 の Create a new project (新規作成) から
Echo Bot (Bot Framework v4 - .NET Core 3.1) を選択して作ります。

プロジェクト名は任意で。(私は MyQnABot にしました)

Create」(作成) を押します。

3-3: 実行してみる

プロジェクトが開くので、取りあえずなにもいじらずデバッグ実行してみます。(F5 押して実行)

web ブラウザが立ち上がります。http://localhost:3978/

3-4: Bot Framewrork Emulator で実行

エミュレータ (Bot Framewrork Emulator) を開きます。

Open Bot」ボタンをクリック

Bot URL (エンドポイント) に http://localhost:3978/api/messages を入力し「Connect」

チャット画面が開きます。

開いたとき、最初は Hello and welcome! の定型文だけ返してきていますが、
こちらが何か言うと、その送った文字列そのままを返す、という動きをしています。(エコー bot)

3-5: QnA Maker に繋げる準備:接続情報を記述

プロジェクトの設定ファイル appsettings.json に QnA Maker の設定を書きます。

QnA Maker の Publish 画面にある以下の *** で囲んだ部分の値を入れる

POST /knowledgebases/***00000000-0000-0000-0000-00000000000***/generateAnswer
Host: ***https://qna-m365kaota.azurewebsites.net/qnamaker***
Authorization: EndpointKey ***11111111-1111-1111-1111-11111111111***
Content-Type: application/json
{"question":"<Your question>"}

appsettings.json サンプル

{
  "MicrosoftAppId": "",
  "MicrosoftAppPassword": "",
  "QnAKnowledgebaseId": "00000000-0000-0000-0000-00000000000",
  "QnAEndpointKey": "11111111-1111-1111-1111-11111111111",
  "QnAEndpointHostName": "https://自分でつけた名前.azurewebsites.net/qnamaker"
}

(今回はサンプルなので構成ファイルに直書きしますが、本番では Azure App Serviceアプリケーション設定 に書くほうが安全です)

3-6: プロジェクトに QnA Maker の SDK 入れる

プロジェクトに Microsoft.Bot.Builder.AI.QnA を NuGet (パッケージマネージャー) から入れます。詳しい方法を以下に書きます。

プロジェクト右クリックで「Manage NuGet Packages

Browse タブの検索バー Microsoft.Bot.Builder.AI.QnA 入れて出てきたパッケージをインストールします。

3-7: bot のコードを書いていく

3-7-1: Startup.cs

Bot から QnA Maker に接続するために HttpClient が必要なので
Startup.csHttpClient を使うための
下準備のコード services.AddHttpClient(); を追加します

public void ConfigureServices(IServiceCollection services)
        {
            // Http Client を使うため
            services.AddHttpClient();

3-7-2: EchoBot.cs: QnA Maker を呼び出し

Bots フォルダの下の EchoBot.cs に bot のクラスがあります。

ここの OnMessageActivityAsync メソッドが
ユーザーから話しかけられた時に呼ばれるメソッドになります。

なのでここで QnA Maker を呼び出せば QA bot が作れます。

まず、必要なものを EchoBot で使えるようにしましょう。

コンストラクタを作って ASP.NET Core から必要なものを渡してもらいます。

今回は QnA Maker への接続情報と HttpClient を作るための IHttpClientFactory を受け取ります。

まず using を追加します

using Microsoft.Extensions.Configuration;
using System.Net.Http;

次にコンストラクタを書いていきます

private readonly IConfiguration _configuration;
private readonly IHttpClientFactory _httpClientFactory;

public EchoBot(IConfiguration configuration, IHttpClientFactory httpClientFactory)
{
   _configuration = configuration;
   _httpClientFactory = httpClientFactory;
}

次に、OnMessageActivityAsync メソッドを置き換えていきます。
足りない using は適宜インテリセンスで追加していってください

// ユーザーから話しかけられた時に呼ばれるメソッド。
// なのでここで QnA Maker を呼び出す
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    // QnA Maker に接続するためのクライアントを作る
    var qnaMaker = new QnAMaker(new QnAMakerEndpoint
        {
            // appsetting.json に書いた設定項目 
            KnowledgeBaseId = _configuration["QnAKnowledgebaseId"],
            EndpointKey = _configuration["QnAEndpointKey"],
            Host = _configuration["QnAEndpointHostName"]
        }, 
        options: null,
        httpClient: _httpClientFactory.CreateClient()
    );

    // QnA Maker から一番マッチした質問の回答を受け取る
    var options = new QnAMakerOptions { Top = 1 };

    // デバッグ用にオウム返し
    await turnContext.SendActivityAsync(
        MessageFactory.Text(text: $"(*゚▽゚* っ)З 質問は『{turnContext.Activity.Text}』だね!")
    );

    var response = await qnaMaker.GetAnswersAsync(turnContext, options);

    // 回答が存在したら応答する
    if (response != null && response.Length > 0)
    {
        await turnContext.SendActivityAsync(
                activity: MessageFactory.Text(response[0].Answer),
                cancellationToken: cancellationToken
            );
    }
    else
    {
        await turnContext.SendActivityAsync(
                activity: MessageFactory.Text("質問に対する回答が見つかりませんでした"),
                cancellationToken: cancellationToken
            );
    }
}

実行してエミュレータでちゃんと動いているのを確認します

たとえば以下のメッセージを試してみてください

大学で買った Windows はどこでダウンロードできるの?

Windows の 32 bit 版と 64 bit 版って何?

Office のインストールについてもっと教えて

3-7-3: EchoBot.cs: 最初のメッセージを編集

EchoBot クラスの OnMembersAddedAsync でメンバーが追加されたときのメッセージがあるので、ここを日本語にしておきましょう。

var welcomeText = "(*゚▽゚* っ)З こんにちは!何でも聞いてね";

3-8: Azure にデプロイ

Visual Studio のプロジェクトの右クリックメニューから「発行」

事前に作っておいた App Service を選びます。

publish (発行) しましょう

4: Teams と繋げる

今までエミュレータでの実行でしたが、いよいよ Teams 上で動かしてみましょう。

4-1: チャンネル登録

最初に作った Web App Bot のリソースに移動します。

その左の「チャンネル」から「Microsoft Teams チャンネルを構成」をクリック。

「保存」を押します。

4-2: Microsoft App ID コピー

また左のメニューの「Configuration (設定)」から
Microsoft App ID をコピーします。

4-3: Teams bot 設定ファイル manifest.json

Teams bot 設定ファイル manifest.json を書きます。

「アプリ名は何」「作者名」などのアプリの設定や
アプリの接続情報「Microsoft App ID/ Secret」(Azure からコピペしてくるやつ)などを
json で記述する、設定ファイルです。

(詳細:公式ドキュメント『Reference: Manifest schema for Microsoft Teams』

色々書けるのですが、今回は最小の要素で構成されたものでいきましょう。

こちらを適当なテキストエディタにコピペして manifest.json という名前で保存してください。

{
    "$schema": " https://developer.microsoft.com/en-us/json-schemas/teams/v1.3/MicrosoftTeams.schema.json",
    "manifestVersion": "1.3",
    "version": "1.0.0",
    "id": "ボットチャンネル登録にあるボットのAppId",
    "packageName": "com.example.mysamplebot",
    "developer": {
        "name": "開発者名",
        "websiteUrl": "https://example.com/",
        "privacyUrl": "https://example.com/privacy",
        "termsOfUseUrl": "https://example.com/app-tos"
    },
    "name": {
        "short": "FAQbot",
        "full": "FAQ-bot"
    },
    "description": {
        "short": "サンプルのボット",
        "full": "サンプルのボットです。"
    },
    "icons": {
        "outline": "icon32x32.png",
        "color": "icon192x192.png"
    },
    "accentColor": "#ff0000",
    "bots": [
        {
            "botId": "ボットチャンネル登録にあるボットのAppId",
            "needsChannelSelector": false,
            "isNotificationOnly": false,
            "scopes": [
                "personal", "team", "groupchat"
            ],
            "supportsFiles": false,
            "commandLists": []
        }
    ]
}

こちらに先ほどコピーしておいた Microsoft App ID をコピペします。2 か所あります。

4-4: bot アイコンをつくる

アイコン用に 32 x 32 と 192 x 192 の画像を
それぞれ icon32x32.png, icon192x192.png などという名前で保存しましょう。

アイコン画像作るのが面倒な方は
こちらからご自由にお使いください

https://github.com/chomado/210219_FAQbot-on-Teams/tree/main/teams-settings

4-5: zip で固める

エクスプローラーで manifest.json, icon32x32.png, icon192x192.png を選択して右クリックから圧縮します。


(図:私が過去書いた記事『【第4/5】Teams bot をローカル (Visual Studio 2019) で開発し、Azure で無料で動かす【その4:Teams に繋げてデバッグ編】』)

4-6: Teams にカスタムアプリとして登録

さて、いよいよ Teams での作業となります。
Teams を開いて左下の「カスタムアプリをアップロード」をクリックします。


(図:私が過去書いた記事『【第4/5】Teams bot をローカル (Visual Studio 2019) で開発し、Azure で無料で動かす【その4:Teams に繋げてデバッグ編】』)

あとはメッセージの体裁を適当に整えれば完成です!

コードは全て GitHub に公開しました

https://github.com/chomado/210219_FAQbot-on-Teams

読んで頂きましてありがとうございました😊

ご質問やご感想などありましたら、ぜひツイッター (@chomado) でお気軽にお問い合わせください。