Microsoft Teams用の会話エージェントを構築するときは、会話イベントを操作できます。 Teams は、エージェントがアクティブなスコープで発生する会話イベントの通知をエージェントに送信します。 コードでこれらのイベントをキャプチャして、以下のアクションを行うことができます。
- エージェントがチームに追加されたときにウェルカム メッセージをトリガーします。
- 新しいチーム メンバーが追加または削除されたときにウェルカム メッセージをトリガーする。
- チャネルが作成、名前変更、削除されたときに通知をトリガーする。
- エージェント メッセージがユーザーに気に入られたときに通知をトリガーします。
- インストール中にユーザー入力 (選択) からエージェントの既定のチャネルを特定します。
会話の更新イベント
会話更新イベントを使用して、より優れた通知と効果的なエージェント アクションを提供できます。
重要
- 新しいイベントはいつでも追加でき、エージェントが受信を開始します。
- 予期しないイベントを受信するようにエージェントを設計します。
- Teams SDK を使用している場合、エージェントは、処理しないことを選択したイベントに
200 - OK で自動的に応答します。
- Azure Communication Services (ACS) クライアントが Teams 会議に参加または退出すると、会話更新イベントはトリガーされません。
エージェントは、次のいずれかの場合に conversationUpdate イベントを受け取ります。
- エージェントが会話に追加されたとき。
- 会話に他のメンバーが追加または削除されます。
- 会話メタデータが変更されました。
conversationUpdate イベントは、追加されたチームのメンバーシップ更新に関する情報を受け取ると、エージェントに送信されます。 また、ボットが個人の会話に初めて追加されたときにも更新を受け取ります。
次の表は、Teams 会話更新イベントの一覧と詳細を示しています。
| 実行されたアクション |
EventType |
呼び出されたメソッド |
説明 |
範囲 |
| チャネルを作成しました |
channelCreated |
OnTeamsChannelCreatedAsync |
チャネルが作成される。 |
チーム |
| チャネルの名前が変更されました |
channelRenamed |
OnTeamsChannelRenamedAsync |
チャネルの名前が変更されます。 |
チーム |
| チャネルが削除されました |
channelDeleted |
OnTeamsChannelDeletedAsync |
チャネルが削除されます。 |
チーム |
| 復元されたチャネル |
channelRestored |
OnTeamsChannelRestoredAsync |
チャネルが復元されます。 |
チーム |
| メンバーが追加されました |
membersAdded |
OnTeamsMembersAddedAsync |
メンバーが追加されます。 |
すべて |
| 削除されたメンバー |
membersRemoved |
OnTeamsMembersRemovedAsync |
メンバーが削除されます。 |
すべて |
| チャットの名前が変更されました |
teamRenamed |
OnTeamsTeamRenamedAsync |
チームの名前が変更されます。 |
チーム |
| チームが削除されました |
teamDeleted |
OnTeamsTeamDeletedAsync |
チームが削除されます。 |
チーム |
| チームがアーカイブされました |
teamArchived |
OnTeamsTeamArchivedAsync |
チームはアーカイブされます。 |
チーム |
| チームのアーカイブが解除されました |
teamUnarchived |
OnTeamsTeamUnarchivedAsync |
チームのアーカイブが解除されます。 |
チーム |
| 復元されたチーム |
teamRestored |
OnTeamsTeamRestoredAsync |
チームが復元される |
チーム |
チャネルを作成しました
channelCreated イベントは、エージェントがインストールされているチームに新しいチャネルが作成されるたびにエージェントに送信されます。
次のコードは、チャネルで作成されたイベントの例を示しています。
app.OnChannelCreated(async context =>
{
var channelName = context.Activity.ChannelData.Channel.Name;
await context.Send($"{channelName} is the Channel created");
});
app.on('channelCreated', async ({ activity, send }) => {
const channelName = activity.channelData.channel.name;
await send(`${channelName} is the Channel created`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:34:07.478Z",
"localTimestamp": "2017-02-23T12:34:07.478-07:00",
"id": "f:dd6ec311",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1wR7IdIRIoerMIWbewMi75JA3scaMuxvFon9eRQW2Nix5loMDo0362st2IaRVRirPZBv1WdXT8TIFWWmlQCizZQ"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterBot"
},
"channelData": {
"channel": {
"id": "19:6d97d816470f481dbcda38244b98689a@thread.skype",
"name": "FunDiscussions"
},
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"eventType": "channelCreated",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_channel_created
async def handle_channel_created(ctx: ActivityContext[ConversationUpdateActivity]):
channel = ctx.activity.channel_data.channel
await ctx.send(f"The new channel is {channel.name}. The channel id is {channel.id}")
チャネルの名前が変更されました
channelRenamed イベントは、エージェントがインストールされているチームでチャネルの名前が変更されるたびにエージェントに送信されます。
次のコードは、チャネルの名前が変更されたイベントの例を示しています。
app.OnChannelRenamed(async context =>
{
var channelName = context.Activity.ChannelData.Channel.Name;
await context.Send($"{channelName} is the new Channel name");
});
app.on('channelRenamed', async ({ activity, send }) => {
const channelName = activity.channelData.channel.name;
await send(`${channelName} is the new Channel name`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:34:07.478Z",
"localTimestamp": "2017-02-23T12:34:07.478-07:00",
"id": "f:dd6ec311",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1wR7IdIRIoerMIWbewMi75JA3scaMuxvFon9eRQW2Nix5loMDo0362st2IaRVRirPZBv1WdXT8TIFWWmlQCizZQ"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterBot"
},
"channelData": {
"channel": {
"id": "19:6d97d816470f481dbcda38244b98689a@thread.skype",
"name": "PhotographyUpdates"
},
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"eventType": "channelRenamed",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_channel_renamed
async def handle_channel_renamed(ctx: ActivityContext[ConversationUpdateActivity]):
channel_name = ctx.activity.channel_data.channel.name
await ctx.send(f"The new channel name is {channel_name}")
チャネルが削除されました
channelDeleted イベントは、エージェントがインストールされているチームでチャネルが削除されるたびに、エージェントに送信されます。
次のコードは、チャネル削除イベントの例を示しています。
app.OnChannelDeleted(async context =>
{
var channelName = context.Activity.ChannelData.Channel.Name;
await context.Send($"{channelName} is the Channel deleted");
});
app.on('channelDeleted', async ({ activity, send }) => {
const channelName = activity.channelData.channel.name;
await send(`${channelName} is the Channel deleted`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:34:07.478Z",
"localTimestamp": "2017-02-23T12:34:07.478-07:00",
"id": "f:dd6ec311",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1wR7IdIRIoerMIWbewMi75JA3scaMuxvFon9eRQW2Nix5loMDo0362st2IaRVRirPZBv1WdXT8TIFWWmlQCizZQ"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterBot"
},
"channelData": {
"channel": {
"id": "19:6d97d816470f481dbcda38244b98689a@thread.skype",
"name": "PhotographyUpdates"
},
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"eventType": "channelDeleted",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_channel_deleted
async def handle_channel_deleted(ctx: ActivityContext[ConversationUpdateActivity]):
channel_name = ctx.activity.channel_data.channel.name
await ctx.send(f"The deleted channel is {channel_name}")
復元されたチャネル
channelRestored イベントは、以前に削除されたチャネルがエージェントが既にインストールされているチームに復元されるたびに、エージェントに送信されます。
次のコードは、チャネルが復元したイベントの例を示しています。
app.OnChannelRestored(async context =>
{
var channelName = context.Activity.ChannelData.Channel.Name;
await context.Send($"{channelName} is the Channel restored.");
});
app.on('channelRestored', async ({ activity, send }) => {
const channelName = activity.channelData.channel.name;
await send(`${channelName} is the Channel restored`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:34:07.478Z",
"localTimestamp": "2017-02-23T12:34:07.478-07:00",
"id": "f:dd6ec311",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1wR7IdIRIoerMIWbewMi75JA3scaMuxvFon9eRQW2Nix5loMDo0362st2IaRVRirPZBv1WdXT8TIFWWmlQCizZQ"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterBot"
},
"channelData": {
"channel": {
"id": "19:6d97d816470f481dbcda38244b98689a@thread.skype",
"name": "FunDiscussions"
},
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"eventType": "channelRestored",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_channel_restored
async def handle_channel_restored(ctx: ActivityContext[ConversationUpdateActivity]):
channel = ctx.activity.channel_data.channel
await ctx.send(
f"The restored channel is {channel.name}. The channel id is {channel.id}"
)
メンバーが追加されました
メンバーが追加したイベントは、次のシナリオでエージェントに送信されます。
エージェント自体がインストールされ、会話に追加されたとき
チーム コンテキストでは、アクティビティの conversation.id は、アプリのインストール中にユーザーが選択したチャネルまたはエージェントがインストールされたチャネルの id に設定されます。
エージェントがインストールされている会話にユーザーが追加されたとき
イベント ペイロードで受信したユーザー ID はエージェントに固有であり、ユーザーを直接メッセージングするなど、将来の使用のためにキャッシュできます。
メンバーが追加したアクティビティ eventType は、イベントがチーム コンテキストから送信されたときに teamMemberAdded に設定されます。 追加された新しいメンバーがエージェント自体かユーザーかを判断するには、Context objectのActivity オブジェクトをチェックします。
MembersAdded リストに、idがRecipient オブジェクトのid フィールドと同じオブジェクトが含まれている場合、追加されたメンバーはエージェントです。それ以外の場合はユーザーです。 エージェントの id は、 28:<MicrosoftAppId>形式になっています。
次のコードは、チーム メンバーがイベントを追加した例を示しています。
app.OnMembersAdded(async context =>
{
foreach (var member in context.Activity.MembersAdded)
{
if (member.Id == context.Activity.Recipient.Id)
{
// Send a message to introduce the bot to the team.
await context.Send($"The {member.Name} agent has joined {context.Activity.ChannelData.Team.Name}");
}
else
{
await context.Send($"{member.Name} joined {context.Activity.ChannelData.Team.Name}");
}
}
});
app.on('membersAdded', async ({ activity, send }) => {
for (const member of activity.membersAdded) {
const teamName = activity.channelData?.team?.name ?? 'not in team';
await send(`${member.id} joined ${teamName}.`);
}
});
エージェントがチームに追加されたときにエージェントが受け取るメッセージ。
注:
このペイロードでは、 conversation.id と channelData.settings.selectedChannel.id は、アプリのインストール中にユーザーが選択したチャネルの ID、またはインストールがトリガーされたチャネルの ID です。
{
"type": "conversationUpdate",
"membersAdded": [
{
"id": "28:608cacfd-1cea-40c9-b678-4b93e69bb72b"
}
],
"timestamp": "2021-12-07T22:34:56.534Z",
"id": "f:0b9079f4-d4d3-3d8e-b883-798298053c7e",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer/",
"from": {
"id": "29:1ljv6N86roXr5pjPrCJVIz6xHh5QxjI....",
"aadObjectId": "eddfa9d4-346e-4cce-a18f-fa6261ad776b"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"tenantId": "b28fdbfd-2b78-4f93-b0f8-8881793f0f8f",
"id": "19:0b7f32667e064dd9b25d7969801541f4@thread.tacv2",
"name": "2021 Test Channel"
},
"recipient": {
"id": "28:608cacfd-1cea-40c9-b678-4b93e69bb72b",
"name": "Test Agent"
},
"channelData": {
"settings": {
"selectedChannel": {
"id": "19:0b7f32667e064dd9b25d7969801541f4@thread.tacv2"
}
},
"team": {
"aadGroupId": "f3ec8cd2-e704-4344-8c47-9a3a21d683c0",
"name": "TestTeam2022",
"id": "19:zFLSDFWsesfzcmKArqKJ-65aOXJz@sgf462H2wz41@thread.tacv2"
},
"eventType": "teamMemberAdded",
"tenant": {
"id": "b28fdbfd-2b78-4f93-b0f8-8881793f0f8f"
}
}
}
エージェントが 1 対 1 のチャットに追加されたときにエージェントが受け取るメッセージ。
{
"membersAdded": [{
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0"
},
{
"id": "29:<userID>",
"aadObjectId": "***"
}
],
"type": "conversationUpdate",
"timestamp": "2019-04-23T10:17:44.349Z",
"id": "f:5f85c2ad",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:<USERID>",
"aadObjectId": "***"
},
"conversation": {
"conversationType": "personal",
"id": "***"
},
"recipient": {
"id": "28:<BOT ID>",
"name": "<BOT NAME>"
},
"channelData": {
"tenant": {
"id": "<TENANT ID>"
}
}
}
@app.on_conversation_update
async def handle_members_added(ctx: ActivityContext[ConversationUpdateActivity]):
if ctx.activity.members_added:
for member in ctx.activity.members_added:
await ctx.send(f"Welcome your new team member {member.id}")
削除されたメンバー
メンバーが削除したイベントは、次のシナリオでエージェントに送信されます。
- エージェント自体がアンインストールされ、会話から削除されます。
- エージェントがインストールされている会話からユーザーが削除されたとき。
メンバーが削除したアクティビティ eventType は、イベントがチーム コンテキストから送信されたときに teamMemberRemoved に設定されます。 削除された新しいメンバーがエージェント自体かユーザーかを判断するには、Context objectのActivity オブジェクトをチェックします。
MembersRemoved リストに、idがRecipient オブジェクトのid フィールドと同じオブジェクトが含まれている場合、追加されたメンバーはエージェントです。それ以外の場合はユーザーです。 エージェントの ID は、 28:<MicrosoftAppId>として書式設定されます。
注:
ユーザーがテナントから完全に削除されると、membersRemoved conversationUpdate イベントがトリガーされます。
次のコードは、チーム メンバーが削除したイベントの例を示しています。
app.OnMembersRemoved(async context =>
{
foreach (var member in context.Activity.MembersRemoved)
{
if (member.Id == context.Activity.Recipient.Id)
{
// The agent was removed.
// You should clear any cached data you have for this team.
}
else
{
await context.Send($"{member.Name} was removed from {context.Activity.ChannelData.Team.Name}");
}
}
});
app.on('membersRemoved', async ({ activity, send }) => {
for (const member of activity.membersRemoved) {
const teamName = activity.channelData?.team?.name ?? 'not in team';
await send(`${member.id} removed from ${teamName}.`);
}
});
次のペイロード例の channelData オブジェクトは、グループ チャットではなくチームへのメンバー追加、または新しい 1 対 1 の会話の開始に基づくものです。
{
"membersRemoved": [
{
"id": "29:1_LCi5Up14pAy65yZuaJzG1uIT7ujYhjjSTsUNqjORsZHjLHKiQIBJa4cX2XsAsRoaY7va2w6ZymA9-1VtSY_g"
}
],
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:37:06.96Z",
"localTimestamp": "2017-02-23T12:37:06.96-07:00",
"id": "f:d8a6a4aa",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0OIy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient":
{
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterAgent"
},
"channelData": {
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"eventType": "teamMemberRemoved",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_conversation_update
async def handle_members_removed(ctx: ActivityContext[ConversationUpdateActivity]):
if ctx.activity.members_removed:
for member in ctx.activity.members_removed:
await ctx.send(f"Say goodbye to {member.id}")
チャットの名前が変更されました
チームの名前が変更されると、エージェントに通知されます。 ボットは、channelData オブジェクト内に eventType.teamRenamed を含む conversationUpdate イベントを受信します。
次のコードは、チーム名が変更されたイベントの例を示しています。
app.OnTeamRenamed(async context =>
{
var teamName = context.Activity.ChannelData.Team.Name;
await context.Send($"{teamName} is the new Team name");
});
app.on('teamRenamed', async ({ activity, send }) => {
const teamName = activity.channelData.team.name;
await send(`${teamName} is the new Team name`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:35:56.825Z",
"localTimestamp": "2017-02-23T12:35:56.825-07:00",
"id": "f:1406033e",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype",
"name": "New Team Name"
},
"eventType": "teamRenamed",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_team_renamed
async def handle_team_renamed(ctx: ActivityContext[ConversationUpdateActivity]):
team_name = ctx.activity.channel_data.team.name
await ctx.send(f"The new team name is {team_name}")
チームが削除されました
チームが削除されると、エージェントは通知を受け取ります。 ボットは、channelData オブジェクト内に eventType.teamDeleted を含む conversationUpdate イベントを受信します。
次のコードは、チームが削除したイベントの例を示しています。
app.OnTeamDeleted(async context =>
{
// Handle delete event.
});
app.on('teamDeleted', async ({ activity }) => {
// Handle delete event.
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:35:56.825Z",
"localTimestamp": "2017-02-23T12:35:56.825-07:00",
"id": "f:1406033e",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype",
"name": "Team Name"
},
"eventType": "teamDeleted",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_team_deleted
async def handle_team_deleted(ctx: ActivityContext[ConversationUpdateActivity]):
# Handle delete event.
pass
復元されたチーム
エージェントは、削除後にチームが復元されたときに通知を受け取ります。 ボットは、channelData オブジェクト内に eventType.teamrestored を含む conversationUpdate イベントを受信します。
次のコードは、チームが復元したイベントの例を示しています。
app.OnTeamRestored(async context =>
{
var teamName = context.Activity.ChannelData.Team.Name;
await context.Send($"{teamName} is the team name");
});
app.on('teamRestored', async ({ activity, send }) => {
const teamName = activity.channelData.team.name;
await send(`${teamName} is the team name`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:35:56.825Z",
"localTimestamp": "2017-02-23T12:35:56.825-07:00",
"id": "f:1406033e",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype",
"name": "Team Name"
},
"eventType": "teamrestored",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_team_restored
async def handle_team_restored(ctx: ActivityContext[ConversationUpdateActivity]):
team_name = ctx.activity.channel_data.team.name
await ctx.send(f"The team name is {team_name}")
チームがアーカイブされました
チームがインストールおよびアーカイブされると、エージェントは通知を受け取ります。 ボットは、channelData オブジェクト内に eventType.teamarchived を含む conversationUpdate イベントを受信します。
次のコードは、チーム アーカイブ イベントの例を示しています。
app.OnTeamArchived(async context =>
{
var teamName = context.Activity.ChannelData.Team.Name;
await context.Send($"{teamName} is the team name");
});
app.on('teamArchived', async ({ activity, send }) => {
const teamName = activity.channelData.team.name;
await send(`${teamName} is the team name`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:35:56.825Z",
"localTimestamp": "2017-02-23T12:35:56.825-07:00",
"id": "f:1406033e",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype",
"name": "Team Name"
},
"eventType": "teamArchived",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_team_archived
async def handle_team_archived(ctx: ActivityContext[ConversationUpdateActivity]):
team_name = ctx.activity.channel_data.team.name
await ctx.send(f"The team name is {team_name}")
チームのアーカイブが解除されました
チームがインストールされ、アーカイブ解除されると、エージェントは通知を受け取ります。 ボットは、channelData オブジェクト内に eventType.teamUnarchived を含む conversationUpdate イベントを受信します。
次のコードは、チームのアーカイブされていないイベントの例を示しています。
app.OnTeamUnarchived(async context =>
{
var teamName = context.Activity.ChannelData.Team.Name;
await context.Send($"{teamName} is the team name");
});
app.on('teamUnarchived', async ({ activity, send }) => {
const teamName = activity.channelData.team.name;
await send(`${teamName} is the team name`);
});
{
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:35:56.825Z",
"localTimestamp": "2017-02-23T12:35:56.825-07:00",
"id": "f:1406033e",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype",
"name": "Team Name"
},
"eventType": "teamUnarchived",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
@app.on_team_unarchived
async def handle_team_unarchived(ctx: ActivityContext[ConversationUpdateActivity]):
team_name = ctx.activity.channel_data.team.name
await ctx.send(f"The team name is {team_name}")
会話更新イベントを操作したので、メッセージに対するさまざまなリアクションに対して発生するメッセージリアクション イベントを理解できます。
メッセージ リアクション イベント
messageReaction イベントは、ユーザーがエージェントによって送信されたメッセージに対するリアクションを追加または削除したときに送信されます。
replyToId にはメッセージの ID が、Type にはテキスト形式のリアクションの種類が含まれます。 リアクションの種類には、怒り、ハート、笑い、いいね!、悲しい、驚きなどがあります。 このイベントには、元のメッセージの内容は含まれません。 エージェントにとってメッセージに対する反応の処理が重要な場合は、メッセージを送信するときにメッセージを格納する必要があります。 次の表に、イベントの種類とペイロード オブジェクトの詳細を示します。
エージェント メッセージに追加されたリアクション
次のコードは、エージェント メッセージに対する反応の例を示しています。
app.OnReactionsAdded(async context =>
{
foreach (var reaction in context.Activity.ReactionsAdded)
{
var newReaction = $"You reacted with '{reaction.Type}' to the following message: '{context.Activity.ReplyToId}'";
await context.Send(newReaction);
}
});
app.on('reactionsAdded', async ({ activity, send }) => {
const reactionsAdded = activity.reactionsAdded;
if (reactionsAdded && reactionsAdded.length > 0) {
for (const reaction of reactionsAdded) {
const newReaction = `You reacted with '${reaction.type}' to the following message: '${activity.replyToId}'`;
await send(newReaction);
}
}
});
{
"reactionsAdded": [
{
"type": "like"
}
],
"type": "messageReaction",
"timestamp": "2017-10-16T18:45:41.943Z",
"id": "f:9f78d1f3",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA",
"aadObjectId": "c33aafc4-646d-4543-9d4c-abd28e4d2110"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"channel": {
"id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
},
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
},
"replyToId": "1575667808184",
"legacy": {
"replyToId": "1:19uJ8TZA1cZcms7-2HLOW3pWRF4nSWEoVnRqc0DPa_kY"
}
}
@app.on_reactions_added
async def handle_reactions_added(ctx: ActivityContext):
for reaction in ctx.activity.reactions_added:
await ctx.send(
f"You added '{reaction.type}' regarding message '{ctx.activity.reply_to_id}'"
)
エージェント メッセージから削除された反応
次のコードは、エージェント メッセージから削除されたリアクションの例を示しています。
app.OnReactionsRemoved(async context =>
{
foreach (var reaction in context.Activity.ReactionsRemoved)
{
var newReaction = $"You removed the reaction '{reaction.Type}' from the following message: '{context.Activity.ReplyToId}'";
await context.Send(newReaction);
}
});
app.on('reactionsRemoved', async ({ activity, send }) => {
const reactionsRemoved = activity.reactionsRemoved;
if (reactionsRemoved && reactionsRemoved.length > 0) {
for (const reaction of reactionsRemoved) {
const newReaction = `You removed the reaction '${reaction.type}' from the message: '${activity.replyToId}'`;
await send(newReaction);
}
}
});
{
"reactionsRemoved": [
{
"type": "like"
}
],
"type": "messageReaction",
"timestamp": "2017-10-16T18:45:41.943Z",
"id": "f:9f78d1f3",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA",
"aadObjectId": "c33aafc4-646d-4543-9d4c-abd28e4d2110"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterLocal"
},
"channelData": {
"channel": {
"id": "19:3629591d4b774aa08cb0887902eee7c1@thread.skype"
},
"team": {
"id": "19:efa9296d959346209fea44151c742e73@thread.skype"
},
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
},
"replyToId": "1575667808184",
"legacy": {
"replyToId": "1:19uJ8TZA1cZcms7-2HLOW3pWRF4nSWEoVnRqc0DPa_kY"
}
}
@app.on_reactions_removed
async def handle_reactions_removed(ctx: ActivityContext):
for reaction in ctx.activity.reactions_removed:
await ctx.send(
f"You removed '{reaction.type}' regarding message '{ctx.activity.reply_to_id}'"
)
インストール更新イベント
エージェントを会話スレッドにインストールすると、エージェントは installationUpdate イベントを受け取ります。 スレッドからエージェントをアンインストールすると、イベントもトリガーされます。 エージェントをインストールすると、イベントの アクション フィールドが 追加に設定され、エージェントがアンインストールされると 、アクション フィールドが 削除に設定されます。
注:
アプリケーションをアップグレードすると、エージェントはマニフェストにエージェントを追加または削除するためにのみ、 installationUpdate イベントを受け取ります。 その他のすべてのケースでは、 installationUpdate イベントはトリガーされません。 エージェントを追加する場合は アクション フィールドが add-upgrade に設定され、エージェントを削除した場合は remove-upgrade に設定されます。
更新イベントのインストール
installationUpdate イベントを使用して、インストール時にエージェントから入門メッセージを送信します。 このイベントは、プライバシーとデータ保持の要件を満たすのに役立ちます。 エージェントがアンインストールされたときに、ユーザーまたはスレッド のデータをクリーンして削除することもできます。
エージェントがチームに追加されたときに送信される conversationUpdate イベントと同様に、 installationUpdate イベントの conversation.id は、アプリのインストール中にユーザーが選択したチャネルの ID またはインストールが発生したチャネルに設定されます。 ID は、ユーザーがエージェントを操作する予定のチャネルを表し、ウェルカム メッセージを送信するときにエージェントが使用する必要があります。 General チャネルの ID が明示的に必要なシナリオでは、channelDataのteam.idから取得できます。
この例では、conversationUpdateアクティビティとinstallationUpdateアクティビティのconversation.idを、Daves Demo チームの応答チャネルの ID に設定します。
注:
選択したチャネル ID は、アプリがチームにインストールされたときに送信されるinstallationUpdate追加イベントにのみ設定されます。
app.OnInstall(async context =>
{
var action = context.Activity.Action;
if (string.Equals(action, "Add", StringComparison.InvariantCultureIgnoreCase))
{
await context.Send("Added");
}
else
{
await context.Send("Uninstalled");
}
});
イベントをキャプチャするための代替方法として、シナリオを追加または削除するための専用ハンドラーを使用することもできます。
protected override async Task OnInstallationUpdateAddAsync(IContext<IInstallationUpdateActivity> Context object, CancellationToken cancellationToken)
{
// TO:DO Installation workflow return;
}
app.on('install.add', async ({ send }) => {
await send('Added');
});
app.on('install.remove', async ({ send }) => {
await send('Uninstalled');
});
{
{
"type": "installationUpdate",
"id": "f:816eb23d-bfa1-afa3-dfeb-d2aa338e9541",
"timestamp": "2021-11-09T04:47:30.91Z",
"serviceUrl": "https://smba.trafficmanager.net/amer/",
"channelId": "msteams",
"from": {
"id": "29:1ljv6N86roXr5pjPrCJVIz6xHh5QxjI....",
"aadObjectId": "eddfa9d4-346e-4cce-a18f-fa6261ad776b"
},
"recipient": {
"id": "28:608cacfd-1cea-40c9-b678-4b93e69bb72b",
"name": "Test Agent"
},
"locale": "en-US",
"entities": [
{
"type": "clientInfo",
"locale": "en-US"
}
],
"conversation": {
"isGroup": true,
"id": "19:0b7f32667e064dd9b25d7969801541f4@thread.tacv2",
"name": "2021 Test Channel",
"conversationType": "channel",
"tenantId": "b28fdbfd-2b78-4f93-b0f8-8881793f0f8f"
},
"channelData": {
"settings": {
"selectedChannel": {
"id": "19:0b7f32667e064dd9b25d7969801541f4@thread.tacv2"
}
},
"channel": {
"id": "19:0b7f32667e064dd9b25d7969801541f4@thread.tacv2"
},
"team": {
"aadGroupId": "da849743-4259-475f-ae7a-4f4b0fb49943",
"name": "TestTeam2022",
"id": "19:zFLSDFWsesfzcmKArqKJ-65aOXJz@sgf462H2wz41@thread.tacv2"
},
"tenant": {
"id": "b28fdbfd-2b78-4f93-b0f8-8881793f0f8f"
},
"source": {
"name": "message"
}
},
"action": "add"
}
@app.on_install_add
async def handle_install_add(ctx: ActivityContext):
await ctx.send("Added")
@app.on_install_remove
async def handle_install_remove(ctx: ActivityContext):
await ctx.send("Uninstalled")
エージェントを使用した個人用アプリのアンインストール動作
アプリをアンインストールすると、エージェントもアンインストールされます。 ユーザーがアプリにメッセージを送信すると、403 応答コードが表示されます。 エージェントは、エージェントによって投稿された新しいメッセージの 403 応答コードを受け取ります。 Teams スコープと groupChat スコープを持つ個人用スコープ内のエージェントのアンインストール後の動作が調整されるようになりました。 アプリがアンインストールされた後は、メッセージを送受信できません。
インストールおよびアンインストール イベント向けのイベント ハンドリング
インストール イベントとアンインストール イベントを使用すると、次の場合に発生する Teams からの予期しないイベントの受信に対してエージェントが例外を与える場合があります。
- Teams SDK を使用せずにエージェントをビルドすると、その結果、エージェントは予期しないイベントを受信するときに例外を発生させます。
- Teams SDK を使用してエージェントをビルドし、基本イベント ハンドルをオーバーライドして既定のイベント動作を変更することを選択します。
今後いつでも新しいイベントを追加でき、エージェントが受信を開始できることを知っておくべきことが重要です。 そのため、予期しないイベントを受け取る可能性があることを想定して設計する必要があります。 Teams SDK を使用している場合、エージェントは、処理を選択しないイベントに 200 - OK で自動的に応答します。
会話イベントでのエラーの処理
エージェントがさまざまなイベントまたはアクティビティの処理中にエラーを検出した場合は、次のスクリーンショットに示すように、意味のあるコンテキストを持たないメッセージを会話に送信しないでください。
開発フェーズでは、メッセージ交換で意味のあるメッセージを送信すると常に役立ちます。これにより、デバッグを改善するために特定のエラーに関する詳細が提供されます。 ただし、運用環境では、エラーまたはイベントを Azure アプリケーション Insights にログに記録する必要があります。 詳細については、「 ボットにテレメトリを追加する」を参照してください。
コード サンプル
|
サンプルの名前 |
説明 |
.NET |
Node.js |
Python |
| 会話ボット |
このアプリは、ボットの会話イベントを示し、アダプティブ カード、開封確認、メッセージ更新イベントをサポートします。 これには、アクセシビリティに対するイマーシブ リーダーのサポートが含まれています。 |
表示 |
表示 |
表示 |
次の手順