Overview

This article will provide an overview of all webhooks and data pushed from VCaaS meetings. It includes two parts: Meeting Data Push After Meeting is Ended and Real Time Webhooks

Meeting Data Push After Meeting is Ended

Description

After the meeting is over, corresponding meeting duration, attendance of participants, meeting recording (if recording was enabled during the meeting), POLL, QUIZ and other data will be generated. VCaaS platform provides two ways to obtain meeting data: push and query meeting data interface. The meeting duration and attendance data provided by VCaaS platform are based on client connection event generation, and there may be event delays.

  1. When creating a meeting, the callbackUrl parameter in the request parameters can be used to specify the callback address for receiving meeting data. If this parameter is not set, VCaaS platform will not actively push meeting data, and users can obtain meeting data by querying the meeting data interface.
  2. 5 minutes after a meeting ends, VCaaS platform will push meeting data once. If it does not receive a correct response with response code 200 from the callback interface, VCaaS platform will push the meeting data again after 5, 10, 15 and 30 minutes. After a total of 5 pushes, the active push of meeting data will be terminated.
  3. The callback interface for receiving meeting data must be a POST method, and users need to implement the idempotency of the callback interface themselves.
  4. Example of the callback interface for receiving meeting data:
/**
 * Example of a callback interface for receiving meeting data
 *
 * @param meetingData The meeting data pushed by the VCaaS platform
 */
@PostMapping(path = "/accept-meeting-data-demo")
public void acceptMeetingDataDemo(@RequestBody MeetingCompleteDataDto meetingData) {
    log.info("accept meeting data:{}", Jsons.toString(meetingData, ""));
}
  1. The data structure of MeetingCompleteDataDto in the example is consistent with the data structure of meeting data.

Meeting Data Response

{
  // Meeting duration data
  "meetingData": {
    // Meeting ID
    "meetingUid": "",
    // External meeting ID
    "meetingExternalId": "",
    // Original scheduled meeting start time
    "scheduledStartTime": "",
    // Original scheduled meeting end time
    "scheduledEndTime": "",
    // Actual meeting start time
    "startTime": "",
    // Actual meeting end time
    "endTime": "",
    // Meeting duration, in seconds
    "duration": ""
  },
  // Attendee attendance data
  "attendeeDatas": [
    {
      // Meeting ID  
      "meetingUid": "",
      // External meeting ID
      "meetingExternalId": "",
      // Attendee ID
      "attendeeUid": "",
      // External attendee ID
      "externalId": "",
      // Attendee's first entry time
      "timeIn": "",
      // Attendee's last exit time
      "timeOut": "",
      // Total attendance duration, in seconds
      "totalTime": "",
      // Device
      "device": "",
      // Attendee attendance detail data
      "details": [
        {
          // Attendance type, AttendeeJoined: enter the meeting; AttendeeLeft: leave the meeting; AttendeeDropped: attendee disconnected;
          "type": "",
          // Timestamp, in milliseconds
          "timestamp": 0
        }
      ]
    }
  ],
  // Meeting video data
  "meetingVideoData": {
    // Meeting ID 
    "meetingUid": "",
    // External meeting ID 
    "meetingExternalId": "",
    // Meeting video download address
    "videoUrls": [
        ""
    ]
  },
  // Meeting interaction data
  "meetingInteractiveData": {
    // Meeting ID 
    "meetingUid": "",
    // External meeting ID 
    "meetingExternalId": "",
    // Quiz data
    "quizData": {
      // Total number of quiz attempts   
      "totalCount": 0,
      // Quiz detail data
      "detailDatas": [
        {
          // Question ID  
          "id": "",
          // Question content and options
          "content": {
            // Options
            "options": [
              {
                "value": "",
                "label": ""
              }
            ],
            // Question content
            "content": ""
          },
          // Average accuracy
          "averageAccuracy": "",
          // Correct answer
          "correctAnswer": ""
        }
      ]
    },
    // Poll data
    "pollData": {
      // Total number of polls
      "totalCount": 0,
      // Poll detail data
      "detailDatas": [
        {
          // Poll ID
          "id": "",
          // Poll content and options
          "content": {
            // Options
            "options": [
              {
                "value": "",
                "label": ""
              }
            ],
            // Content
            "content": ""
          }
        }
      ]
    }
  },
  // Attendee interaction data
  "attendeeInteractiveDatas": [
    {
      // Meeting ID 
      "meetingUid": "",
      // External meeting ID 
      "meetingExternalId": "",
      // Attendee ID 
      "attendeeUid": "",
      // External attendee ID 
      "externalId": "",
      // Attendee quiz data
      "attendeeQuizData": {
        // Number of quiz attempts
        "count": 0,
        // Quiz results
        "answers": [
          {
            // Question ID
            "id": "",
            // Attendee username
            "username": "",
            // Question type
            "questionType": "",
            // Selection
            "selection": ""
          }
        ]
      },
    // Attendee poll data
    "attendeePollData": {
      // Number of poll attempts
      "count": 0,
      // Poll results
      "answers": [
        {
          // Poll ID
          "id": "",
          // Attendee username
          "username": "",
          // Poll type
          "pollType": "",
          // Poll option
          "pollOption": {
            "value": "",
            "label": ""
            }
          }
        ]
      }
    }
  ]
}

