アクティビティ ハンドラーを使用したイベント ドリブンの会話

この記事の対象: SDK v4

アクティビティ ハンドラーは、イベント ドリブンな方法で、ボットの会話ロジックを整理します。 それぞれのアクティビティの種類またはサブタイプが、異なる種類の会話イベントを表します。 内部では、ボットのターン ハンドラーは、受信したアクティビティの種類に関係なく、個別のアクティビティ ハンドラーを呼び出します。

たとえば、ボットがメッセージ アクティビティを受信すると、ターン ハンドラーはその受信アクティビティを確認して、on message アクティビティ アクティビティ ハンドラーに送信します。 ボットを構築するとき、メッセージを処理し、これに応答するためのボット ロジックはこの on message アクティビティ ハンドラーに格納されます。 同様に、会話に追加されたメンバーを処理するロジックは、会話にメンバーが追加されると必ず呼び出される on members added ハンドラーに格納されます。

ボット ロジックを整理するその他の方法については、ボットのしくみにある「ボット ロジック」セクションを参照してください。

Note

Bot Framework JavaScript SDK、C#、Python SDK は引き続きサポートされますが、Java SDK については、最終的な長期サポートは 2023 年 11 月に終了する予定です。 このリポジトリ内の重要なセキュリティとバグの修正のみが行われます。

Java SDK を使用して構築された既存のボットは引き続き機能します。

新しいボットの構築については、Power Virtual Agents の使用を検討し、適切なチャットボット ソリューションの選択についてお読みください。

詳細については、「The future of bot building」をご覧ください。

これらのハンドラーにロジックを実装するには、以下の「サンプル アクティビティアクティビティ ハンドラー」セクションで示されるように、お使いのボットでこれらのメソッドをオーバーライドします。 これらの各ハンドラーに基本実装はないため、必要なロジックをご自身のオーバーライドに追加するだけです。

基本ターン ハンドラーのオーバーライドが必要になる場合もあります。たとえば、ターンの最後に状態を保存するような状況です。 これを行う場合は、最初に必ず await base.OnTurnAsync(turnContext, cancellationToken); を呼び出して、OnTurnAsync の基本実装がご自身の追加コードの前に実行されていることを確認します。 この実装は特に、OnMessageActivityAsync などの残りのアクティビティ ハンドラーを呼び出す役割を果たします。

アクティビティの処理

ボット ロジックは 1 つ以上のチャネルからの受信アクティビティを処理し、応答の送信アクティビティを生成します。

主なボット ロジックはボット コードで定義されます。 ボットをアクティビティ ハンドラーとして実装するには、IBot インターフェイスを実装する ActivityHandler からボット クラスを派生させます。 ActivityHandler ではさまざまなハンドラーが、 OnMessageActivityAsync および OnMembersAddedAsync などのさまざまな種類のアクティビティに対して定義されます。 これらのメソッドは保護されていますが、ActivityHandler から派生しているため、上書きすることができます。

ActivityHandler で定義されているハンドラーを次に示します。

