重要
本部分中的代码示例基于 Bot Framework SDK 版本 4.6 和更高版本。 如果要查找早期版本的文档,请参阅文档的旧版 SDK 文件夹中的 机器人 - v3 SDK 部分。
机器人可以访问有关安装它的团队或聊天的其他上下文数据。 此信息可用于丰富机器人的功能并提供更个性化的体验。
提取名单或用户个人资料
机器人可以查询成员列表及其基本用户配置文件,包括 Teams 用户 ID 和Microsoft Entra信息,如名称和 objectId。 可以使用此信息来关联用户标识。 例如,若要检查通过Microsoft Entra凭据登录到选项卡的用户是否为团队成员。 对于获取对话成员,最小或最大页面大小取决于实现。 小于 50 的页面大小被视为 50,大于 500 的页面大小上限为 500。 即使使用非分页版本,它在大型团队中也不可靠,不得使用。 有关详细信息,请参阅 Teams 机器人 API 在提取团队或聊天成员方面的更改。
注意
- 分页在团队和频道中可用。
- 聊天中不支持分页。 对于聊天,始终返回整个名单。
以下示例代码使用分页终结点提取名单:
public class MyBot : TeamsActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var members = new List<TeamsChannelAccount>();
string continuationToken = null;
do
{
// Gets a paginated list of members of one-on-one, group, or team conversation.
var currentPage = await TeamsInfo.GetPagedMembersAsync(turnContext, 100, continuationToken, cancellationToken);
continuationToken = currentPage.ContinuationToken;
members.AddRange(currentPage.Members);
}
while (continuationToken != null);
}
}
export class MyBot extends TeamsActivityHandler {
constructor() {
super();
// See https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0 to learn more about the message and other activity types.
this.onMessage(async (turnContext, next) => {
var continuationToken;
var members = [];
do {
// Gets a paginated list of members of one-on-one, group, or team conversation.
var pagedMembers = await TeamsInfo.getPagedMembers(turnContext, 100, continuationToken);
continuationToken = pagedMembers.continuationToken;
members.push(...pagedMembers.members);
}
while(continuationToken !== undefined)
// By calling next() you ensure that the next BotHandler is run.
await next();
});
}
}
SDK 参考
async def _show_members(
self, turn_context: TurnContext
):
# Get a conversationMember from a team.
members = await TeamsInfo.get_team_members(turn_context)
可以使用 serviceUrl
的值作为终结点,直接在 /v3/conversations/{conversationId}/pagedmembers?pageSize={pageSize}&continuationToken={continuationToken}
上发出 GET 请求。
serviceUrl
的值稳定,但可能会更改。 当新消息到达时,机器人必须验证其存储的 serviceUrl
值。 响应有效负载还指示用户是常规用户还是匿名用户。
GET /v3/conversations/19:meeting_N2QzYTA3YmItYmMwOC00OTJmLThkYzMtZWMzZGU0NGIyZGI0@thread.v2/pagedmembers?pageSize=100&continuationToken=asdfasdfalkdsjfalksjdf
Response body
{
"continuationToken":"asdfqwerueiqpiewr",
"members":[
{
"id":"29:1GcS4EyB_oSI8A88XmWBN7NJFyMqe3QGnJdgLfFGkJnVelzRGos0bPbpsfJjcbAD22bmKc4GMbrY2g4JDrrA8vM06X1-cHHle4zOE6U4ttcc",
"name":"Anon1 (Guest)",
"tenantId":"29:1UX7p8Fkx7p93MZlBFS71swTB9juQOCfnXf2L3wxOUITCcIGpFcRX-JiFjLDVZhxGpEfzSTGNsZeEyTKr1iu3Vw",
"userRole":"anonymous"
},
{
"id":"29:1bSnHZ7Js2STWrgk6ScEErLk1Lp2zQuD5H2qQ960rtvstKp8tKLl-3r8b6DoW0QxZimuTxk_kupZ1DBMpvIQQUAZL-PNj0EORDvRZXy8kvWk",
"objectId":"76b0b09f-d410-48fd-993e-84da521a597b",
"givenName":"John",
"surname":"Patterson",
"email":"johnp@fabrikam.com",
"userPrincipalName":"johnp@fabrikam.com",
"tenantId":"29:1UX7p8Fkx7p93MZlBFS71swTB9juQOCfnXf2L3wxOUITCcIGpFcRX-JiFjLDVZhxGpEfzSTGNsZeEyTKr1iu3Vw",
"userRole":"user"
},
{
"id":"29:1URzNQM1x1PNMr1D7L5_lFe6qF6gEfAbkdG8_BUxOW2mTKryQqEZtBTqDt10-MghkzjYDuUj4KG6nvg5lFAyjOLiGJ4jzhb99WrnI7XKriCs",
"objectId":"6b7b3b2a-2c4b-4175-8582-41c9e685c1b5",
"givenName":"Rick",
"surname":"Stevens",
"email":"Rick.Stevens@fabrikam.com",
"userPrincipalName":"rstevens@fabrikam.com",
"tenantId":"29:1UX7p8Fkx7p93MZlBFS71swTB9juQOCfnXf2L3wxOUITCcIGpFcRX-JiFjLDVZhxGpEfzSTGNsZeEyTKr1iu3Vw",
"userRole":"user"
}
]
}
提取名单或用户个人资料后,可以获取单个成员的详细信息。 若要检索聊天或团队的一个或多个成员的信息,请使用适用于 C# 或 TeamsInfo.getMembers
TypeScript API TeamsInfo.GetMembersAsync
的 Microsoft Teams 机器人 API。
获取单个成员详细信息
还可以使用其 Teams 用户 ID、UPN 或Microsoft Entra对象 ID 检索特定用户的详细信息。
以下示例代码用于获取单个成员详细信息:
public class MyBot : TeamsActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// Gets the account of a single conversation member.
// This works in one-on-one, group, and team scoped conversations.
var member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);
}
}
export class MyBot extends TeamsActivityHandler {
constructor() {
super();
// See learn.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0 to learn more about the message and other activity types.
this.onMessage(async (turnContext, next) => {
const member = await TeamsInfo.getMember(turnContext, encodeURI('someone@somecompany.com'));
// By calling next() you ensure that the next BotHandler is run.
await next();
});
}
}
async def _show_members(
self, turn_context: TurnContext
):
# TeamsInfo.get_member: Gets the member of a team scoped conversation.
member = await TeamsInfo.get_member(turn_context, turn_context.activity.from_property.id)
可以使用 serviceUrl
的值作为终结点,直接在 /v3/conversations/{conversationId}/members/{userId}
上发出 GET 请求。
serviceUrl
的值稳定,但可能会更改。 当新消息到达时,机器人必须验证其存储的 serviceUrl
值。 这可用于常规用户和匿名用户。
下面是常规用户的响应示例:
GET /v3/conversations/19:ja0cu120i1jod12j@skype.net/members/29:1GcS4EyB_oSI8A88XmWBN7NJFyMqe3QGnJdgLfFGkJnVelzRGos0bPbpsfJjcbAD22bmKc4GMbrY2g4JDrrA8vM06X1-cHHle4zOE6U4ttcc
Response body
{
"id": "29:1GcS4EyB_oSI8A88XmWBN7NJFyMqe3QGnJdgLfFGkJnVelzRGos0bPbpsfJjcbAD22bmKc4GMbrY2g4JDrrA8vM06X1-cHHle4zOE6U4ttcc",
"objectId": "9d3e08f9-a7ae-43aa-a4d3-de3f319a8a9c",
"givenName": "Larry",
"surname": "Brown",
"email": "Larry.Brown@fabrikam.com",
"userPrincipalName": "labrown@fabrikam.com",
"tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47",
"userRole":"user"
}
下面是匿名用户的响应示例:
GET /v3/conversations/19:ja0cu120i1jod12j@skype.net/members/<anonymous user id>"
Response body
{
"id": "29:1GcS4EyB_oSI8A88XmWBN7NJFyMqe3QGnJdgLfFGkJnVelzRGos0bPbpsfJjcbAD22bmKc4GMbrY2g4JDrrA8vM06X1-cHHle4zOE6U4ttcc",
"name": "Anon1 (Guest)",
"tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47",
"userRole":"anonymous"
}
获取单个成员的详细信息后,可以获取团队的详细信息。 若要检索团队的信息,请使用适用于 C# 或 TeamsInfo.getTeamDetails
TypeScript 的 Teams 机器人 APITeamsInfo.GetMemberDetailsAsync
。
获取团队的详细信息
在团队中安装后,机器人可以查询有关该团队的元数据,包括Microsoft Entra组 ID。
以下示例代码用于获取团队的详细信息:
public class MyBot : TeamsActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// Gets the details for the given team id. This only works in team scoped conversations.
// TeamsGetTeamInfo: Gets the TeamsInfo object from the current activity.
TeamDetails teamDetails = await TeamsInfo.GetTeamDetailsAsync(turnContext, turnContext.Activity.TeamsGetTeamInfo().Id, cancellationToken);
if (teamDetails != null) {
await turnContext.SendActivityAsync($"The groupId is: {teamDetails.AadGroupId}");
}
else {
// Sends a message activity to the sender of the incoming activity.
await turnContext.SendActivityAsync($"Message did not come from a channel in a team.");
}
}
}
export class MyBot extends TeamsActivityHandler {
constructor() {
super();
// See https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0 to learn more about the message and other activity types.
this.onMessage(async (turnContext, next) => {
// Gets the details for the given team id.
const teamDetails = await TeamsInfo.getTeamDetails(turnContext);
if (teamDetails) {
// Sends a message activity to the sender of the incoming activity.
await turnContext.sendActivity(`The group ID is: ${teamDetails.aadGroupId}`);
} else {
await turnContext.sendActivity('This message did not come from a channel in a team.');
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
}
}
SDK 参考
async def _show_details(self, turn_context: TurnContext):
# Gets the details for the given team id.
team_details = await TeamsInfo.get_team_details(turn_context)
# MessageFactory.text(): Specifies the type of text data in a message attachment.
reply = MessageFactory.text(f"The team name is {team_details.name}. The team ID is {team_details.id}. The AADGroupID is {team_details.aad_group_id}.")
# Sends a message activity to the sender of the incoming activity.
await turn_context.send_activity(reply)
可以使用 serviceUrl
的值作为终结点,直接在 /v3/teams/{teamId}
上发出 GET 请求。
serviceUrl
的值稳定,但可能会更改。 当新消息到达时,机器人必须验证其存储的 serviceUrl
值。
GET /v3/teams/19:ja0cu120i1jod12j@skype.net
Response body
{
"id": "29:1GcS4EyB_oSI8A88XmWBN7NJFyMqe3QGnJdgLfFGkJnVelzRGos0bPbpsfJjcbAD22bmKc4GMbrY2g4JDrrA8vM06X1-cHHle4zOE6U4ttcc",
"name": "The Team Name",
"aadGroupId": "02ce3874-dd86-41ba-bddc-013f34019978"
}
获取团队的详细信息后,可以获取团队中的频道列表。 若要检索团队中频道列表的信息,请使用适用于 C# 或 TeamsInfo.getTeamChannels
TypeScript API TeamsInfo.GetTeamChannelsAsync
的 Teams 机器人 API。
获取团队中的频道列表
机器人可以查询团队中的频道列表。
注意
- 默认常规频道的名称作为
null
返回,以允许本地化。
- 常规频道的频道 ID 始终与团队 ID 匹配。
以下示例代码用于获取团队中的频道列表:
public class MyBot : TeamsActivityHandler
{
// Override this in a derived class to provide logic specific to Message activities.
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// Returns a list of channels in a Team. This only works in team scoped conversations.
IEnumerable<ChannelInfo> channels = await TeamsInfo.GetTeamChannelsAsync(turnContext, turnContext.Activity.TeamsGetTeamInfo().Id, cancellationToken);
// Sends a message activity to the sender of the incoming activity.
await turnContext.SendActivityAsync($"The channel count is: {channels.Count()}");
}
}
SDK 参考
export class MyBot extends TeamsActivityHandler {
constructor() {
super();
// See https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0 to learn more about the message and other activity types.
this.onMessage(async (turnContext, next) => {
// Supports retrieving channels hosted by a team.
const channels = await TeamsInfo.getTeamChannels(turnContext);
// Sends a message activity to the sender of the incoming activity.
await turnContext.sendActivity(`The channel count is: ${channels.length}`);
// By calling next() you ensure that the next BotHandler is run.
await next();
});
}
}
SDK 参考
async def _show_channels(
self, turn_context: TurnContext
):
# Supports retrieving channels hosted by a team.
channels = await TeamsInfo.get_team_channels(turn_context)
reply = MessageFactory.text(f"Total of {len(channels)} channels are currently in team")
await turn_context.send_activity(reply)
可以使用 serviceUrl
的值作为终结点,直接在 /v3/teams/{teamId}/conversations
上发出 GET 请求。
serviceUrl
的值稳定,但可能会更改。 当新消息到达时,机器人必须验证其存储的 serviceUrl
值。
GET /v3/teams/19%3A033451497ea84fcc83d17ed7fb08a1b6%40thread.skype/conversations
Response body
{
"conversations": [{
"id": "19:033451497ea84fcc83d17ed7fb08a1b6@thread.skype",
"name": null
}, {
"id": "19:cc25e4aae50746ecbb11473bba24c70a@thread.skype",
"name": "Materials"
}, {
"id": "19:b7b84cba410c406ba671dbbf5e0a3519@thread.skype",
"name": "Design"
}, {
"id": "19:fc5db2aed489454e8f8c06829ed6c986@thread.skype",
"name": "Marketing"
}]
}
代码示例
有关演示该功能的完整工作示例,请参阅 Bot Framework 的以下 Teams 示例:
示例名称 |
说明 |
.NET |
Node.js |
Python |
清单 |
Teams 对话自动程序 |
此应用演示机器人对话事件,支持自适应卡片、已读回执和消息更新事件。 它包括对辅助功能的沉浸式阅读器支持。 |
View |
View |
View |
View |
使用 OAuthPrompt 进行身份验证 |
此示例应用演示机器人如何使用 Teams 身份验证。 |
View |
View |
View |
View |
Teams 文件上传 |
此适用于 Teams 的机器人示例演示了使用 Bot Framework v4 的文件上传功能,使用户能够在聊天中上传文件和查看内联图像。 |
View |
View |
View |
View |
对话 (TeamsJS v1.x) 中称为任务模块 |
此示例应用演示如何使用 Bot Framework v4 (TeamsJS v1.x) 中称为任务模块的对话 |
View |
View |
View |
View |
在通道中启动新线程 |
此应用演示如何使用 Bot Framework v4 在特定 Teams 频道中启动对话线程。 |
View |
View |
View |
View |
Teams 应用本地化 |
此示例演示如何使用机器人和选项卡为Microsoft Teams 应用实现本地化。 |
View |
View |
不适用 |
View |
后续步骤
另请参阅