重要
你需要參加 Frontier 預覽計畫 ,才能搶 先取得 Microsoft Agent 365 的使用權。 Frontier 直接連結你與 Microsoft 最新的 AI 創新。 Frontier 預覽受限於您現有的客戶協議預覽條款。 由於這些功能仍在開發中,其可用性與功能可能會隨時間改變。
通知模組讓開發者能建立能回應 Microsoft 365 應用程式事件與通知的代理程式。 有了通知支援,客服人員能在用戶透過電子郵件、文件評論或其他協作情境互動時接收並處理警示。
通知工作流程
請依照此工作流程啟用您的 AI 代理應用程式通知:
安裝通知套件。
匯入通知元件
寄存器通知處理程序
- 使用通知處理方法來登錄路由
- 針對特定通知類型設定處理程式(例如:電子郵件、Word、Excel、PowerPoint)
代理程式中的程序通知
- 代理程式接收來自 Microsoft 365 應用程式的通知
- 處理收到的通知並適當回應
通知類型
支援以下通知類型。
| 通知類型 |
Description |
子頻道識別碼 |
|
電子郵件 |
代理人會收到一封電子郵件,裡面提到或地址 |
email |
|
字 |
代理人在 Word 文件的留言中被提及 |
word |
|
Excel |
代理人在 Excel 文件的註解中被提及 |
excel |
| - PowerPoint |
代理人在一份PowerPoint文件的評論中被提及 |
powerpoint |
| 週期事件 |
代理程式生命週期通知(建立使用者身份、工作負載啟動、使用者刪除) |
無法使用 |
代理生命週期事件
代理生命週期事件使您的代理能回應與代理使用者身份管理相關的特定系統事件。 SDK 目前支援三個生命週期事件:
| 活動類型 |
事件識別碼 |
Description |
|
使用者身份建立 |
agenticUserIdentityCreated |
當建立代理使用者身份時觸發 |
|
工作負載入職更新 |
agenticUserWorkloadOnboardingUpdated |
當代理使用者的工作負載入職狀態更新時會觸發 |
|
使用者已刪除 |
agenticUserDeleted |
當代理使用者身份被刪除時觸發 |
這些事件允許代理執行初始化任務、清理操作或狀態管理,以回應使用者生命週期的變更。
向你的經紀人新增通知
請依照以下步驟在現有代理人中啟用通知處理:
匯入通知元件
將這些匯入資料加入你的代理檔案:
from microsoft_agents_a365 import AgentApplication
from microsoft_agents_a365.notifications import (
AgentNotification,
AgentNotificationActivity,
NotificationTypes
)
from microsoft_agents.activity import ChannelId
from microsoft_agents.hosting.core import Authorization, TurnContext
-
AgentApplication:用於建置 Agent365 應用程式的基底類別;提供路由活動、狀態管理及請求處理的核心功能
-
AgentNotification:用於以裝飾器方法註冊通知處理程序的類別。 提供
on_agent_notification()、 on_email()、、 on_word()及其他便利裝潢服務
-
AgentNotificationActivity:包含解析後通知資料的包裝器,具有像 和
wpx_comment_notification 這樣的類型屬性email_notification,包含通知專屬的中繼資料(ID、對話細節、文件參考)
-
通知類型:所支援通知類型的列舉(
EMAIL_NOTIFICATION, WPX_COMMENT, AGENT_LIFECYCLE)
-
ChannelId:用於指定通知通道(例如,
ChannelId(channel="agents", sub_channel="*"))
-
授權:處理通知的授權上下文
-
TurnContext:來自 Agents SDK 的當前對話 Turn context
import { AgentApplication, TurnContext, TurnState } from '@microsoft/agents-hosting';
import { ActivityTypes } from '@microsoft/agents-activity';
import {
AgentNotificationActivity,
NotificationType
} from '@microsoft/agents-a365-notifications';
-
AgentApplication:用於建置 Agent365 應用程式的基底類別;提供路由活動、狀態管理及請求處理的核心功能。 用於
onAgentNotification() 登錄處理器
-
AgentNotificationActivity:解析通知活動,並以強烈類型化的通知資料。 屬性如
emailNotification 和 wpxCommentNotification 包含通知專屬的元資料(ID、對話細節、文件參考)
-
通知類型:通知類型的列舉(
Unknown, WpxComment, EmailNotification, AgentLifecycleNotification)
-
TurnContext:目前對話 Turn context
-
TurnState:用於對話的狀態管理
using Microsoft.Agents.Hosting;
using Microsoft.Agents.A365.Notifications;
using Microsoft.Agents.A365.Notifications.Extensions;
using Microsoft.Agents.A365.Notifications.Models;
-
AgentApplication:用於建置 Agent365 應用程式的基底類別;提供路由活動、狀態管理及請求處理的核心功能。 用於
OnAgentNotification() 登錄處理器
-
AgentNotificationActivity:以強型別通知資料包裝活動。 屬性如
EmailNotification 和 WpxCommentNotification 包含通知專屬的元資料(ID、對話細節、文件參考)
-
NotificationTypeEnum:支援通知類型的列舉(
Unknown, WpxComment, EmailNotification, AgentLifecycleNotification)
-
ITurnContext:代表當前對話轉向情境的介面
-
ITurnState:對話狀態管理介面
在您的代理中註冊通知處理程式
將通知處理程式加入您的代理的初始化:
class YourAgent(AgentApplication):
def __init__(self, app):
# Create notification handler
agent_notification = AgentNotification(app)
# Register handler for all notifications
@agent_notification.on_agent_notification(
ChannelId(channel="agents", sub_channel="*")
)
async def handle_all_notifications(context, state, notification):
# Route based on notification type
if notification.notification_type == NotificationTypes.EMAIL_NOTIFICATION:
await self.handle_email_notification(context, state, notification)
elif notification.notification_type == NotificationTypes.WPX_COMMENT:
await self.handle_comment_notification(context, state, notification)
else:
await context.send_activity('Notification type not yet implemented.')
export class YourAgent extends AgentApplication {
constructor() {
super();
// Register notification handler
this.onAgentNotification("*", async (context, state, notification) => {
await this.handleAgentNotificationActivity(context, state, notification);
});
}
async handleAgentNotificationActivity(context, state, notification) {
// Route based on notification type
switch (notification.notificationType) {
case NotificationType.EmailNotification:
await this.handleEmailNotification(context, state, notification);
break;
case NotificationType.WpxComment:
await this.handleCommentNotification(context, state, notification);
break;
default:
await context.sendActivity('Notification type not yet implemented.');
}
}
}
public class YourAgent : AgentApplication
{
public YourAgent()
{
// Register notification handler
this.OnAgentNotification(
"*",
HandleNotificationAsync
);
}
private async Task HandleNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
// Route based on notification type
switch (activity.NotificationType)
{
case NotificationTypeEnum.EmailNotification:
await HandleEmailNotificationAsync(turnContext, turnState, activity,
cancellationToken);
break;
case NotificationTypeEnum.WpxComment:
await HandleCommentNotificationAsync(turnContext, turnState, activity,
cancellationToken);
break;
default:
await turnContext.SendActivityAsync("Notification type not yet implemented.",
cancellationToken: cancellationToken);
break;
}
}
}
實作特定的通知處理器
為每種通知類型新增處理方法:
class YourAgent(AgentApplication):
# ... __init__ from above ...
async def handle_email_notification(self, context, state, notification):
"""Handle email notifications"""
email = notification.email_notification
if not email:
await context.send_activity('No email data found')
return
# Process the email
await context.send_activity(
f'Received email notification. Email ID: {email.id}'
)
# Your email processing logic here
async def handle_comment_notification(self, context, state, notification):
"""Handle document comment notifications"""
comment = notification.wpx_comment_notification
if not comment:
await context.send_activity('No comment data found')
return
# Process the comment
await context.send_activity(
f'Received comment notification. Document ID: {comment.document_id}'
)
# Your comment processing logic here
async handleEmailNotification(context, state, notification) {
const email = notification.emailNotification;
if (!email) {
await context.sendActivity('No email data found');
return;
}
// Process the email
await context.sendActivity(`Received email notification. Email ID: ${email.id}`);
// Your email processing logic here
}
async handleCommentNotification(context, state, notification) {
const comment = notification.wpxCommentNotification;
if (!comment) {
await context.sendActivity('No comment data found');
return;
}
// Process the comment
await context.sendActivity(`Received comment. Document ID: ${comment.documentId}`);
// Your comment processing logic here
}
private async Task HandleEmailNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var email = activity.EmailNotification;
if (email == null)
{
await turnContext.SendActivityAsync("No email data found",
cancellationToken: cancellationToken);
return;
}
// Process the email
await turnContext.SendActivityAsync(
$"Received email notification. Email ID: {email.Id}",
cancellationToken: cancellationToken
);
// Your email processing logic here
}
private async Task HandleCommentNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment == null)
{
await turnContext.SendActivityAsync("No comment data found",
cancellationToken: cancellationToken);
return;
}
// Process the comment
await turnContext.SendActivityAsync(
$"Received comment. Document ID: {comment.DocumentId}",
cancellationToken: cancellationToken
);
// Your comment processing logic here
}
專用通知處理器
在設定 基本通知路由後,使用專門的處理方法進行更細緻的控制。 這些應用程式可讓您:
- 為同一通知類型註冊多個處理器
- 設定處理者優先權並排序
- 依處理器設定自動認證
注意
在大多數使用情境下,通用處理模式就足夠了。 當你需要進階路由或多個處理者來處理同一通知類型時,可以使用這些專門的處理器。
專門處理所有通知的處理器
註冊更多處理所有通知類型的處理器:
from microsoft_agents_a365.notifications import (
AgentNotification,
NotificationTypes
)
from microsoft_agents.activity import ChannelId
# Create notification handler
agent_notification = AgentNotification(app)
# Register handler for all notifications
@agent_notification.on_agent_notification(
ChannelId(channel="agents", sub_channel="*")
)
async def handle_all_notifications(context, state, notification):
if notification.notification_type == NotificationTypes.EMAIL_NOTIFICATION:
if notification.email_notification:
await context.send_activity(f"Received email: {notification.email_notification.id}")
elif notification.notification_type == NotificationTypes.WPX_COMMENT:
if notification.wpx_comment_notification:
await context.send_activity(f"Received comment: {notification.wpx_comment_notification.comment_id}")
import '@microsoft/agents-a365-notifications';
// Register handler for all notifications
app.onAgentNotification('*', async (context, state, notification) => {
const { notificationType, emailNotification, wpxCommentNotification } = notification;
switch (notificationType) {
case NotificationType.EmailNotification:
if (emailNotification) {
console.log('Email ID:', emailNotification.id);
await context.sendActivity('Processing your email...');
}
break;
case NotificationType.WpxComment:
if (wpxCommentNotification) {
console.log('Comment ID:', wpxCommentNotification.commentId);
await context.sendActivity('Responding to your comment...');
}
break;
}
});
using Microsoft.Agents.A365.Notifications;
using Microsoft.Agents.A365.Notifications.Extensions;
using Microsoft.Agents.A365.Notifications.Models;
// Register handler for all notifications (wildcard)
this.OnAgentNotification(
"*",
AgentNotificationActivityAsync
);
private async Task AgentNotificationActivityAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
switch (activity.NotificationType)
{
case NotificationTypeEnum.EmailNotification:
var email = activity.EmailNotification;
if (email != null)
{
await turnContext.SendActivityAsync(
$"Received email: {email.Id}",
cancellationToken: cancellationToken
);
}
break;
case NotificationTypeEnum.WpxComment:
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
$"Received comment: {comment.CommentId}",
cancellationToken: cancellationToken
);
}
break;
}
}
專門處理電子郵件通知的處理程式
專門註冊更多處理人員以接收電子郵件通知:
from microsoft_agents_a365.notifications import AgentNotification
from microsoft_agents.activity import ChannelId, AgentSubChannel
# Create notification handler
agent_notification = AgentNotification(app)
# Use the convenience method for email notifications
@agent_notification.on_email()
async def handle_email(context, state, notification):
email = notification.email_notification
if not email:
await context.send_activity('No email found')
return
# Process the email
email_id = email.id
conversation_id = email.conversation_id
# Send response
await context.send_activity('Thank you for your email!')
app.onAgenticEmailNotification(async (context, state, notification) => {
const email = notification.emailNotification;
if (!email) {
await context.sendActivity('No email found');
return;
}
// Process the email
console.log('Email ID:', email.id);
console.log('Conversation ID:', email.conversationId);
// Send a response
await context.sendActivity('Thank you for your email!');
});
// Register handler for email notifications
this.OnAgenticEmailNotification(HandleEmailNotificationAsync);
private async Task HandleEmailNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var email = activity.EmailNotification;
if (email == null)
{
await turnContext.SendActivityAsync("No email found",
cancellationToken: cancellationToken);
return;
}
// Process email
var emailId = email.Id;
var conversationId = email.ConversationId;
// Send response
await turnContext.SendActivityAsync(
"Thank you for your email!",
cancellationToken: cancellationToken
);
}
註冊更多 Word、Excel 及 PowerPoint 評論通知的處理人員:
from microsoft_agents_a365.notifications import AgentNotification
# Create notification handler
agent_notification = AgentNotification(app)
# Use convenience methods for document notifications
@agent_notification.on_word()
async def handle_word(context, state, notification):
comment = notification.wpx_comment_notification
if comment:
document_id = comment.document_id
comment_id = comment.comment_id
await context.send_activity(f'Processing Word comment: {comment_id}')
@agent_notification.on_excel()
async def handle_excel(context, state, notification):
comment = notification.wpx_comment_notification
if comment:
await context.send_activity('Processing Excel comment')
@agent_notification.on_powerpoint()
async def handle_powerpoint(context, state, notification):
comment = notification.wpx_comment_notification
if comment:
await context.send_activity('Processing PowerPoint comment')
// Handle Word notifications
app.onAgenticWordNotification(async (context, state, notification) => {
const comment = notification.wpxCommentNotification;
if (comment) {
console.log('Word comment:', comment.commentText);
await context.sendActivity('Processing your Word comment...');
}
});
// Handle Excel notifications
app.onAgenticExcelNotification(async (context, state, notification) => {
const comment = notification.wpxCommentNotification;
if (comment) {
await context.sendActivity('Processing your Excel comment...');
}
});
// Handle PowerPoint notifications
app.onAgenticPowerPointNotification(async (context, state, notification) => {
const comment = notification.wpxCommentNotification;
if (comment) {
await context.sendActivity('Processing your PowerPoint comment...');
}
});
// Register handlers for document notifications
this.OnAgenticWordNotification(HandleWordNotificationAsync);
this.OnAgenticExcelNotification(HandleExcelNotificationAsync);
this.OnAgenticPowerPointNotification(HandlePowerPointNotificationAsync);
private async Task HandleWordNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
$"Processing Word comment: {comment.CommentText}",
cancellationToken: cancellationToken
);
}
}
private async Task HandleExcelNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
"Processing Excel comment",
cancellationToken: cancellationToken
);
}
}
private async Task HandlePowerPointNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
"Processing PowerPoint comment",
cancellationToken: cancellationToken
);
}
}
生命週期事件專用處理程序
註冊更多處理程序,用於代理生命週期事件,如使用者身份建立、工作負載啟動及使用者刪除:
from microsoft_agents_a365.notifications import AgentNotification
# Create notification handler
agent_notification = AgentNotification(app)
# Handle all lifecycle events
@agent_notification.on_agent_lifecycle_notification("*")
async def handle_lifecycle(context, state, notification):
lifecycle_notification = notification.agent_lifecycle_notification
if lifecycle_notification:
event_type = lifecycle_notification.lifecycle_event_type
if event_type == "agenticUserIdentityCreated":
await context.send_activity('User identity created')
elif event_type == "agenticUserWorkloadOnboardingUpdated":
await context.send_activity('Workload onboarding completed')
elif event_type == "agenticUserDeleted":
await context.send_activity('User identity deleted')
// Handle all lifecycle notifications
app.onLifecycleNotification(async (context, state, notification) => {
await context.sendActivity('Lifecycle event received');
});
// Handle specific lifecycle events
app.onAgenticUserCreatedNotification(async (context, state, notification) => {
await context.sendActivity('User identity created');
});
app.onAgenticUserWorkloadOnboardingNotification(
async (context, state, notification) => {
await context.sendActivity('Workload onboarding completed');
}
);
app.onAgenticUserIdentityDeletedNotification(
async (context, state, notification) => {
await context.sendActivity('User identity deleted');
}
);
// Register lifecycle notification handlers
this.OnLifecycleNotification(HandleAllLifecycleEventsAsync);
this.OnAgenticUserIdentityCreatedNotification(HandleUserCreatedAsync);
this.OnAgenticUserWorkloadOnboardingNotification(HandleWorkloadOnboardingAsync);
this.OnAgenticUserDeletedNotification(HandleUserDeletedAsync);
private async Task HandleAllLifecycleEventsAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"Lifecycle event received",
cancellationToken: cancellationToken
);
}
private async Task HandleUserCreatedAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"User identity created",
cancellationToken: cancellationToken
);
}
private async Task HandleWorkloadOnboardingAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"Workload onboarding completed",
cancellationToken: cancellationToken
);
}
private async Task HandleUserDeletedAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"User identity deleted",
cancellationToken: cancellationToken
);
}
進階設定
本節介紹進階設定選項,以微調通知處理程序。 這些配置讓你能控制處理器的執行順序、管理認證需求,並優化針對複雜情境的通知處理。
處理者優先順序與排名
使用多個專用處理器時,你可以用排名值來指定優先順序。 較低的值就代表優先順序較高。
from microsoft_agents_a365.notifications import AgentNotification
from microsoft_agents.activity import ChannelId, AgentSubChannel
# Create notification handler
agent_notification = AgentNotification(app)
# Higher priority handler (processed first)
@agent_notification.on_email(rank=100)
async def high_priority_email(context, state, notification):
# Handle with high priority
pass
# Lower priority handler (processed after higher priority)
@agent_notification.on_email(rank=200)
async def low_priority_email(context, state, notification):
# Handle with lower priority
pass
// Higher priority handler (lower rank number)
app.onAgenticEmailNotification(
async (context, state, notification) => {
// Handle email with high priority
},
100 // rank
);
// Lower priority handler
app.onAgenticEmailNotification(
async (context, state, notification) => {
// Handle email with lower priority
},
200 // rank
);
// Higher priority handler (lower rank number)
this.OnAgenticEmailNotification(
HighPriorityEmailHandlerAsync,
rank: 100
);
// Lower priority handler
this.OnAgenticEmailNotification(
LowerPriorityEmailHandlerAsync,
rank: 200
);
驗證處理常式
為需要驗證的通知設定自動登入處理器:
from microsoft_agents_a365.notifications import AgentNotification
from microsoft_agents.activity import ChannelId, AgentSubChannel
# Create notification handler
agent_notification = AgentNotification(app)
# Handler with automatic authentication
@agent_notification.on_email(auto_sign_in_handlers=['agentic'])
async def authenticated_email(context, state, notification):
# Authentication is handled automatically
pass
app.onAgenticEmailNotification(
async (context, state, notification) => {
// Handler with automatic authentication
},
32767, // rank (default)
['agentic'] // autoSignInHandlers
);
this.OnAgenticEmailNotification(
HandleAuthenticatedEmailAsync,
rank: 32767,
autoSignInHandlers: new[] { "agentic" }
);
測試與監視
用通知測試你的經紀人
在實作通知處理器後,測試你的代理程式,確保它能正確接收並處理不同類型的通知。 依照 測試指南 設定環境,然後主要專注於 「帶通知 活動測試」部分,利用代理認證驗證通知。
監控通知處理
透過增加可觀察功能來監控您的代理的通知處理。 追蹤通知處理、回應時間及錯誤率,以了解代理表現。
了解更多關於追蹤與監控的實施