概述
这篇文章将提供有关从 VCaaS 会议中推送的所有 Webhooks 和数据的概述。它包括两个部分:会议结束后的会议数据推送和实时数据推送。
会议结束后的会议数据推送
说明
会议结束后,会产生相应的会议时长、与会者考勤、会议录像(会议过程中开启录像)以及会议过程中的 POLL、QUIZ 记录等数据。 VCaaS 平台提供主动推送和查询会议数据接口两种方式获取会议数据。VCaaS 平台提供的会议时长和与会者考勤数据是基于客户端连接事件产生,可能出现事件延时。
- 创建会议时,可以通过请求参数中的 callbackUrl 字段指定接收会议数据的回调地址。若未设置该参数,则 VCaaS 平台不会主动推送会议数据,用户可以通过查询会议数据接口获取会议数据。
- 会议结束时,VCaaS 平台会立即进行一次会议数据的推送。若未正常接收到回调接口响应码为200的正确响应 ,在间隔5分钟、10分钟、15分钟、30分钟后,VCaaS 平台会再次推送会议数据,累计推送4次后,将结束会议数据的主动推送。
- 接收会议数据的回调接口必须为 POST 方法,用户需要自行实现回调接口的幂等性。
- 接收会议数据的回调接口示例:
/**
* 接收会议数据的回调接口示例
*
* @param meetingData VCaaS 平台推送的会议数据
*/
@PostMapping(path = "/accept-meeting-data-demo")
public void acceptMeetingDataDemo(@RequestBody MeetingCompleteDataDto meetingData) {
log.info("accept meeting data:{}", Jsons.toString(meetingData, ""));
}
示例中 MeetingCompleteDataDto 的数据结构和会议数据数据结构说明一致。
会议数据响应
{
// 会议时长数据
"meetingData": {
// 会议ID
"meetingUid": "",
// 外部会议ID
"meetingExternalId": "",
// 原计划会议开始时间
"scheduledStartTime": "",
// 原计划会议结束时间
"scheduledEndTime": "",
// 会议实际开始时间
"startTime": "",
// 会议实际结束时间
"endTime": "",
// 会议持续时长,单位:秒
"duration": ""
},
// 会议与会者考勤数据
"attendeeDatas": [
{
// 会议ID
"meetingUid": "",
// 外部会议ID
"meetingExternalId": "",
// 与会者ID
"attendeeUid": "",
// 外部与会者ID
"externalId": "",
// 与会者首次进入会议时间
"timeIn": "",
// 与会者最后一次离开会议时间
"timeOut": "",
// 参会总时长,单位:秒
"totalTime": "",
// 设备
"device": "",
// 与会者考勤明细数据
"details": [
{
// 考勤类型,AttendeeJoined:进入会议;AttendeeLeft:离开会议;AttendeeDropped:与会者掉线;
"type": "",
// 时间戳,单位:毫秒
"timestamp": 0
}
]
}
],
// 会议录像数据
"meetingVideoData": {
// 会议ID
"meetingUid": "",
// 外部会议ID
"meetingExternalId": "",
// 会议录像下载地址
"videoUrls": [
""
]
},
// 会议互动数据
"meetingInteractiveData": {
// 会议ID
"meetingUid": "",
// 外部会议ID
"meetingExternalId": "",
// 答题数据
"quizData": {
// 使用答题器总次数
"totalCount": 0,
// 答题器明细数据
"detailDatas": [
{
// 题目ID
"id": "",
// 题目内容和选项
"content": {
// 选项
"options": [
{
"value": "",
"label": ""
}
],
// 题目内容
"content": ""
},
// 答题正确率
"averageAccuracy": "",
// 正确答案
"correctAnswer": ""
}
]
},
// 投票数据
"pollData": {
// 使用投票总次数
"totalCount": 0,
// 投票明细数据
"detailDatas": [
{
// 投票ID
"id": "",
// 投票内容与选项
"content": {
// 选项
"options": [
{
"value": "",
"label": ""
}
],
// 内容
"content": ""
}
}
]
}
},
// 会议与会者互动数据
"attendeeInteractiveDatas": [
{
// 会议ID
"meetingUid": "",
// 外部会议ID
"meetingExternalId": "",
// 与会者ID
"attendeeUid": "",
// 外部与会者ID
"externalId": "",
// 与会者答题数据
"attendeeQuizData": {
// 参与答题次数
"count": 0,
// 答题结果
"answers": [
{
// 题目ID
"id": "",
// 与会者用户名
"username": "",
// 题型
"questionType": "",
// 与会者选项
"selection": ""
}
]
},
// 与会者投票数据
"attendeePollData": {
// 参与投票次数
"count": 0,
// 投票结果
"answers": [
{
// 投票ID
"id": "",
// 与会者用户名
"username": "",
// 投票类型
"pollType": "",
// 投票选项
"pollOption": {
"value": "",
"label": ""
}
}
]
}
}
]
}
实时数据推送
说明
客户可以选择接收捕获会议中发生事件的实时回调。
- 在创建会议时,可以在“创建会议”请求体中设置 realTimeCallbackUrl 及其相关字段。如果未设置这些参数,VCaaS 平台将不会主动推送事件数据。
- 实时回调发生在以下情况下:1) 有人加入或离开会议(userJoinLeaveUrl) 2) 会议开始或结束(meetingStartEndUrl) 3) 会议开始录制或停止录制(recordingStartEndUrl)。每个操作都有其自己的数据格式(请参见下面的示例)。
- 如果 VCaaS 在操作发生时未收到正确的响应(200 状态码和 success 响应),它将尝试在 15、30、180 和 1800 秒后再次共享数据。尝试 5 次后,将停止共享数据。
- 回调接口必须使用 POST 方法。用户必须确保接口能够处理重复的数据。
可配置的参数
参数 | 类型 | 必需 | 备注 |
---|---|---|---|
userJoinLeaveUrl | String | 否 | 用户加入和离开会议事件的回调 URL |
meetingStartEndUrl | String | 否 | 会议开始和结束事件的回调 URL |
recordingStartEndUrl | String | 否 | 会议开始录制和停止录制事件的回调 URL |
endClassForAllUrl | String | 否 | 老师点击 End class for all 事件的回调 URL |
实时回调URL示例实现
{
"meetingExternalId": "500000",
"meetingTitle": "Tech meeting",
"startTime": 1673062042,
"endTime": 1673753242,
// 实时回调URL
"realTimeCallbackUrl": {
"userJoinLeaveUrl": "https://app.hilink.co/",
"meetingStartEndUrl": "https://app.hilink.co/",
"recordingStartEndUrl": "https://app.hilink.co/",
"endClassForAllUrl": "https://app.hilink.co/"
},
"config": {
},
"docIds": [
]
}
处理实时回调 API 示例
@PostMapping(path = "/mock-callback")
public String mockCallback(@RequestBody Map<String, Object> data) {
log.info("receive callback data: {}", data);
// TODO: Add any additional processing logic here
return "success";
}
实时回调数据结构
用户进入/离开会议事件
{
// 由 HiLink 分配的内部会议ID
"meetingUid": "12345",
// 客户端分配的外部ID
"meetingExternalId": "meeting-500000",
// 用户角色,0=教师,1=IT支持,2=学生
"userRole": "0",
// 客户端定义的用户ID
"externalId": "user-1234",
// 客户端定义的用户名称
"externalName": "",
// 用户活动状态 0=用户加入,1=用户离开,2=用户进入等待室
"userStatus": "1",
// 用户活动的时间戳
"timestamp": "123456"
}
会议开始/结束事件
{
// 由 HiLink 分配的内部会议ID
"meetingUid": "12345",
// 客户端分配的外部ID
"meetingExternalId": "meeting-500000",
// 用户活动的时间戳
"timestamp": "123456",
// 0: 会议开始,1: 会议结束
"meetingStatus": 1,
// 0: 普通会议结束,1: 非正常会议结束(网络错误)
"meetingEndType": 0
}
会议开始录制/停止录制事件
{
// 由 HiLink 分配的内部会议ID
"meetingUid": "12345",
// 客户端分配的外部ID
"meetingExternalId": "meeting-500000",
// 用户角色,0=教师,1=IT支持,2=系统关闭
"userRole": "0",
// 客户端定义的用户ID
"externalId": "user-1234",
// 客户端定义的用户名称
"externalName": "",
// 录制状态 0=开始录制, 1=停止录制
"recordingStatus": "0",
// 用户活动的时间戳
"timestamp": "123456"
}
老师点击 End class for all 实时回调事件
{
// 由 HiLink 分配的内部会议ID
"meetingUid": "12345",
// 客户端分配的外部ID
"meetingExternalId": "meeting-500000",
// 用户角色,0=教师,1=IT支持
"userRole": "0",
// 客户端定义的用户ID
"externalId": "user-1234",
// 客户端定义的用户名称
"externalName": "",
// 用户活动的时间戳
"timestamp": "123456"
}