Real-Time Callbacks

Description

Clients can choose to receive real-time callbacks that capture events happening in meetings.

  1. When creating a meeting, the realTimeCallbackUrl and its related fields in the 'Create Meeting' request body. If these parameters are not set, VCaaS platform will not actively push event data.
  2. Real-time callbacks happen when: 1) someone joins or leaves a meeting (userJoinLeaveUrl) 2) a meeting starts or ends (meetingStartEndUrl). 3) a recording starts or ends. Each action has its own data format (see example below).
  3. If VCaaS doesn’t get a correct response (200 status code and 'success' response) when an action happens, it will try to share the data again after 15, 30, 180 and 1800 seconds. After 5 tries, it will stop sharing data.
  4. The callback interface must use a POST method. Users have to ensure the interface can handle repeated data.

Configurable Parameters

ParameterTypeRequiredNote
userJoinLeaveUrlStringfalseCallback URL for users joining and leaving meeting events
meetingStartEndUrlStringfalseCallback URL for meeting start and end events
recordingStartEndUrlStringfalseCallback URL for recording start and end events
endClassForAllUrlStringfalseCallback URL for the teacher's click on the end class for all event

Example realTimeCallbackUrl Implementation

{
    "meetingExternalId": "500000",
    "meetingTitle": "Tech meeting",
    "startTime": 1673062042,
    "endTime": 1673753242,
    // Real Time Callback Webhook URLs
    "realTimeCallbackUrl": { 
        "userJoinLeaveUrl": "https://app.hilink.co/", 
        "meetingStartEndUrl": "https://app.hilink.co/" 
        "recordingStartEndUrl": "https://app.hilink.co/",
        "endClassForAllUrl": "https://app.hilink.co/"
    },
    "config": {
    },
    "docIds": [
    ]
}

Handling real-time callback API examples

@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";
}

Data Structure for Real-time Callbacks

User Join/Leave Events

{
    // Internal Meeting ID assigned by HiLink
    "meetingUid": "12345",
    // External ID assigned by client
    "meetingExternalId": "meeting-500000",
    // user role,0=teacher, 1=IT support,2=student
    "userRole": "0",
    // user ID defined by client
    "externalId": "user-1234",
    // user name defined by client
    "externalName": "",
    // user activity status 0=user join, 1=user left, 2=user in waiting room
    "userStatus": "1",
    // timestamp of user activity
    "timestamp": "123456"
}

Meeting Start/End Events

{
    // Internal Meeting ID assigned by HiLink
    "meetingUid": "12345",
    // External ID assigned by client
    "meetingExternalId": "meeting-500000",
    // timestamp of user activity
    "timestamp": "123456"
    // 0: meeting starts, 1: session ends
    "meetingStatus": 1,
    // 0: regular meeting ends, 1: irregular meeting ends (network error)
    "meetingEndType": 0
}

Recording Start/End Events

{
    // Internal meeting ID assigned by HiLink
    "meetingUid": "12345",
    // External ID assigned by the client
    "meetingExternalId": "meeting-500000",
    // User role, 0=teacher, 1=IT support, 2=system stops recording
    "userRole": "0",
    // User ID defined by the client
    "externalId": "user-1234",
    // User name defined by the client
    "externalName": "",
    // Recording status, 0=start recording, 1=stop recording
    "recordingStatus": "0",
    // Timestamp of user activity
    "timestamp": "123456"
}

Teacher's click on the end class for all events

{
    // Internal Meeting ID assigned by HiLink
    "meetingUid": "12345",
    // External ID assigned by client
    "meetingExternalId": "meeting-500000",
    // User role, 0=teacher, 1=IT support
    "userRole": "0",
    // user ID defined by client
    "externalId": "user-1234",
    // user name defined by client
    "externalName": "",
    // timestamp of user activity
    "timestamp": "123456"
}
Last Updated: