使用 Microsoft Teams 导出 API 导出内容

Teams 导出 API 允许从 Microsoft Teams 导出 1:1、群组聊天、会议聊天和频道消息。 如果你的组织需要导出 Microsoft Teams 消息,你可以使用 Teams 导出 API 提取它们。 聊天消息 表示 频道 或聊天中的单个 聊天消息。 聊天消息可以是根聊天消息,也可以是聊天消息中的 replyToId 属性定义的回复线程的一部分。

下面是有关如何使用这些导出 API 的一些示例:

  • 示例 1:如果你已在组织中启用 Microsoft Teams,并且希望通过传递给定用户或团队的日期范围,以编程方式将所有 Microsoft Teams 消息导出到日期。

  • 示例 2:如果要通过提供日期范围,以编程方式每天导出所有用户或团队消息。 导出 API 可以检索在给定日期范围内创建或更新的所有消息。

  • (Beta) 示例 3:如果要以编程方式导出到给定会议组织者的 Teams 会议录制的链接,然后下载实际录制内容。

  • (Beta) 示例 4:如果要以编程方式导出到给定会议组织者的 Teams 会议脚本的链接,然后下载实际脚本。

Teams 导出 API 支持哪些内容?

  • 批量导出 Teams 消息: Teams 导出 API 支持每个租户每个应用最多 200 RPS,应用程序最多支持 600 RPS,在这些限制下,你应该能够批量导出 Teams 消息。

  • 应用程序上下文:若要调用 Microsoft Graph,应用必须从Microsoft 标识平台获取访问令牌。 访问令牌包含有关你的应用的信息,以及它对通过 Microsoft Graph 可用的资源和 API 拥有的权限。 若要获取访问令牌,你的应用必须注册到 Microsoft 标识平台,并经用户或管理员授权才能访问所需的 Microsoft Graph 资源。

    如果你已经熟悉将应用与Microsoft 标识平台集成以获取令牌,请参阅后续步骤部分,了解特定于 Microsoft Graph 的信息和示例。

  • 混合环境: 导出 API 支持在混合环境 (本地 Exchange 和 Teams) 上预配的用户发送的消息。 配置混合环境的用户发送的任何消息都可以使用导出 API 进行访问。

  • 用户删除的邮件: 用户从 Teams 客户端中删除的消息可以使用导出 API 进行访问,从删除时间起最多 21 天。

  • 邮件附件: 导出 API 包括作为邮件的一部分发送的附件的链接。 使用导出 API 可以检索消息中附加的文件。

  • 反应: 导出 API 支持用户对 Teams 消息发起的反应。 目前支持的反应是心,愤怒,喜欢,悲伤,惊讶和笑。 除了反应,导出 API 还支持反应编辑历史记录,其中包括对消息的反应所做的更改和更新。

  • 共享通道消息: 支持从共享频道捕获消息的导出 API。

  • 已删除的 Teams: 导出 API 支持 从已删除的 Teams 和已删除的标准、专用和共享频道捕获消息。

  • 聊天消息属性: 请参阅 Teams 导出 API 支持的属性的完整列表

  • 控制消息: 导出 API 除了支持捕获用户生成的消息外,还支持捕获控制消息。 控制消息是系统生成的消息,显示在 Teams 客户端上,并带有重要信息,例如“用户 A 已将用户 B 添加到聊天并共享所有聊天历史记录”以及时间戳。 系统消息使调用方能够深入了解团队、频道或聊天中发生的事件。 目前,导出 API 支持 聊天、团队和标准频道的“添加成员”和“删除成员”事件

Teams 导出 API 不支持哪些内容?

  • Teams Copilot 交互 & Microsoft 365 Chat:导出 API 不支持用户连接到机器人发送的 Copilot 交互消息和 Microsoft 365 聊天消息。