Event ハンドラー 説明
任意のアクティビティの種類を受信した OnTurnAsync 受信したアクティビティの種類に基づいて、他のハンドラーのいずれかを呼び出します。
メッセージ アクティビティを受信した OnMessageActivityAsync これをオーバーライドして message アクティビティを処理します。
会話の更新アクティビティを受信した OnConversationUpdateActivityAsync conversationUpdate アクティビティで、ボット以外のメンバーが会話に参加した場合、または会話から退出した場合にハンドラーを呼び出します。
ボットではないメンバーが会話に参加した OnMembersAddedAsync これをオーバーライドして、会話に参加するメンバーを処理します。
ボットではないメンバーが会話から退出した OnMembersRemovedAsync これをオーバーライドして、会話から退出メンバーを処理します。
イベント アクティビティを受信した OnEventActivityAsync event アクティビティで、イベントの種類に固有のハンドラーを呼び出します。
Token-response イベント アクティビティを受信した OnTokenResponseEventAsync これをオーバーライドして、トークン応答イベントを処理します。
Non-token-response イベント アクティビティを受信した OnEventAsync これをオーバーライドして、その他の種類のイベントを処理します。
メッセージの反応アクティビティを受信した OnMessageReactionActivityAsync messageReaction アクティビティで、メッセージに対して 1 つ以上の反応が追加または削除された場合にハンドラーを呼び出します。
メッセージの反応がメッセージに追加された OnReactionsAddedAsync これをオーバーライドして、メッセージに追加された反応を処理します。
メッセージの反応がメッセージから削除された OnReactionsRemovedAsync これをオーバーライドして、メッセージから削除された反応を処理します。
インストールの更新アクティビティを受信した OnInstallationUpdateActivityAsync installationUpdate アクティビティで、ボットがインストールされたかアンインストールされたかに基づいてハンドラーを呼び出します。
ボットがインストールされた OnInstallationUpdateAddAsync これをオーバーライドして、ボットが組織単位内にインストールされるタイミングのロジックを追加します。
ボットがアンインストールされた OnInstallationUpdateRemoveAsync これをオーバーライドして、組織単位内でボットがアンインストールされるタイミングのロジックを追加します。
他のアクティビティの種類を受信した OnUnrecognizedActivityTypeAsync これをオーバーライドして、他の方法では処理されない任意のアクティビティの種類を処理します。

このような各種ハンドラーにインバウンド アクティビティに関する情報を提供する turnContext があり、これはインバウンド HTTP 要求に対応しています。 アクティビティの種類もさまざまであるため、各ハンドラーが、そのターン コンテキスト パラメーターで厳密に型指定されたアクティビティを提供します。ほとんどの場合、OnMessageActivityAsync は常に処理され通常は最も一般的です。

このフレームワークの以前の 4.x バージョンと同様に、パブリック メソッド OnTurnAsync を実装するオプションもあります。 現在、このメソッドの基本実装はエラー チェックを処理し、各受信アクティビティの種類に応じて、特定のハンドラー (たとえば、このサンプルでは定義する 2 つのハンドラー) をそれぞれ呼び出します。 ほとんどの場合、このメソッドはそのままにして、個別のハンドラーを使用できますが、OnTurnAsync のカスタム実装が必要な場合でも、これは引き続き使用できます。

重要

OnTurnAsync メソッドをオーバーライドする場合は、base.OnTurnAsync を呼び出して、他のすべての On<activity>Async ハンドラーを呼び出すための基本実装を取得するか、ご自身でこれらのハンドラーを呼び出す必要があります。 それ以外の場合、これらのハンドラーは呼び出されず、そのコードは実行されません。

サンプル アクティビティ ハンドラー

たとえば、on members added を処理してユーザーを会話に招待したり、on message を処理して、ボットに送信したメッセージをエコー バックしたりすることができます。

public class EchoBot : ActivityHandler
{
    protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
    {
        var replyText = $"Echo: {turnContext.Activity.Text}";
        await turnContext.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);
    }

    protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
    {
        var welcomeText = "Hello and welcome!";
        foreach (var member in membersAdded)
        {
            if (member.Id != turnContext.Activity.Recipient.Id)
            {
                await turnContext.SendActivityAsync(MessageFactory.Text(welcomeText, welcomeText), cancellationToken);
            }
        }
    }
}

次のステップ

  • Microsoft Teams チャンネルでは、ボットが Teams と適切に連携するためにサポートする必要がある Teams 固有のアクティビティがいくつか紹介されています。 Microsoft Teams のボット開発の主要な概念を理解するには、「Microsoft Teams のボットのしくみ」を参照してください
  • アクティビティ ハンドラーは、ターン間の会話状態を追跡する必要のないボットを設計するのに適した方法です。 ダイアログ ライブラリは、ユーザーとの長期にわたる会話を管理するための方法となります。