使用活動處理程式的事件驅動交談
本文內容
適用於: SDK v4
活動處理程式 是組織 Bot 交談邏輯的事件驅動方式。
活動的每個不同類型或子類型都代表不同類型的交談事件。
實際上,Bot 的 回合處理程式 會針對所接收的任何活動類型呼叫個別活動處理程式。
例如,如果 Bot 收到訊息活動,回合處理程式就會看到傳入活動,並將它傳送至 訊息活動 活動處理程式。 建置 Bot 時,用於處理和回應訊息的 Bot 邏輯會在此訊息 活動 處理程式中。 同樣地,處理要新增至交談之成員的邏輯將會進入您在 加入成員 的處理程式中,每當成員加入至交談時,就會呼叫該處理程式。
如需組織 Bot 邏輯的其他方式,請參閱 Bot 運作方式中的 Bot 邏輯 一節。
若要實作這些處理程式的邏輯,您會在 Bot 中覆寫這些方法,例如下面的 範例活動處理程式 一節。 針對每個處理程式,沒有基底實作,因此只要在覆寫中新增您想要的邏輯即可。
在某些情況下,您會想要覆寫基底回合處理程式,例如 在回合結束時儲存狀態 。 這樣做時,請務必先呼叫 await base.OnTurnAsync(turnContext, cancellationToken);
,確定的基底實作 OnTurnAsync
會在您的其他程式碼之前執行。 該基底實作是負責呼叫其他活動處理程式,例如 OnMessageActivityAsync
。
JavaScript ActivityHandler
會使用事件發出器和接聽程式模式。
例如,使用 onMessage
方法來註冊訊息活動的事件接聽程式。 您可以註冊多個接聽程式。 當 Bot 收到訊息活動時,活動處理程式會看到傳入的活動,並以註冊的順序傳送每個 onMessage
活動接聽程式。
建置 Bot 時,Bot 邏輯會進入接聽程式, onMessage
以處理和回應訊息。 同樣地,處理要新增至交談之成員的邏輯將會出現在接 onMembersAdded
聽程式中,每當成員新增至交談時,就會呼叫該接聽程式。
若要新增這些接聽程式,您會在 Bot 中註冊它們,如下列 Bot 邏輯 一節所示。 針對每個接聽程式,請包含 Bot 邏輯,然後請務必在結尾 呼叫 next()
。 藉由呼叫 next()
,您可以確定下一個接聽程式正在執行。
請務必在 回合結束前儲存狀態 。 您可以覆寫活動處理程式 run
方法,並在父 run
系的方法完成之後儲存狀態來執行此動作。
沒有常見的情況,您會想要覆寫基底回合處理程式,因此,如果您嘗試這樣做,請小心。
有一個名為的特殊處理程式 onDialog
。 處理程式 onDialog
會在結尾執行,在其餘處理程式執行之後執行,而且不會系結至特定活動類型。 如同上述所有處理程式,請務必呼叫 next()
以確保其餘的進程會結束。
若要實作這些處理程式的邏輯,您會在 Bot 中覆寫這些方法,例如下面的 範例活動處理程式 一節。 這些處理程式沒有基底實作,因此請在覆寫中新增您想要的邏輯。
在某些情況下,您會想要覆寫基底回合處理程式,例如 在回合結束時儲存狀態 。 這樣做時,請務必先呼叫 super.onTurn(turnContext);
,確定的基底實 onTurn
作會在您的其他程式碼之前執行。 該基底實作是負責呼叫其他活動處理程式,例如 onMessageActivity
。
建置 Bot 時,Bot 邏輯會在此處理程式中 on_message_activity
處理和回應訊息。 同樣地,處理要新增至交談之成員的邏輯將會進入您的 on_members_added
處理程式,每當成員新增至交談時,就會呼叫該處理程式。
例如,如果 Bot 收到訊息活動,回合處理程式就會看到該傳入活動,並將它傳送至 on_message_activity
活動處理程式。
若要實作這些處理程式的邏輯,您會在 Bot 中覆寫這些方法,例如下面的 範例活動處理程式 一節。 針對每個處理程式,沒有基底實作,因此只要在覆寫中新增您想要的邏輯即可。
在某些情況下,您會想要覆寫基底回合處理程式,例如 在回合結束時儲存狀態 。 這樣做時,請務必先呼叫 await super().on_turn(turnContext);
,確定的基底實作 on_turn
會在您的其他程式碼之前執行。 該基底實作是負責呼叫其他活動處理程式,例如 on_message_activity
。
活動處理
Bot 邏輯會處理來自一或多個通道的連入活動,併產生傳出活動以回應。
主要 Bot 邏輯定義於 Bot 程式代碼中。 若要實作 Bot 作為活動處理程式,請從 ActivityHandler
衍生 Bot 類別,以實作 IBot
介面。 ActivityHandler
針對不同類型的活動定義各種處理程式,例如 OnMessageActivityAsync
、 和 OnMembersAddedAsync
。 這些方法受到保護,但可以覆寫,因為我們衍生自 ActivityHandler
。
中 ActivityHandler
定義的處理程式如下:
活動
處理常式
描述
收到的任何活動類型
OnTurnAsync
根據收到的活動類型,呼叫其他處理程式之一。
已接收的訊息活動
OnMessageActivityAsync
覆寫此項目以處理 message
活動。
已接收交談更新活動
OnConversationUpdateActivityAsync
conversationUpdate
在活動上,如果 Bot 加入或離開交談以外的成員,則會呼叫處理程式。
非 Bot 成員已加入交談
OnMembersAddedAsync
覆寫此項目以處理加入交談的成員。
非 Bot 成員離開交談
OnMembersRemovedAsync
覆寫此選項以處理離開交談的成員。
已接收的事件活動
OnEventActivityAsync
event
在活動上,呼叫事件類型特定的處理程式。
已接收令牌回應事件活動
OnTokenResponseEventAsync
覆寫此項目以處理令牌回應事件。
收到非令牌回應事件活動
OnEventAsync
覆寫此選項以處理其他類型的事件。
已接收訊息反應活動
OnMessageReactionActivityAsync
messageReaction
在活動上,如果已新增或移除訊息中的一或多個回應,則呼叫處理程式。
新增至訊息的訊息反應
OnReactionsAddedAsync
覆寫此選項以處理新增至訊息的反應。
訊息回應已從訊息中移除
OnReactionsRemovedAsync
覆寫此選項以處理從訊息中移除的反應。
已接收安裝更新活動
OnInstallationUpdateActivityAsync
installationUpdate
在活動上,根據 Bot 是否已安裝或卸載,呼叫處理程式。
已安裝 Bot
OnInstallationUpdateAddAsync
覆寫此選項,以在組織單位內安裝 Bot 時新增邏輯。
已卸載 Bot
OnInstallationUpdateRemoveAsync
覆寫此選項,以在組織單位內卸載 Bot 時新增邏輯。
收到的其他活動類型
OnUnrecognizedActivityTypeAsync
覆寫此選項以處理任何未處理的活動類型。
這些不同的處理程式具有 turnContext
,提供傳入活動的相關信息,其對應至輸入 HTTP 要求。 活動可以是各種類型,因此每個處理程式都會在其回合內容參數中提供強型別活動;在大部分情況下, OnMessageActivityAsync
一律會處理,而且通常是最常見的。
如同此架構的舊版 4.x,也有可實作公用方法 的選項 OnTurnAsync
。 目前,此方法的基底實作會處理錯誤檢查,然後根據傳入活動的類型呼叫每個特定處理程式(例如我們在此範例中定義的兩個處理程式)。 在大部分情況下,您可以將該方法單獨使用,並使用個別處理程式,但如果您的情況需要的自定義實 OnTurnAsync
作,它仍然是一個選項。
重要
如果您覆寫 OnTurnAsync
方法,您必須呼叫 base.OnTurnAsync
以取得基底實作,以呼叫所有其他 On<activity>Async
處理程式或自行呼叫這些處理程式。 否則,不會呼叫這些處理程式,而且不會執行該程序代碼。
主要 Bot 邏輯定義於 Bot 程式代碼中。 若要將 Bot 實作為活動處理程式,請擴充 ActivityHandler
。 ActivityHandler
針對不同類型的活動定義各種事件,您可以註冊事件接聽程式來修改 Bot 的行為,例如 使用 onMessage
和 onConversationUpdate
。
使用這些方法來註冊每種事件類型的接聽程式:
活動
註冊方法
描述
收到的任何活動類型
onTurn
在收到任何活動時註冊接聽程式。
已接收的訊息活動
onMessage
註冊接收活動時的 message
接聽程式。
已接收交談更新活動
onConversationUpdate
在收到任何 conversationUpdate
活動時註冊接聽程式。
成員已加入交談
onMembersAdded
註冊成員加入交談時的接聽程式,包括 Bot。
成員離開交談
onMembersRemoved
註冊成員離開交談時,包括 Bot 的接聽程式。
已接收訊息反應活動
onMessageReaction
在收到任何 messageReaction
活動時註冊接聽程式。
新增至訊息的訊息反應
onReactionsAdded
註冊當回應新增至訊息時的接聽程式。
訊息回應已從訊息中移除
onReactionsRemoved
註冊從訊息中移除回應時的接聽程式。
已接收的事件活動
onEvent
在收到任何 event
活動時註冊接聽程式。
已接收令牌回應事件活動
onTokenResponseEvent
註冊接收事件時的 tokens/response
接聽程式。
已接收安裝更新活動
onInstallationUpdate
在收到任何 installationUpdate
活動時註冊接聽程式。
已安裝 Bot
onInstallationUpdateAdd
註冊在組織單位內安裝 Bot 時的接聽程式。
已卸載 Bot
onInstallationUpdateRemove
在組織單位內卸載 Bot 時,註冊的接聽程式。
收到的其他活動類型
onUnrecognizedActivityType
當未定義特定活動類型的處理程式時,註冊 的接聽程式。
活動處理程式已完成
onDialog
在任何適用的處理程式完成之後呼叫。
next
從每個處理程式呼叫接續函式,以允許繼續處理。 如果未 next
呼叫 ,則活動處理會結束。
主要 Bot 邏輯定義於 Bot 程式代碼中。 若要實作 Bot 作為活動處理程式,請從 ActivityHandler
衍生 Bot 類別,以實作 Bot
介面。 ActivityHandler
針對不同類型的活動定義各種處理程式,例如 onMessageActivity
、 和 onMembersAdded
。 這些方法受到保護,但可以覆寫,因為我們衍生自 ActivityHandler
。
中 ActivityHandler
定義的處理程式如下:
活動
處理常式
描述
收到的任何活動類型
onTurn
根據收到的活動類型,呼叫其他處理程式之一。
已接收的訊息活動
onMessageActivity
覆寫此項目以處理 message
活動。
已接收交談更新活動
onConversationUpdateActivity
conversationUpdate
在活動上,如果 Bot 加入或離開交談以外的成員,則會呼叫處理程式。
非 Bot 成員已加入交談
onMembersAdded
覆寫此項目以處理加入交談的成員。
非 Bot 成員離開交談
onMembersRemoved
覆寫此選項以處理離開交談的成員。
已接收的事件活動
onEventActivity
event
在活動上,呼叫事件類型特定的處理程式。
已接收令牌回應事件活動
onTokenResponseEvent
覆寫此項目以處理令牌回應事件。
收到非令牌回應事件活動
onEvent
覆寫此選項以處理其他類型的事件。
已接收訊息反應活動
onMessageReactionActivity
messageReaction
在活動上,如果已新增或移除訊息中的一或多個回應,則呼叫處理程式。
新增至訊息的訊息反應
onReactionsAdded
覆寫此選項以處理新增至訊息的反應。
訊息回應已從訊息中移除
onReactionsRemoved
覆寫此選項以處理從訊息中移除的反應。
已接收安裝更新活動
onInstallationUpdate
installationUpdate
在活動上,根據 Bot 是否已安裝或卸載,呼叫處理程式。
已安裝 Bot
onInstallationUpdateAdd
覆寫此選項,以在組織單位內安裝 Bot 時新增邏輯。
已卸載 Bot
onInstallationUpdateRemove
覆寫此選項,以在組織單位內卸載 Bot 時新增邏輯。
收到的其他活動類型
onUnrecognizedActivityType
覆寫此選項以處理任何未處理的活動類型。
這些不同的處理程式具有 turnContext
,提供傳入活動的相關信息,其對應至輸入 HTTP 要求。 活動可以是各種類型,因此每個處理程式都會在其回合內容參數中提供強型別活動;在大部分情況下, onMessageActivity
一律會處理,而且通常是最常見的。
另外還有一個選項可以實作公用方法 onTurn
。 目前,此方法的基底實作會處理錯誤檢查,然後根據傳入活動的類型呼叫每個特定處理程式(例如我們在此範例中定義的兩個處理程式)。 在大部分情況下,您可以將該方法單獨使用,並使用個別處理程式,但如果您的情況需要的自定義實 onTurn
作,它仍然是一個選項。
重要
如果您覆寫 onTurn
方法,您必須呼叫 super.onTurn
以取得基底實作,以呼叫所有其他 on<activity>
處理程式或自行呼叫這些處理程式。 否則,不會呼叫這些處理程式,而且不會執行該程序代碼。
主要 Bot 邏輯定義於 Bot 程式代碼中。 若要實作 Bot 作為活動處理程式,請從 ActivityHandler
衍生 Bot 類別,而該類別又衍生自抽象 Bot
類。 ActivityHandler
針對不同類型的活動定義各種處理程式,例如 on_message_activity
和 on_members_added
。 這些方法受到保護,但可以覆寫,因為我們衍生自 ActivityHandler
。
中 ActivityHandler
定義的處理程式如下:
活動
處理常式
描述
收到的任何活動類型
on_turn
根據收到的活動類型,呼叫其他處理程式之一。
已接收的訊息活動
on_message_activity
覆寫此項目以處理 message
活動。
已接收交談更新活動
on_conversation_update_activity
conversationUpdate
在活動上,如果 Bot 加入或離開交談以外的成員,則會呼叫處理程式。
非 Bot 成員已加入交談
on_members_added_activity
覆寫此項目以處理加入交談的成員。
非 Bot 成員離開交談
on_members_removed_activity
覆寫此選項以處理離開交談的成員。
已接收的事件活動
on_event_activity
event
在活動上,呼叫事件類型特定的處理程式。
已接收令牌回應事件活動
on_token_response_event
覆寫此項目以處理令牌回應事件。
收到非令牌回應事件活動
on_event_activity
覆寫此選項以處理其他類型的事件。
已接收訊息反應活動
on_message_reaction_activity
messageReaction
在活動上,如果已新增或移除訊息中的一或多個回應,則呼叫處理程式。
新增至訊息的訊息反應
on_reactions_added
覆寫此選項以處理新增至訊息的反應。
訊息回應已從訊息中移除
on_reactions_removed
覆寫此選項以處理從訊息中移除的反應。
已接收安裝更新活動
on_installation_update
installationUpdate
在活動上,根據 Bot 是否已安裝或卸載,呼叫處理程式。
已安裝 Bot
on_installation_update_add
覆寫此選項,以在組織單位內安裝 Bot 時新增邏輯。
已卸載 Bot
on_installation_update_remove
覆寫此選項,以在組織單位內卸載 Bot 時新增邏輯。
收到的其他活動類型
on_unrecognized_activity_type
覆寫此選項以處理任何未處理的活動類型。
這些不同的處理程式具有 turn_context
,提供傳入活動的相關信息,其對應至輸入 HTTP 要求。 活動可以是各種類型,因此每個處理程式都會在其回合內容參數中提供強型別活動;在大部分情況下, on_message_activity
一律會處理,而且通常是最常見的。
如同此架構的舊版 4.x,也有可實作公用方法 的選項 on_turn
。 目前,此方法的基底實作會處理錯誤檢查,然後根據傳入活動的類型呼叫每個特定處理程式(例如我們在此範例中定義的兩個處理程式)。 在大部分情況下,您可以將該方法單獨使用,並使用個別處理程式,但如果您的情況需要的自定義實 on_turn
作,它仍然是一個選項。
重要
如果您覆寫 on_turn
方法,您必須呼叫 super().on_turn
以取得基底實作,以呼叫所有其他 on_<activity>
處理程式或自行呼叫這些處理程式。 否則,不會呼叫這些處理程式,而且不會執行該程序代碼。
範例活動處理程式
例如,您可以處理 新增 至歡迎使用者交談的成員,並處理 訊息 以回應他們傳送給 Bot 的訊息。
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 特定活動,您的 Bot 必須支援才能與 Teams 正常運作。 若要了解開發 Microsoft Teams Bot 的重要概念,請參閱 Microsoft Teams Bot 的運作方式
活動處理程式是設計不需要追蹤回合之間對話狀態的 Bot 的好方法。 dialogs 連結庫 提供方式來管理與用戶長時間執行的交談。