如何访问 Teams 导出 API

  • 示例 1 是一个简单的查询,用于检索不带任何筛选器的用户或团队的所有消息:

    GET https://graph.microsoft.com/v1.0/users/{id}/chats/getAllMessages
    
    GET https://graph.microsoft.com/v1.0/teams/{id}/channels/getAllMessages
    
  • 示例 2 是一个示例查询,用于通过指定日期时间筛选器和前 50 条消息来检索用户或团队的所有消息:

    GET https://graph.microsoft.com/v1.0/users/{id}/chats/getAllMessages?$top=50&$filter=lastModifiedDateTime gt 2020-06-04T18:03:11.591Z and lastModifiedDateTime lt 2020-06-05T21:00:09.413Z
    
    GET https://graph.microsoft.com/v1.0/teams/{id}/channels/getAllMessages?$top=50&$filter=lastModifiedDateTime gt 2020-06-04T18:03:11.591Z and lastModifiedDateTime lt 2020-06-05T21:00:09.413Z
    
  • (Beta) 示例 3 是一个示例查询,用于检索指向用户所有可用 Teams 会议录制内容的链接。 支持 TOP n 筛选器,类似于聊天消息:

    GET https://graph.microsoft.com/beta/users/{id}/onlineMeetings/getAllRecordings?$filter=MeetingOrganizerId eq ‘{id}’
    
  • (Beta) 示例 4 是一个示例查询,用于检索指向用户所有可用 Teams 会议脚本的链接。 支持 TOP n 筛选器,类似于聊天消息:

    GET https://graph.microsoft.com/beta/users/{id}/onlineMeetings/getAllTranscripts?$filter=MeetingOrganizerId eq ‘{id}’
    

注意

如果有多个结果,API 将返回包含下一页链接的响应。 若要获取下一组结果,只需从 @odata.nextlink调用 URL 上的 GET。 如果 @odata.nextlink 不存在或为 null,则检索所有消息。

访问 Teams 导出 API 的先决条件

  • Microsoft Graph 中访问敏感数据的 Microsoft Teams API 被视为受保护的 API。 只要满足 在没有用户的情况下访问 的要求,就可以调用这些 API。

  • 应用程序权限由运行且没有登录用户的应用使用;应用程序权限只能由管理员批准。 需要以下权限:

    • Chat.Read.All:允许访问所有 1:1、群组聊天和会议聊天消息

    • ChannelMessage.Read.All:允许访问所有通道消息

    • User.Read.All:允许访问租户的用户列表

    • OnlineMeetingTranscript.Read.All:允许访问所有 1:n 计划的 Teams 会议的脚本

    • OnlineMeetingRecording.Read.All:允许访问所有 1:n 计划的 Teams 会议的录制内容

Teams 导出 API 的许可证要求

导出 API 通过模型查询参数支持安全性和合规性 (S+C) 和常规使用方案。 S+C 方案 (模型 A) 包括种子设定容量,需要 E5 订阅和常规使用方案 (模型 B) 可用于所有订阅,并且仅供使用。 有关种子容量和消耗费用的详细信息,请参阅 Microsoft Graph Teams API 的许可和付款要求

对于 Beta API,目前没有模型 A 或模型 B 许可或使用强制措施。 但是,将来可能会发生更改。

S+C/模型 A 方案

仅限于执行安全性和/或合规性功能的应用程序,用户必须具有特定的 E5 许可证才能使用此功能并接收种子容量。 种子设定容量按用户计算,每月计算,并在租户级别聚合。 对于超出种子容量的使用量,应用所有者将按 API 使用量计费。 模型 A 只能访问来自已分配 E5 许可证的用户的消息。

合作伙伴名称 合作伙伴解决方案
logo-of-smarsh Microsoft Teams 存档和合规性
Proofpoint 徽标的屏幕截图。 Microsoft Teams 的 Proofpoint 内容捕获

常规用法/模型 B 方案

适用于所有非 S+C 相关方案,没有许可证要求或种子设定的容量。 当消耗计量可用时,应用所有者将对所有每月 API 调用付费。

以下合作伙伴已经过认证。 你的公司可以选择与企业中的这些合作伙伴的任意组合合作。

合作伙伴名称 合作伙伴解决方案
logo-of-rubrik Microsoft Teams 备份和恢复
logo-of-veeam Microsoft Teams 备份和恢复

后续步骤

如果你是寻求加入认证计划的供应商,请填写 此表单 作为下一步。 如果需要提供其他上下文和详细信息,请邮寄给 MS Teams 生态系统团队 (TeamsCategoryPartner@microsoft.com) 。

评估模式 (默认)

对于评估目的,没有模型声明允许访问每个请求应用程序使用受限的 API。

JSON 表示形式

  1. 以下示例是聊天资源的 JSON 表示形式:

    命名空间:microsoft.graph

    {
     "id": "string (identifier)",
     "replyToId": "string (identifier)",
     "from": {"@odata.type": "microsoft.graph.identitySet"},
     "etag": "string",
     "messageType": "string",
     "createdDateTime": "string (timestamp)",
     "lastModifiedDateTime": "string (timestamp)",
     "deletedDateTime": "string (timestamp)",
     "subject": "string",
     "from": {
                 "application": null,
                 "device": null,
                 "conversation": null,
                 "user": {
    
                     "id": \[{"@odata.type": "microsoft.graph.user"}\],
                     "displayName": "User Name",
    
                     "userIdentityType": "aadUser"                }
             },
     "body": {"@odata.type": "microsoft.graph.itemBody"},
     "summary": "string",
    
     "chatId": \[{"@odata.type": "microsoft.graph.chat"}\]
    
     "attachments": \[{"@odata.type": "microsoft.graph.chatMessageAttachment"}\],
     "mentions": \[{"@odata.type": "microsoft.graph.chatMessageMention"}\],
     "importance": "string",
     "locale": "string",
     }
    

    注意

    有关 chatMessage 资源的详细信息,请参阅 chatMessage 资源类型 一文。

  2. 以下示例是记录资源的 JSON 表示形式:

    命名空间:microsoft.graph

    {
     "@odata.context": "https://graph.microsoft.com/beta/$metadata#Collection(meetingRecording)", 
     "@odata.count": 2, 
     "@odata.nextLink": "https://graph.microsoft.com/beta/users('{userId}')/onlineMeetings/getAllRecordings?$filter=MeetingOrganizerId+eq+%27{userId}%27&$skiptoken=MSMjMCMjTkNaYVNIQjVVbXRPYWxaV1dscGFWVGg1V2pOb1IxUXpRWGxrUm1oTFVrWmtTV1ZyYkhwUlZVWm9UMWR3VEdWWGRFTlJWVVpDVVZFOVBRPT0%3d", 
     "value":
       [ 
         { 
          "@odata.type": "#microsoft.graph.meetingRecording", 
          "id": "6263af16-b660-41d0-a17b-83fbd15a39c7", 
          "meetingId": "MSoxMjczYTAxNi0yMDFkRLTmOTUtODA5My0xYjdmOTliM2VkZWIqMCoqMTk6bWVldGluZ19aR1F3WTJZNE9XTXROekppWlMwME1XWTRMVGc0TWpBdE1BBXdOV1kzWlRsak9UTXlAdGhyZWFkLnYy", 
          "meetingOrganizerId": "{userId}", 
          "createdDateTime": "2022-08-03T20:43:36.2573447Z", 
          "recordingContentUrl":    "https://graph.microsoft.com/beta/users/{userId}/onlineMeetings/MSoxMjczYTAxNi0yMDFkLTRmOTUtODA4My0xYjdmOTliM2VkZWIqMCoqMTk6bWVldGluZ19aR1F3WTJZNE9XTXROekppWlMwME1XWTRMVGc0TWpBdE1ERXdOV1kzWlRsak9UTXlAdGhyZWFkLnYy/recordings/MSMjMCMjMGFjNmUwZTgtYmZjYy00NDQxLTk2MGYtZjllNjVhNjI0NzBh/content" 
         }, 
         { 
          "@odata.type": "#microsoft.graph.meetingRecording", 
          "id": "{recordingId}", 
          "meetingId": "{meetingId}", 
          "meetingOrganizerId": "{userId}", 
          "createdDateTime": "2022-08-03T20:44:11.2635254Z", 
          "recordingContentUrl": " https://graph.microsoft.com/beta/users/{userId}/onlineMeetings/{meetingId}/recordings/{recordingId}/content" 
          },
        ] 
       }
    

    其中:

    • <id> 表示单个录制。

    • <meetingId> 表示会议或呼叫标识符。

    • <meetingOrganizerId> 表示会议的组织者。

    • <createdDateTime> 指示会议的开始时间。

    • <recordingContentUrl> value 指示录制内容的 URL。

    • 录制内容采用 MP4 格式。

    • 录制内容本身的平均大小在磁盘上约为 350 MB,具体取决于我们在 30 分钟到 60 分钟范围内的会议的平均大小。

    • 结果不一定按 createdDateTime排序。 但是,如果单个会议存在多个录制内容,则它们将共享相同的 meetingId 值。 此外,针对有问题的会议,对多个录制的条目进行正确排序。

    • 只有在关联的会议录制可用后,才能保证结果出现。 换句话说,调用方不需要额外的可用性轮询。

    • 根据 Teams 导出 API 中的当前模式,将支持对结果进行分页。 通过响应中存在 @oData.nextLink 属性,将支持分页。 nextLink 属性包含一个 skipToken 值,如下所示。 如果不存在 skipToken ,则表示当前批中没有其他要检索的结果:

      请求 响应 @nextLink 备注
      /getAllRecordings 计数:10 ?skipToken=ABC 初始请求不带 skipToken
      /getAllRecordings?skipToken=ABC 计数:10 ?skipToken=DEF SkipToken 返回,请求获取下一页
      /getAllRecordings?skipToken=DEF 计数:7 没有 skipToken,不再有可用数据
    • $top 根据 Teams 导出 API 中的当前模式,也支持参数。

    • DeltaToken 支持更改跟踪和同步方案。 有关现有增量查询的概述和示例,请参阅 使用增量查询跟踪 Microsoft Graph 数据中的更改。

    • 以下 API 可用于获取所选 userIdmeetingIdrecordingId 在 GET getAllRecordings API 的响应中获取的实际录制内容。 它返回录制的内容:

    GET users('{userId}')/onlineMeetings('{meetingId}')/recordings('{recordingId}')/content 
    
  3. 以下示例是脚本资源的 JSON 表示形式:

    命名空间:microsoft.graph

    {
      "@odata.context": "https://graph.microsoft.com/beta/$metadata#Collection(callTranscript)",  
      "@odata.count": 2, 
      "@odata.nextLink": "https://graph.microsoft.com/beta/users('{userId}')/onlineMeetings/getAllTranscripts?$filter=MeetingOrganizerId+eq+%27{userId}%27&$skiptoken=MSMjMCMjTkNaYVNIQjVVbXRPYWxaV1dscGFWVGg1V2pOb1IxUXpRWGxrUm1oTFVrWmtTV1ZyYkhwUlZVWm9UMWR3VEdWWGRFTlJWVVpDVVZFOVBRPT0%3d",  
      "value":
        [ 
          { 
           "@odata.type": "#microsoft.graph.callTranscript", 
           "id": "MSMjMCMjMGFjNmUwZTgtYmZjYy00NDQxLTk2MGYtZjllNjVhNjI0NzBh", 
           "meetingId": "MSoxMjczYTAxNi0yMDFkLTRmOTUtODA4My0xYjdmOTliM2VkZWIqMCoqMTk6bWVldGluZ19aR1F3WTJZNE9XTXROekppWlMwME1XWTRMVGc0TWpBdE1ERXdOV1kzWlRsak9UTXlAdGhyZWFkLnYy", 
           "meetingOrganizerId": "{userId}", 
           "transcriptContentUrl": "https://graph.microsoft.com/beta/users/{userId}/onlineMeetings/MSoxMjczYTAxNi0yMDFkLTRmOTUtODA4My0xYjdmOTliM2VkZWIqMCoqMTk6bWVldGluZ19aR1F3WTJZNE9XTXROekppWlMwME1XWTRMVGc0TWpBdE1ERXdOV1kzWlRsak9UTXlAdGhyZWFkLnYy/transcripts/MSMjMCMjMGFjNmUwZTgtYmZjYy00NDQxLTk2MGYtZjllNjVhNjI0NzBh/content", 
          "createdDateTime": "2022-08-03T20:43:36.6248355Z" 
          }, 
          { 
           "@odata.type": "#microsoft.graph.callTranscript", 
           "id": "{transcriptId}", 
           "meetingId": "{meetingId}", 
           "meetingOrganizerId": "{userId}", 
           "transcriptContentUrl": "https://graph.microsoft.com/beta/users/{userId}/onlineMeetings/{meetingId}/transcripts/{transcriptId}/content",   
           },
         ] 
        }
    

    其中:

    • <id> 表示单个录制。

    • <meetingId> 表示会议或呼叫标识符。

    • <meetingOrganizerId> 表示会议的组织者。

    • <createdDateTime> 指示会议的开始时间。

    • <transcriptContentUrl> value 指示脚本内容的 URL。

    • 默认情况下,脚本内容将采用 VTT 格式。 但是,使用 Accept 标头值 application/vnd.openxmlformats-officedocument.wordprocessingml.document,也可以获取 DOCX 格式。

    • JSON/VTT 格式的脚本内容本身的平均大小约为 300 KB,具体取决于我们在 30 分钟到 60 分钟范围内的会议的平均大小。

    • 结果不保证按 createdDateTime排序。 但是,如果单个会议存在多个录制内容,则它们将共享相同的 meetingId 值。 此外,将为有问题的会议正确排序多个录制的条目。

    • 只有在关联的会议录制可用后,才能保证结果出现。 换句话说,调用方不需要额外的可用性轮询。

    • 根据 Teams 导出 API 中的当前模式,将支持对结果进行分页。 通过响应中存在 @oData.nextLink 属性,将支持分页。 属性 nextLink 将包含一个 skipToken 值,如下所示。 如果不存在 skipToken ,则表示当前批中没有其他要检索的结果:

      请求 响应 @nextLink 备注
      /getAllTranscripts 计数:10 ?skipToken=ABC 初始请求不带 skipToken
      /getAllTranscripts?skipToken=ABC 计数:10 ?skipToken=DEF SkipToken 返回,请求获取下一页
      /getAllTranscripts?skipToken=DEF 计数:7 没有 skipToken,不再有可用数据
    • $top 根据 Teams 导出 API 中的当前模式,也支持参数。

    • DeltaToken 支持更改跟踪和同步方案。 有关现有增量查询的概述和示例,请参阅 使用增量查询跟踪 Microsoft Graph 数据中的更改

    • 以下 API 可用于获取在 GET get getAllTranscripts API 的响应中获取的所选 userId、meetingId 和 transcriptId 的实际脚本内容。 它返回录制的内容。

    GET users('{userId}')/onlineMeetings('{meetingId}')/transcripts('{transcriptId}')/content
    

有关详细信息,请参阅 使用 Graph API 提取脚本

导出 API 筛选器

在 Teams Graph 服务上托管的导出 API 使用 users/{userId}/chats/getAllMessages从 Substrate 用户邮箱获取所有用户消息。 导出 API 为聊天线程中的所有用户调用 API 时,会检索用户的已发送和接收消息,这会导致导出重复消息。

导出 API 具有筛选器参数,可帮助优化为聊天线程返回的消息。 API GET 支持新的筛选器参数,这些参数允许根据发送的用户、机器人、应用程序和系统事件消息提取消息。 filter 参数支持由以下项发送的消息:

  • 用户 (同一请求中支持的多个用户 ID)

  • 应用程序 (机器人、连接器等 )

  • 匿名用户

  • 联合用户 (外部访问用户)

  • 系统事件消息 (控制消息)

这些参数是请求 的一 $filter部分。 如果请求中没有这些参数,则将返回来自指定用户聊天中的所有用户的消息。

支持的筛选方案如下所示:

$filter=from/application/applicationIdentityType eq '<appType>' (bots/tenantBots/connectors, etc.)  
  
$filter=from/user/id eq '<oid>' (any number of id filters)  
  
$filter=from/user/userIdentityType eq 'anonymousGuest'  
  
$filter=from/user/userIdentityType eq 'federatedUser' (guest/external)  
  
