使用 Microsoft Graph 将第三方平台消息导入 Teams
借助 Microsoft Graph,可以将用户的现有消息历史记录和数据从外部系统迁移到 Teams 频道。 通过在 Teams 中重新创建第三方平台消息传送层次结构,用户可以无缝地继续其通信,并且不会中断。
注意
将来,Microsoft 可能要求你或你的客户根据导入的数据量支付其他费用。
导入概述
总体看来,导入过程包括以下步骤:
- 创建具有时间后退戳的团队 。
- 创建具有时间后退戳的频道 。
- 导入外部时间后退日期消息 。
- 完成团队和频道迁移过程 。
- 添加团队成员 。
先决条件
分析和准备消息数据
- 查看第三方数据以确定迁移的内容。
- 从第三方聊天系统中提取所选数据。
- 将第三方聊天结构映射到 Teams 结构。
- 将导入数据转换为迁移所需的格式。
设置 Microsoft 365 租户
- 确保导入数据存在Microsoft 365 租户。 有关为 Teams 设置 Microsoft 365 租户的详细信息,请参阅 准备 Microsoft 365 租户。
- 确保团队成员Microsoft Entra ID。 有关详细信息,请参阅 将新用户添加到 Microsoft Entra ID。
步骤 1:创建团队
由于正在迁移现有数据,因此,在迁移过程中保留原始消息时间戳和阻止消息传送活动是在 Teams 中重新创建用户现有消息流的关键。 实现方法如下所示:
使用团队资源
createdDateTime
属性创建一个具有后退时间戳的新团队 。 将新团队置于一种特殊状态migration mode
,在迁移过程完成之前限制用户参与团队中的大多数活动。 在 POST 请求中包含具有migration
值的teamCreationMode
实例属性,以显式标识要为迁移创建的新团队。
注意
字段 createdDateTime
仅针对迁移的团队或频道的实例进行填充。
权限
ScopeName | DisplayName | 说明 | 类型 | 管理员同意? | 涵盖的实体/API |
---|---|---|---|---|---|
Teamwork.Migrate.All |
管理迁移到 Microsoft Teams | 创建和管理用于迁移到 Teams 的资源。 | 仅限应用程序 | 是 | POST /teams |
请求(创建处于迁移状态的团队)
POST https://graph.microsoft.com/v1.0/teams
Content-Type: application/json
{
"@microsoft.graph.teamCreationMode": "migration",
"template@odata.bind": "https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
"displayName": "My Sample Team",
"description": "My Sample Team’s Description",
"createdDateTime": "2020-03-14T11:22:17.043Z"
}
响应
HTTP/1.1 202 Accepted
Location: /teams/{team-id}/operations/{operation-id}
Content-Location: /teams/{team-id}
错误消息
400 Bad Request
在以下场景下会收到错误消息:
- 如果已经针对将来设置
createdDateTime
。 - 如果正确指定了
createdDateTime
,但teamCreationMode
实例属性缺失或者被设置成了无效值。
步骤 2:创建频道
为导入的消息创建频道类似于创建团队场景:
使用频道资源
createdDateTime
属性创建具有后退时间戳的新频道 。 将新频道置于一种特殊状态migration mode
,在迁移过程完成之前限制用户在频道内进行大多数聊天活动。 在 POST 请求中包含具有migration
值的channelCreationMode
实例属性,以显式标识要为迁移创建的新团队。
权限
ScopeName | DisplayName | 说明 | 类型 | 管理员同意? | 涵盖的实体/API |
---|---|---|---|---|---|
Teamwork.Migrate.All |
管理迁移到 Microsoft Teams | 创建和管理用于迁移到 Teams 的资源。 | 仅限应用程序 | 是 | POST /teams |
请求(在迁移状态下创建频道)
POST https://graph.microsoft.com/v1.0/teams/{team-id}/channels
Content-Type: application/json
{
"@microsoft.graph.channelCreationMode": "migration",
"displayName": "Architecture Discussion",
"description": "This channel is where we debate all future architecture plans",
"membershipType": "standard",
"createdDateTime": "2020-03-14T11:22:17.047Z"
}
响应
HTTP/1.1 202 Accepted
{
"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#teams('team-id')/channels/$entity",
"id":"id-value",
"createdDateTime":null,
"displayName":"Architecture Discussion",
"description":"This channel is where we debate all future architecture plans",
"isFavoriteByDefault":null,
"email":null,
"webUrl":null,
"membershipType":null,
"moderationSettings":null
}
错误消息
400 Bad Request
在以下场景下会收到错误消息:
- 如果已经针对将来设置
createdDateTime
。 - 如果正确指定了
createdDateTime
,但channelCreationMode
实例属性缺失或者被设置成了无效值。
步骤 3:导入消息
创建团队和频道后,可以使用请求正文中的 和 from
键开始发送实时消息createdDateTime
。
注意
- 不支持使用早于消息线程
createdDateTime
的createdDateTime
导入的消息。 - 在同一线程的消息中,
createdDateTime
必须是唯一的。 -
createdDateTime
支持毫秒精度的时间戳。 例如,如果传入请求消息的createdDateTime
值设置为 2020-09-16T05:50:31.0025302Z,则在引入消息时,该值将转换为 2020-09-16T05:50:31.002Z。
请求(纯文本的 POST 消息)
POST https://graph.microsoft.com/v1.0/teams/team-id/channels/channel-id/messages
{
"createdDateTime":"2019-02-04T19:58:15.511Z",
"from":{
"user":{
"id":"id-value",
"displayName":"Joh Doe",
"userIdentityType":"aadUser"
}
},
"body":{
"contentType":"html",
"content":"Hello World"
}
}
响应
HTTP/1.1 200 OK
{
"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#teams('team-id')/channels('channel-id')/messages/$entity",
"id":"id-value",
"replyToId":null,
"etag":"id-value",
"messageType":"message",
"createdDateTime":"2019-02-04T19:58:15.58Z",
"lastModifiedDateTime":null,
"deleted":false,
"subject":null,
"summary":null,
"importance":"normal",
"locale":"en-us",
"policyViolation":null,
"from":{
"application":null,
"device":null,
"conversation":null,
"user":{
"id":"id-value",
"displayName":"Joh Doe",
"userIdentityType":"aadUser"
}
},
"body":{
"contentType":"html",
"content":"Hello World"
},
"attachments":[
],
"mentions":[
],
"reactions":[
]
}
错误消息
400 Bad Request
请求(使用内联图像发布消息)
注意
- 由于请求是
chatMessage
的一部分,因此在此场景中没有特殊的权限范围。 - 此处适用
chatMessage
的范围。
POST https://graph.microsoft.com/v1.0/teams/team-id/channels/channel-id/messages
{
"body": {
"contentType": "html",
"content": "<div><div>\n<div><span><img height=\"250\" src=\"../hostedContents/1/$value\" width=\"176.2295081967213\" style=\"vertical-align:bottom; width:176px; height:250px\"></span>\n\n</div>\n\n\n</div>\n</div>"
},
"hostedContents":[
{
"@microsoft.graph.temporaryId": "1",
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAANcAAAExCAYAAADvFzeeAAAXjklEQVR4Ae2d/XNU1RnH+9e0FFrA0RCIyaS8hRA0HV5KbS1gHRgVpjMClY4GHJ3yYm1HCmXaWttaaZUZtIIFKYi8lFAkvOQ9u5vN225IARVBbX9/Os9NbrLZbMjmhCfJPX5+2Lmb3T25y3O+n/M599x7w9f+++UXwoMakIF7n4GvUdR7X1RqSk01A8CFuZm5GGUAuIwKi72wF3ABF+YyygBwGRUWc2Eu4AIuzGWUAeAyKizmwlzABVyYyygDwGVUWMyFuYALuDCXUQaAy6iwmAtzARdwfWXMdeuzT+TGxz3Sfb1LunrapL07IW3pePDQ5/qavqef0c+OdYAELuAac4jGGkLL9rdvfyo9N9ODQAqBGmmrwGlb/R0u3xG4gMspOC5hG882CoRaaCSA8n1ff9doIQMu4PIOrus3u+8ZVNnw6e/Od5AALuDKOyz5hmqiPnfnzi1J9bSbgRWCpvvQfY307wQu4BoxJCOFaDK8rwsQmQsUIQhWW93XSIsewAVckYdLQ24F0Ui/926AARdwRRounZ6Np7GyYdN9DzdFBC7gijRc43GMlQ1U9s/6HXJNjYELuHI<<-----Removed----->>>>",
"contentType": "image/png"
}
]
}
响应
HTTP/1.1 200 OK
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#teams('team-id')/channels('channel-id')/messages/$entity",
"id": "id-value",
"replyToId": null,
"etag": "id-value",
"messageType": "message",
"createdDateTime": "2019-02-04T19:58:15.511Z",
"lastModifiedDateTime": null,
"deleted": false,
"subject": null,
"summary": null,
"importance": "normal",
"locale": "en-us",
"policyViolation": null,
"from": {
"application": null,
"device": null,
"conversation": null,
"user": {
"id": "id-value",
"displayName": "Joh Doe",
"userIdentityType": "aadUser"
}
},
"body": {
"contentType": "html",
"content": "<div><div>\n<div><span><img height=\"250\" src=\"https://graph.microsoft.com/teams/teamId/channels/channelId/messages/id-value/hostedContents/hostedContentId/$value\" width=\"176.2295081967213\" style=\"vertical-align:bottom; width:176px; height:250px\"></span>\n\n</div>\n\n\n</div>\n</div>"
},
"attachments": [],
"mentions": [],
"reactions": []
}
步骤 4:完成迁移模式
消息迁移过程完成后,团队和频道将使用 方法退出迁移模式 completeMigration
。 此步骤将打开团队和频道资源供团队成员常规使用。 该操作绑定到 team
实例。 在团队完成之前,必须在迁移模式之外完成所有频道。
请求(终端频道迁移模式)
POST https://graph.microsoft.com/v1.0/teams/team-id/channels/channel-id/completeMigration
响应
HTTP/1.1 204 NoContent
请求(终端团队迁移模式)
POST https://graph.microsoft.com/v1.0/teams/team-id/completeMigration
响应
HTTP/1.1 204 NoContent
调用不在 migrationMode
中的 team
或 channel
的操作。
步骤 5:添加团队成员
可以使用 Teams UI 或 Microsoft Graph 添加成员 API 将成员添加到团队:
请求(添加成员)
POST https://graph.microsoft.com/beta/teams/{team-id}/members
Content-type: application/json
Content-length: 30
{
"@odata.type": "#microsoft.graph.aadUserConversationMember",
"roles": [],
"user@odata.bind": "https://graph.microsoft.com/beta/users/{user-id}"
}
响应
HTTP/1.1 204 No Content
使用技巧和其他信息
发出
completeMigration
请求后,无法将更多消息导入团队。只有在
completeMigration
请求返回成功答复后,才能将团队成员添加到新团队。限制:消息以每个频道 5 RPS 的速度导入。
如果需要更正迁移结果,则必须删除团队,重复步骤以创建团队和频道,并重新迁移消息。
注意
内联映像是导入消息 API 架构支持的唯一媒体类型。
导入内容范围
下表提供了内容范围:
在范围内 | 范围外 |
---|---|
团队和频道消息 | 1:1 和群组聊天消息 |
原始消息的创建时间 | 专用频道 |
作为消息的一部分的内联图像 | 提及时 |
指向 SPO 或 OneDrive 中现有文件的链接 | 回应 |
带有富文本的消息 | 视频 |
消息回复链 | 公告 |
高吞吐量处理 | 代码段 |
贴纸 | |
表情符号 | |
报价单 | |
频道间交叉发布 | |
共享频道 |