アクティビティ ハンドラーを使用したイベント ドリブンの会話
[アーティクル] 12/26/2023
3 人の共同作成者
フィードバック
この記事の内容
この記事の対象: SDK v4
アクティビティ ハンドラー は、イベント ドリブンな方法で、ボットの会話ロジックを整理します。
それぞれのアクティビティの種類またはサブタイプが、異なる種類の会話イベントを表します。
内部では、ボットのターン ハンドラー は、受信したアクティビティの種類に関係なく、個別のアクティビティ ハンドラーを呼び出します。
たとえば、ボットがメッセージ アクティビティを受信すると、ターン ハンドラーはその受信アクティビティを確認して、on message アクティビティ アクティビティ ハンドラーに送信します。 ボットを構築するとき、メッセージを処理し、これに応答するためのボット ロジックはこの on message アクティビティ ハンドラーに格納されます。 同様に、会話に追加されたメンバーを処理するロジックは、会話にメンバーが追加されると必ず呼び出される on members added ハンドラーに格納されます。
ボット ロジックを整理するその他の方法については、ボットのしくみ にある「ボット ロジック 」セクションを参照してください。
これらのハンドラーにロジックを実装するには、以下の「サンプル アクティビティアクティビティ ハンドラー 」セクションで示されるように、お使いのボットでこれらのメソッドをオーバーライドします。 これらの各ハンドラーに基本実装はないため、必要なロジックをご自身のオーバーライドに追加するだけです。
基本ターン ハンドラーのオーバーライドが必要になる場合もあります。たとえば、ターンの最後に状態を保存 するような状況です。 これを行う場合は、最初に必ず await base.OnTurnAsync(turnContext, cancellationToken);
を呼び出して、OnTurnAsync
の基本実装がご自身の追加コードの前に実行されていることを確認します。 この実装は特に、OnMessageActivityAsync
などの残りのアクティビティ ハンドラーを呼び出す役割を果たします。
JavaScript の ActivityHandler
では、イベント エミッタ/リスナー パターンが使用されます。
たとえば、onMessage
メソッドを使用してメッセージ アクティビティのイベント リスナーを登録します。 リスナーは複数登録できます。 ボットがメッセージ アクティビティを受信すると、アクティビティ ハンドラーがそのアクティビティを認識し、各 onMessage
アクティビティ リスナーを登録された順に送信します。
ボットを構築すると、メッセージの処理とメッセージへの応答を行うボット ロジックが onMessage
リスナーに格納されます。 同様に、会話に追加されたメンバーを処理するロジックは、会話にメンバーが追加されると必ず呼び出される onMembersAdded
リスナーに格納されます。
これらのリスナーを追加するには、以下の「ボット ロジック 」セクションで示すように、ご自身のボットにリスナーを登録します。 各リスナーにボット ロジックを組み込み、最後に必ず next()
を呼び出します 。 next()
を呼び出すことで、次のリスナーが確実に実行されます。
ターンが終了する前に必ず状態を保存 してください。 これを行うには、アクティビティ ハンドラーの run
メソッドをオーバーライドし、親の run
メソッドが完了した後に状態を保存します。
基本ターン ハンドラーのオーバーライドが必要になる状況はめったにないため、この操作を行う場合は気を付けてください。
onDialog
という名前の特殊なハンドラーがあります。 onDialog
ハンドラーは、ハンドラーの残りの部分の実行後、最後に実行され、特定のアクティビティの種類には関連付けられていません。 上記のすべてのハンドラーと同様、必ず next()
を呼び出して、プロセスの残りの部分を終了してください。
これらのハンドラーにロジックを実装するには、以下の「サンプル アクティビティアクティビティ ハンドラー 」セクションで示されるように、お使いのボットでこれらのメソッドをオーバーライドします。 これらの各ハンドラーに基本実装はありません。このため、必要なロジックをご自身のオーバーライドに追加するだけです。
基本ターン ハンドラーのオーバーライドが必要になる場合もあります。たとえば、ターンの最後に状態を保存 するような状況です。 これを行う場合は、最初に必ず super.onTurn(turnContext);
を呼び出して、onTurn
の基本実装がご自身の追加コードの前に実行されていることを確認します。 この実装は特に、onMessageActivity
などの残りのアクティビティ ハンドラーを呼び出す役割を果たします。
ご自身のボットを構築するとき、メッセージを処理し、これに応答するためのボット ロジックはこの on_message_activity
ハンドラーに格納されます。 同様に、会話に追加されたメンバーを処理するロジックは、会話にメンバーが追加されると必ず呼び出される on_members_added
ハンドラーに格納されます。
たとえば、ボットがメッセージ アクティビティを受信すると、ターン ハンドラーはその受信アクティビティを確認して、on_message_activity
アクティビティ ハンドラーに送信します。
これらのハンドラーにロジックを実装するには、以下の「サンプル アクティビティアクティビティ ハンドラー 」セクションで示されるように、お使いのボットでこれらのメソッドをオーバーライドします。 これらの各ハンドラーに基本実装はないため、必要なロジックをご自身のオーバーライドに追加するだけです。
基本ターン ハンドラーのオーバーライドが必要になる場合もあります。たとえば、ターンの最後に状態を保存 するような状況です。 これを行う場合は、最初に必ず await super().on_turn(turnContext);
を呼び出して、on_turn
の基本実装がご自身の追加コードの前に実行されていることを確認します。 この実装は特に、on_message_activity
などの残りのアクティビティ ハンドラーを呼び出す役割を果たします。
アクティビティの処理
ボット ロジックは 1 つ以上のチャネルからの受信アクティビティを処理し、応答の送信アクティビティを生成します。
主なボット ロジックはボット コードで定義されます。 ボットをアクティビティ ハンドラーとして実装するには、IBot
インターフェイスを実装する ActivityHandler
からボット クラスを派生させます。 ActivityHandler
ではさまざまなハンドラーが、 OnMessageActivityAsync
および OnMembersAddedAsync
などのさまざまな種類のアクティビティに対して定義されます。 これらのメソッドは保護されていますが、ActivityHandler
から派生しているため、上書きすることができます。
ActivityHandler
で定義されているハンドラーを次に示します。
イベント
Handler
説明
任意のアクティビティの種類を受信した
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
ハンドラーを呼び出すための基本実装を取得するか、ご自身でこれらのハンドラーを呼び出す必要があります。 それ以外の場合、これらのハンドラーは呼び出されず、そのコードは実行されません。
主なボット ロジックはボット コードで定義されます。 ボットをアクティビティ ハンドラーとして実装するには、ActivityHandler
を拡張します。 ActivityHandler
ではさまざまなイベントがさまざまな種類のアクティビティに対して定義されます。ご自身のボットのビヘイビアーを変更するには、onMessage
、onConversationUpdate
などのイベント リスナーをここで登録します。
各種類のイベントのリスナーを登録するには、次のメソッドを使用します。
イベント
登録メソッド
説明
任意のアクティビティの種類を受信した
onTurn
アクティビティを受信した場合のリスナーを登録します。
メッセージ アクティビティを受信した
onMessage
message
アクティビティを受信した場合のリスナーを登録します。
会話の更新アクティビティを受信した
onConversationUpdate
conversationUpdate
アクティビティを受信した場合のリスナーを登録します。
メンバーが会話に参加した
onMembersAdded
メンバー (ボットを含む) が会話に参加した場合のリスナーを登録します。
メンバーが会話から退出した
onMembersRemoved
メンバー (ボットを含む) が会話から退出した場合のリスナーを登録します。
メッセージの反応アクティビティを受信した
onMessageReaction
messageReaction
アクティビティを受信した場合のリスナーを登録します。
メッセージの反応がメッセージに追加された
onReactionsAdded
反応がメッセージに追加された場合のリスナーを登録します。
メッセージの反応がメッセージから削除された
onReactionsRemoved
反応がメッセージから削除された場合のリスナーを登録します。
イベント アクティビティを受信した
onEvent
event
アクティビティを受信した場合のリスナーを登録します。
Token-response イベント アクティビティを受信した
onTokenResponseEvent
tokens/response
イベントを受信した場合のリスナーを登録します。
インストールの更新アクティビティを受信した
onInstallationUpdate
installationUpdate
アクティビティを受信した場合のリスナーを登録します。
ボットがインストールされた
onInstallationUpdateAdd
組織単位内にボットがインストールされるときのリスナーを登録します。
ボットがアンインストールされた
onInstallationUpdateRemove
組織単位内でボットがアンインストールされるときのリスナーを登録します。
他のアクティビティの種類を受信した
onUnrecognizedActivityType
特定の種類のアクティビティのハンドラーが定義されていない場合のリスナーを登録します。
アクティビティ ハンドラーが完了した
onDialog
適用可能なハンドラーが完了した後に呼び出されます。
各ハンドラーから next
継続関数を呼び出して、処理を続行できるようにします。 next
が呼び出されない場合は、アクティビティの処理が終了します。
主なボット ロジックはボット コードで定義されます。 ボットをアクティビティ ハンドラーとして実装するには、Bot
インターフェイスを実装する ActivityHandler
からボット クラスを派生させます。 ActivityHandler
ではさまざまなハンドラーが、 onMessageActivity
および onMembersAdded
などのさまざまな種類のアクティビティに対して定義されます。 これらのメソッドは保護されていますが、ActivityHandler
から派生しているため、上書きすることができます。
ActivityHandler
で定義されているハンドラーを次に示します。
イベント
Handler
説明
任意のアクティビティの種類を受信した
onTurn
受信したアクティビティの種類に基づいて、他のハンドラーのいずれかを呼び出します。
メッセージ アクティビティを受信した
onMessageActivity
これをオーバーライドして message
アクティビティを処理します。
会話の更新アクティビティを受信した
onConversationUpdateActivity
conversationUpdate
アクティビティで、ボット以外のメンバーが会話に参加した場合、または会話から退出した場合にハンドラーを呼び出します。
ボットではないメンバーが会話に参加した
onMembersAdded
これをオーバーライドして、会話に参加するメンバーを処理します。
ボットではないメンバーが会話から退出した
onMembersRemoved
これをオーバーライドして、会話から退出メンバーを処理します。
イベント アクティビティを受信した
onEventActivity
event
アクティビティで、イベントの種類に固有のハンドラーを呼び出します。
Token-response イベント アクティビティを受信した
onTokenResponseEvent
これをオーバーライドして、トークン応答イベントを処理します。
Non-token-response イベント アクティビティを受信した
onEvent
これをオーバーライドして、その他の種類のイベントを処理します。
メッセージの反応アクティビティを受信した
onMessageReactionActivity
messageReaction
アクティビティで、メッセージに対して 1 つ以上の反応が追加または削除された場合にハンドラーを呼び出します。
メッセージの反応がメッセージに追加された
onReactionsAdded
これをオーバーライドして、メッセージに追加された反応を処理します。
メッセージの反応がメッセージから削除された
onReactionsRemoved
これをオーバーライドして、メッセージから削除された反応を処理します。
インストールの更新アクティビティを受信した
onInstallationUpdate
installationUpdate
アクティビティで、ボットがインストールされたかアンインストールされたかに基づいてハンドラーを呼び出します。
ボットがインストールされた
onInstallationUpdateAdd
これをオーバーライドして、ボットが組織単位内にインストールされるタイミングのロジックを追加します。
ボットがアンインストールされた
onInstallationUpdateRemove
これをオーバーライドして、組織単位内でボットがアンインストールされるタイミングのロジックを追加します。
他のアクティビティの種類を受信した
onUnrecognizedActivityType
これをオーバーライドして、他の方法では処理されない任意のアクティビティの種類を処理します。
このような各種ハンドラーにインバウンド アクティビティに関する情報を提供する turnContext
があり、これはインバウンド HTTP 要求に対応しています。 アクティビティの種類もさまざまであるため、各ハンドラーが、そのターン コンテキスト パラメーターで厳密に型指定されたアクティビティを提供します。ほとんどの場合、onMessageActivity
は常に処理され通常は最も一般的です。
パブリック メソッド onTurn
を実装するオプションもあります。 現在、このメソッドの基本実装はエラー チェックを処理し、各受信アクティビティの種類に応じて、特定のハンドラー (たとえば、このサンプルでは定義する 2 つのハンドラー) をそれぞれ呼び出します。 ほとんどの場合、このメソッドはそのままにして、個別のハンドラーを使用できますが、onTurn
のカスタム実装が必要な場合でも、これは引き続き使用できます。
重要
onTurn
メソッドをオーバーライドする場合は、super.onTurn
を呼び出して、他のすべての on<activity>
ハンドラーを呼び出すための基本実装を取得するか、ご自身でこれらのハンドラーを呼び出す必要があります。 それ以外の場合、これらのハンドラーは呼び出されず、そのコードは実行されません。
主なボット ロジックはボット コードで定義されます。 ボットをアクティビティ ハンドラーとして実装するには、ActivityHandler
からボット クラスを派生させます。そうすることで、抽象 Bot
クラスから派生します。 ActivityHandler
ではさまざまなハンドラーが、 on_message_activity
および on_members_added
などのさまざまな種類のアクティビティに対して定義されます。 これらのメソッドは保護されていますが、ActivityHandler
から派生しているため、上書きすることができます。
ActivityHandler
で定義されているハンドラーを次に示します。
イベント
Handler
説明
任意のアクティビティの種類を受信した
on_turn
受信したアクティビティの種類に基づいて、他のハンドラーのいずれかを呼び出します。
メッセージ アクティビティを受信した
on_message_activity
これをオーバーライドして message
アクティビティを処理します。
会話の更新アクティビティを受信した
on_conversation_update_activity
conversationUpdate
アクティビティで、ボット以外のメンバーが会話に参加した場合、または会話から退出した場合にハンドラーを呼び出します。
ボットではないメンバーが会話に参加した
on_members_added_activity
これをオーバーライドして、会話に参加するメンバーを処理します。
ボットではないメンバーが会話から退出した
on_members_removed_activity
これをオーバーライドして、会話から退出メンバーを処理します。
イベント アクティビティを受信した
on_event_activity
event
アクティビティで、イベントの種類に固有のハンドラーを呼び出します。
Token-response イベント アクティビティを受信した
on_token_response_event
これをオーバーライドして、トークン応答イベントを処理します。
Non-token-response イベント アクティビティを受信した
on_event_activity
これをオーバーライドして、その他の種類のイベントを処理します。
メッセージの反応アクティビティを受信した
on_message_reaction_activity
messageReaction
アクティビティで、メッセージに対して 1 つ以上の反応が追加または削除された場合にハンドラーを呼び出します。
メッセージの反応がメッセージに追加された
on_reactions_added
これをオーバーライドして、メッセージに追加された反応を処理します。
メッセージの反応がメッセージから削除された
on_reactions_removed
これをオーバーライドして、メッセージから削除された反応を処理します。
インストールの更新アクティビティを受信した
on_installation_update
installationUpdate
アクティビティで、ボットがインストールされたかアンインストールされたかに基づいてハンドラーを呼び出します。
ボットがインストールされた
on_installation_update_add
これをオーバーライドして、ボットが組織単位内にインストールされるタイミングのロジックを追加します。
ボットがアンインストールされた
on_installation_update_remove
これをオーバーライドして、組織単位内でボットがアンインストールされるタイミングのロジックを追加します。
他のアクティビティの種類を受信した
on_unrecognized_activity_type
これをオーバーライドして、他の方法では処理されない任意のアクティビティの種類を処理します。
このような各種ハンドラーにインバウンド アクティビティに関する情報を提供する turn_context
があり、これはインバウンド HTTP 要求に対応しています。 アクティビティの種類もさまざまであるため、各ハンドラーが、そのターン コンテキスト パラメーターで厳密に型指定されたアクティビティを提供します。ほとんどの場合、on_message_activity
は常に処理され通常は最も一般的です。
このフレームワークの以前の 4.x バージョンと同様に、パブリック メソッド on_turn
を実装するオプションもあります。 現在、このメソッドの基本実装はエラー チェックを処理し、各受信アクティビティの種類に応じて、特定のハンドラー (たとえば、このサンプルでは定義する 2 つのハンドラー) をそれぞれ呼び出します。 ほとんどの場合、このメソッドはそのままにして、個別のハンドラーを使用できますが、on_turn
のカスタム実装が必要な場合でも、これは引き続き使用できます。
重要
on_turn
メソッドをオーバーライドする場合は、super().on_turn
を呼び出して、他のすべての on_<activity>
ハンドラーを呼び出すための基本実装を取得するか、ご自身でこれらのハンドラーを呼び出す必要があります。 それ以外の場合、これらのハンドラーは呼び出されず、そのコードは実行されません。
サンプル アクティビティ ハンドラー
たとえば、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);
}
}
}
}
class EchoBot extends ActivityHandler {
constructor() {
super();
// See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types.
this.onMessage(async (context, next) => {
const replyText = `Echo: ${ context.activity.text }`;
await context.sendActivity(MessageFactory.text(replyText, replyText));
// By calling next() you ensure that the next BotHandler is run.
await next();
});
this.onMembersAdded(async (context, next) => {
const membersAdded = context.activity.membersAdded;
const welcomeText = 'Hello and welcome!';
for (let cnt = 0; cnt < membersAdded.length; ++cnt) {
if (membersAdded[cnt].id !== context.activity.recipient.id) {
await context.sendActivity(MessageFactory.text(welcomeText, welcomeText));
}
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
}
}
public class EchoBot extends ActivityHandler {
@Override
protected CompletableFuture<Void> onMessageActivity(TurnContext turnContext) {
return turnContext.sendActivity(
MessageFactory.text("Echo: " + turnContext.getActivity().getText())
).thenApply(sendResult -> null);
}
@Override
protected CompletableFuture<Void> onMembersAdded(
List<ChannelAccount> membersAdded,
TurnContext turnContext
) {
String welcomeText = "Hello and welcome!";
return membersAdded.stream()
.filter(
member -> !StringUtils
.equals(member.getId(), turnContext.getActivity().getRecipient().getId())
).map(channel -> turnContext.sendActivity(MessageFactory.text(welcomeText, welcomeText, null)))
.collect(CompletableFutures.toFutureList()).thenApply(resourceResponses -> null);
}
}
class EchoBot(ActivityHandler):
async def on_members_added_activity(
self, members_added: [ChannelAccount], turn_context: TurnContext
):
for member in members_added:
if member.id != turn_context.activity.recipient.id:
await turn_context.send_activity("Hello and welcome!")
async def on_message_activity(self, turn_context: TurnContext):
return await turn_context.send_activity(
MessageFactory.text(f"Echo: {turn_context.activity.text}")
)
次のステップ
Microsoft Teams チャンネルでは、ボットが Teams と適切に連携するためにサポートする必要がある Teams 固有のアクティビティがいくつか紹介されています。 Microsoft Teams のボット開発の主要な概念を理解するには、「Microsoft Teams のボットのしくみ 」を参照してください
アクティビティ ハンドラーは、ターン間の会話状態を追跡する必要のないボットを設計するのに適した方法です。 ダイアログ ライブラリ は、ユーザーとの長期にわたる会話を管理するための方法となります。