$filter=from/application/applicationIdentityType eq '<appType>' or from/user/id eq '<oid>' (sent by app or userid)  
  
$filter=from/application/applicationIdentityType eq '<appType>' or from/user/userIdentityType eq 'anonymousGuest' (sent by app or anonymous)  

$filter=from/application/applicationIdentityType eq '<appType>' or from/user/userIdentityType eq 'federatedUser' (sent by app or federated)  
  
$filter=from/application/applicationIdentityType eq '<appType>' or from/user/userIdentityType eq 'anonymousGuest' or from/user/userIdentityType eq 'federatedUser' (sent by app, anonymous or federated)  
  
$filter=from/user/id eq '<oid>' or from/user/userIdentityType eq 'anonymousGuest' (sent by any number of userid or anonymous)  
  
$filter=from/user/id eq '<oid>' or from/user/userIdentityType eq 'federatedUser' (sent by any number of userid or federated)  

$filter=from/application/applicationIdentityType eq '<appType>' or from/user/id eq '<oid>' or from/user/userIdentityType eq 'anonymousGuest' or from/user/userIdentityType eq 'federatedUser' (sent by any number of userid or federated or anonymous)
 
$filter=from/application/applicationIdentityType eq '<appType>' or from/user/id eq '<oid>' or from/user/userIdentityType eq 'anonymousGuest' or from/user/userIdentityType eq 'federatedUser' (sent by any number of userid or federated or anonymous) or messsageType eq 'systemEventMessage'

(<any of the previous filters>) and (lastModifiedDateTime+gt+<date>+and+lastModifiedDateTime+lt+<date>)  
  • 如果 from/user/id eq ‘{oid}’ 存在,则查询将返回指定用户发送的消息。

  • 如果 from/user/userIdentityType eq ‘federatedUser’ 存在,则查询将返回属于用户聊天的联合用户发送的消息。

  • 如果 from/application/applicationIdenitytyType eq '{appType}' 存在,则查询将返回由指定的应用程序类型发送的消息。

  • 如果 messageType eq 'systemEventMessage' 存在,则查询返回系统发送的消息

这些参数可以使用 OR 运算符在它们之间组合,也可以通过将 与 参数组合在一起 lastModifiedDateTime$filter