Skip to the content.

如何获取 Teams Meeting 的上下文信息

我们上一篇文章讲了如果使用 net6 和 c# 来快速开发一个最简单的 teams meeting app。为了让大家比较容易理解,上个sample非常简单,简单到没有什么功能,那我们现在就来慢慢扩展这个app的功能:看看如何获取 meeting 的上下文。

打开上个sample中的 MainPage.cshtml 文件,使用如下代码:

@page "/MainPage"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo</title>
    <link rel="stylesheet" href="/static/styles.css">
    <script src="https://statics.teams.cdn.office.net/sdk/v1.10.0/js/MicrosoftTeams.min.js"
            integrity="sha384-6oUzHUqESdbT3hNPDDZUa/OunUj5SoxuMXNek1Dwe6AmChzqc6EJhjVrJ93DY/Bv"
            crossorigin="anonymous"></script>
</head>
<body>
    <h1>MainPage</h1>
    <div id="meeting-context"></h1>
    <script>
        microsoftTeams.initialize();
        microsoftTeams.getContext(function(context) {
            document.getElementById('meeting-context').innerText = JSON.stringify(context);
        });
    </script>
</body>
</html>

这段代码比较简单,首先加入了对 teams js sdk 的引用,版本为 1.10.0,然后调用了下面这个方法:

microsoftTeams.initialize();

这个是对sdk的初始化,由于我们这个页面是会嵌入到 teams 会议中的,所以 MainPage 页面需要和 Teams客户端本身建立一种联系。这个是一个必要步骤,如果不做这个,其他大多数函数都会失败。

然后我们就调用了 microsoftTeams.getContext(function(context) { ... });,这就是用来获取会议上下文的 api。在sdk里,这个方法的定义如下。https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8bd26b379caa1f82a24aa1bb768d92fe9f30950b/types/microsoftteams/index.d.ts

function getContext(callback: (context: Context) => void): void;

interface Context {
    groupId?: string | undefined;
    teamId?: string | undefined;
    teamName?: string | undefined;
    channelId?: string | undefined;
    channelName?: string | undefined;
    channelType?: ChannelType | undefined;
    entityId: string;
    subEntityId?: string | undefined;
    locale: string;
    osLocaleInfo?: LocaleInfo | undefined;
    upn?: string | undefined;
    tid?: string | undefined;
    theme?: string | undefined;
    isFullScreen?: boolean | undefined;
    teamType?: TeamType | undefined;
    teamSiteUrl?: string | undefined;
    teamSiteDomain?: string | undefined;
    teamSitePath?: string | undefined;
    hostTeamTenantId?: string | undefined;
    hostTeamGroupId?: string | undefined;
    channelRelativeUrl?: string | undefined;
    sessionId?: string | undefined;
    userTeamRole?: UserTeamRole | undefined;
    chatId?: string | undefined;
    loginHint?: string | undefined;
    userPrincipalName?: string | undefined;
    userObjectId?: string | undefined;
    isTeamArchived?: boolean | undefined;
    hostClientType?: HostClientType | undefined;
    frameContext?: FrameContexts | undefined;
    sharepoint?: any;
    tenantSKU?: string | undefined;
    userLicenseType?: string | undefined;
    parentMessageId?: string | undefined;
    ringId?: string | undefined;
    appSessionId?: string | undefined;
    isCallingAllowed?: boolean | undefined;
    isPSTNCallingAllowed?: boolean | undefined;
    meetingId?: string | undefined;
    defaultOneNoteSectionId?: string | undefined;
    isMultiWindow?: boolean | undefined;
    appIconPosition?: number | undefined;
    sourceOrigin?: string | undefined;
    userClickTime?: number | undefined;
    teamTemplateId?: string | undefined;
    userFileOpenPreference?: FileOpenPreference | undefined;
}

可以看到 Context 是一个有非常多属性的结构,我们不展开,我们先来看一下安装后我们得到的 context是什么,在我们上面的代码里,我们把拿到的 context 序列化成 json,然后打印在页面上。

我们安装 app 到一个会议中,然后就可以看到页面上显示了 context 的json数据。

get-context

我们来看一下这个json里含了什么有用的信息:

{
	"locale": "en-us",
	"theme": "default",
	"entityId": null,
	"subEntityId": "",
	"isFullScreen": false,
	"sessionId": "91291367-f8f0-9a5e-d420-490d4eb8bc8d",
	"chatId": "19:meeting_ODA1MjIzYzAtODNhYy00MjE0LWFmZmQtN2MxMTQ0ODdlMWQ2@thread.v2",
	"meetingId": "MCMxOTptZWV0aW5nX09EQTFNakl6WXpBdE9ETmhZeTAwTWpFMExXRm1abVF0TjJNeE1UUTBPRGRsTVdRMkB0aHJlYWQudjIjMA==",
	"parentMessageId": "",
	"hostClientType": "desktop",
	"tenantSKU": "enterprise",
	"jsonTabUrl": "microsoft-teams-json-tab.azurewebsites.net",
	"userLicenseType": "Unknown",
	"appSessionId": "1be21c3a-e846-4bf8-90e3-dc3b01938d39",
	"appLaunchId": "d30e788c-d424-40f5-9373-236345d64249",
	"isMultiWindow": false,
	"appIconPosition": 23,
	"userClickTime": 1640572621827,
	"sourceOrigin": null,
	"userFileOpenPreference": "inline",
	"osLocaleInfo": {
		"platform": "windows",
		"regionalFormat": "en-us",
		"longDate": "dddd, MMMM d, yyyy",
		"shortDate": "M/d/yyyy",
		"longTime": "h:mm:ss tt",
		"shortTime": "h:mm tt"
	},
	"frameContext": "content",
	"teamSiteDomain": "aabbcc365.sharepoint.com",
	"teamSitePath": "",
	"teamSiteUrl": "",
	"ringId": "general",
	"tid": "53213f63-c1e6-4416-bdab-da54fcb7b4b7",
	"loginHint": "admin@aabbcc365.onmicrosoft.com",
	"upn": "admin@aabbcc365.onmicrosoft.com",
	"userPrincipalName": "admin@aabbcc365.onmicrosoft.com",
	"userObjectId": "488e5982-c57c-4373-a4dd-67eab506d98d"
}

有这么一些信息我觉得比较有用:

  • locale 当前 Teams 客户端的语言
  • theme 当前 Teams 客户端的主题,比如是不是暗色主题,或者是高对比度主题
  • meetingId 当前会议的唯一id
  • hostClientType 当前 Teams 客户端的类型
    enum HostClientType {
      desktop = "desktop",
      web = "web",
      android = "android",
      ios = "ios",
      rigel = "rigel",
      surfaceHub = "surfaceHub"
    }
    
  • osLocaleInfo 当前 Teams 客户端的文化信息,比如日期格式之类的
  • tid 当前租户的id
  • userPrincipalName 用户名
  • userObjectId 当前用户的 Azure AD里的Object ID

我们有了这些信息后(特别是meeting id),后面很多 api 就比较容易调用了,我们将在后面的文章里再具体展开。

Written on December 27, 2021