logo
In-app Chat
SDK Error Codes
Powered Byspreading
On this page

Call invitation


Overview

ZEGO Instant Messaging (ZIM) SDK provides the call invitation feature that supports full service procedure control. For example, the feature allows a caller to send a call invitation to a called user and allows the called user to accept or refuse the invitation. In this case, the caller and the called user can be offline. A call invitation can be in a common mode or an advanced mode.

In common mode, a user can initiate, cancel, accept, and reject a call invitation, and does not respond to a call invitation within the specified timeout period. On this basis, in advanced mode, a user can invite a new user during the call, and quit and terminate the call.

The call invitation feature provides only basic capabilities for service procedure control. The service requirements for using this feature must be manually implemented. For example, the feature is commonly used in a chat tool for initiating a voice call invitation or a video call invitation.

User states

ZIMCallUserState specifies the state of a user in each call invitation procedure. This section describes how a user state changes, and the relationship among a state, an operation, and a callback.

State changes

The following figure shows how a user state changes in an entire call invitation process from call initiation to call termination.

StateDescriptionTriggering eventApplicable mode
InvitingBeing invited.The user is being invited.
  • Common mode
  • Advanced mode
AcceptedInvitation accepted.
  • A user initiates a call invitation.
  • A user accepts a call invitation.
RejectedInvitation rejected.A user rejects a call invitation.
CanceledInvitation canceled.
  • A user cancels a call invitation.
  • The called user does not respond to the invitation. The caller gets offline and the heartbeat times out.
ReceivedInvitation received.
  • An online user receives a call invitation.
  • An offline user gets online within the specified timeout period.
TimeoutInvitation times out.The called user fails to respond to the invitation within the specified timeout period.
QuitQuit the call.A user in the call quit the call.
  • Advanced mode
UnknownUnknownContact ZEGOCLOUD technical support.

States and corresponding operations and callbacks

In a call invitation process, the call state of a user determines whether the user can call a specific operation or listen to a specific event.

  • The following table describes the correspondence between a call state and an operation.
callInvitecallCancelcallAcceptcallRejectcallingInvitecallQuitcallEnd
InvitingA user can call this operation when the user is in a call, regardless of the call state of the user.A user can call this operation when no response is given to a call invitation after the user initiates the call invitation, regardless of the user state.✔️✔️
Accepted✔️✔️✔️
Rejected
Canceled
Received✔️✔️
Timeout
Quit
Unknown
  • The following table describes the correspondence between a call state and a callback.
onCallInvitationReceivedonCallInvitationTimeoutonCallInvitationCancelledonCallInvitationEndedonCallUserStateChanged
Inviting✔️✔️✔️✔️✔️
Accepted✔️✔️
Rejected
Cancelled
Received✔️✔️✔️
Timeout
Quit✔️
Unknown

Common mode

In common mode, the lifecycle of a call invitation ends after all invitees respond to the invitation. To be specific, a call invitation is terminated after all invitees accept or refuse the invitation, or the invitation times out. The following example shows that a client A initiates a call invitation to a client B in common mode.

1. Listen to the state changes of call invitation users

You can invoke the onCallUserStateChanged callback to listen to the state changes of an invitee.

Untitled
// Listen to the state changes of users related to the call invitation.
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    for(ZIMCallUserInfo userInfo in callUserStateChangeInfo.callUserList){

        // the userID whose state has changed
        String userID = userInfo.userID;
        // the current latest state of the user
        ZIMCallUserState state = userInfo.state;

        // Passthrough field, consistent with the extended data content carried by the user when calling the accept, reject, and exit interfaces.
        String extendedData = userInfo.extendedData;
    }
};
1
Copied!

2. Initiate a call invitation

The client A initiates a call invitation to the client B. The following figure shows the corresponding flowchart.

  1. Client A registers the onCallInvitationCreated callback interface to receive notifications that a call invitation has been created; Client B registers the onCallInvitationReceived callback interface to receive invitation notifications from client A.
  2. Client A initiates a call invitation by calling the callInvite interface. After receiving the invitation information, client B can choose to Accept or Reject.
Note

If the client B is offline, the following two cases are involved:

  • The client B logs in before the invitation times out. In this case, the client B can invoke the onCallInvitationReceived callback interface to receive the invitation notification.vitation notification.
  • The client B logs in after the invitation times out. In this case, the client B can call the queryCallInvitationList operation to query the invitation list.
  • Send a call invitation to an online user:
Untitled
// Initiate call invitation
List<String> invitees = []; // List of invitees
invitees.add('1234'); // Invitee IDs
ZIMCallInviteConfig callInviteConfig = ZIMCallInviteConfig();
callInviteConfig.timeout = 200; // Invitation timeout period in seconds. The value ranges from 1 to 600.

// (Optional) Fill in when sending a call invitation to an offline user.
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;

ZIM
    .getInstance()
    !.callInvite(invitees, callInviteConfig)
    .then((value) => {})
    .catchError((onError) {});
1
Copied!
  • The invitation initiator receives a notification that the call invitation has been created.
Untitled
/** Notification for the initiator of the call invitation that it has been created */
ZIMEventHandler.onCallInvitationCreated = (ZIM zim, ZIMCallInvitationCreatedInfo info, String callID){

};
1
Copied!
  • The callback notification after the invitee receives the invitation
Untitled
// Callback notification for the call invitee after receiving the invitation
ZIMEventHandler.onCallInvitationReceived = (zim, info, callID) {
    
};
1
Copied!

3. Cancel a call invitation

The client A sends a call invitation to the client B and then cancels the call invitation. The following figure shows the corresponding flowchart.

  1. After the client A initiates a call invitation, the client A can call the callCancel operation to cancel the call invitation.
Note

After a call invitation is successfully initiated and before it times out, if no callee accepts, and if the caller actively logs out or disconnects due to a heartbeat timeout, the call invitation will also be canceled.

  1. After the call invitation is canceled, the client B can receive a notification that is returned by the onCallInvitationCancelled callback.
  • Cancel a call invitation.
Untitled
// Cancel a call
List<String> invitees;  // List of invitees
invitees.add("421234");  // Invitee IDs
String callid = "12352435";  // Call ID
ZIMCallCancelConfig config = new ZIMCallCancelConfig();

ZIM
    .getInstance()
    !.callCancel(invitees, callID, callCancelConfig)
    .then((value) => {})
    .catchError((onError) {});
1
Copied!
  • The callback notification received by the invitee after the call invitation is canceled.

4. Accept a call invitation

The client B receives a call invitation from the client A and then accepts the call invitation. The following figure shows the corresponding flowchart.

  1. After the client B receives a call invitation from the client A, the client B can call the callAccept operation to accept the call invitation.
  2. After the client B accepts the call invitation, the client A can receive a notification that is returned by the onCallUserStateChanged callback. If multiple users are involved in the call invitation, all involved users can receive the notification returned by this callback.
  • Accept a call invitation.
Untitled
ZIMCallAcceptConfig callAcceptConfig = ZIMCallAcceptConfig();
ZIM
    .getInstance()
    !.callAccept(callID, callAcceptConfig)
    .then((value) => {})
    .catchError((onError) {});
1
Copied!
  • The callback notification returned after the invitee accepts the call invitation.
Untitled
// The callback received by users in the call after an invitee accepts the call invitation.
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // Users with states of "Inviting", "Received", and "Accepted" will receive the notification when a user accepts a call invitation
};
1
Copied!

5. Reject a call invitation

The client B receives a call invitation from the client A and then rejects the call invitation. The following figure shows the corresponding flowchart.

  1. After the client B receives a call invitation from the client A, the client B can call the callReject operation to reject the call invitation.
  2. After the client B rejects the call invitation, the client A can receive a notification that is returned by the onCallUserStateChanged callback.
  • Reject a call invitation.
Untitled
String callID = "12352435";        // callID
ZIMCallRejectConfig rejectConfig = ZIMCallRejectConfig();
ZIM.getInstance()!.callReject(callID, rejectConfig).then((value) => {}).catchError((onError){});
1
Copied!
  • The callback notification returned after the invitee rejects the call invitation.
Untitled
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // Users with states of "Inviting", "Received", and "Accepted" will receive the notification when a user rejects a call invitation
};
1
Copied!

6. A call invitation times out

The client B receives a call invitation from the client A, but does not respond to the call invitation within the timeout period. The following figure shows the corresponding flowchart.

  1. The client A, namely, the inviter, can invoke the onCallUserStateChanged callback to receive a notification indicating that the call invitation times out because the client B does not respond to the invitation. If multiple users are involved in the call invitation, all involved users can receive the notification returned by this callback.
  2. The client B, namely, the invitee, can invoke the onCallInvitationTimeout callback to receive a notification indicating that the call invitation times out because the client B itself does not respond to the invitation.
  • Callback received by the inviter after the invitee did not response within the timeout period.
Untitled
// Callback received by the inviter after the invitee did not response within the timeout period. The unit of timeout period: second
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // Users with states of "Inviting", "Received", and "Accepted" will receive the notification when a user rejects a call invitation
};
1
Copied!
  • Callback received by the invitee after the invitee did not response within the timeout period.
Untitled
// Callback received by the invitee after the invitee did not response within the timeout period. The unit of timeout period: second
ZIMEventHandler.onCallInvitationTimeout = (ZIM zim, ZIMCallInvitationTimeoutInfo info, String callID) {
    
};
1
Copied!

Advanced mode

You can initiate a call invitation in advanced mode in a call invitation scenario involving a plurality of users, such as a multi-invitee call invitation scenario.

After a call invitation is initiated in advanced mode, the lifecycle of the call invitation ends when a user calls the callEnd operation to terminate the call. Before the call is terminated, a user in the call can invite a new user or quit the call.

Initiate a call invitation in advanced mode

To initiate a call invitation in advanced mode, you must specify the mode when you call the callInvite operation.

Untitled
// Send a call invitation to online users - Advanced mode

List<String> invitees = ["421234"];  // List of invitee IDs
  
ZIMCallInviteConfig config = ZIMCallInviteConfig();
config.timeout = 200; // Invitation timeout in seconds. The range of value is [1, 600].
// mode represents the call invitation mode
config.mode = ZIMCallInvitationMode.advanced;

// (Optional) Fill in when sending a call invitation to an offline user.
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;

ZIM.getInstance()!.callInvite(invitees, config).then((ZIMCallInvitationSentResult result){
    // The callID here is the ID generated by the SDK internally after the user initiates the call, used to uniquely identify a call invitation; this callID will be used when the initiator cancels the call, and when the invitee accepts/rejects the call.
});
1
Copied!
Note

The advanced mode is the same as the common mode in call invitation cancellation, acceptance, rejection, and timeout. The only difference between the two modes lies in call invitation initiation.

Invite a user during a call

After a call invitation is initiated in advanced mode, a user in the Accepted state can call the callingInvite operation to invite a new user. Note that a maximum of 10 users(including the invitation initiator) are allowed in a call.

  • Invite a user during a call
Untitled
// Invite users during a call 
List<String> inviteesList = ["A","B"]; 
ZIMCallingInviteConfig inviteConfig = ZIMCallingInviteConfig();
// Get callID through the callback of creating an advanced mode call invitation.
ZIM.getInstance()!.callingInvite(inviteesList, "callID", inviteConfig).then((value) {
    // Logic after the successful invitaiton
}).catchError((onError) {
    // Handle errors according to the official error code table
});
1
Copied!
  • Call members receive notification that other users are being invited.
Untitled
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // All users whose user state is "Calling" and "Accepted" can receive notifications here that users are being called.
};
1
Copied!

Actively join a call or switch devices

After implementing the advanced mode call invitation, the callJoin interface can be called in the following two situations:

  • A user who has not joined the call wishes to join the call.
  • After a multi-terminal login user uses device A to initiate or accept an invitation, he or she wants to make other devices the new primary device.
Note
  • The main device refers to the device that actively calls the interface to initiate, accept or join the call to participate in the call.
  • Only the main device can detect changes in call invitations, and other devices can only obtain the data in the call invitations by querying the call invitation list.

For the scenario where the user outside the call joins successfully, the user's state will flow to accepted. At this time, all users in the call will receive the notification callback of onCallUserStateChanged

For the scenario of switching devices, other users in the call will not be aware of it.

Untitled
// Join a call or switch the device
ZIMCallJoinConfig joinConfig = ZIMCallJoinConfig();
joinConfig.extendedData = "extendedData";
ZIM.getInstance()?.callJoin('callID',joinConfig).then((result) => {
    // Logic after successfully joining the call
}).catchError((onError){
    // Handle errors accroding to the official error code table
});
1
Copied!

Quit a call

After a call invitation is initiated in advanced mode, a user in the Accepted state can call the callQuit operation to quit the call. After the user quits the call, the state of the user is changed to quit. Then, the user and other users who still stay in the call receive a notification returned by the onCallUserStateChanged callback.

  • Quit a call.
Untitled
// Quit a call
ZIMCallQuitConfig config = ZIMCallQuitConfig();
// Get callID through the callback of creating an advanced mode call invitation.
ZIM.getInstance()!.callQuit("callID", config).then((value) {
    // Logic after successfully quitting a call
}).catchError((onError){
    // Handle errors according to the official error code table
});
1
Copied!
  • The users in the call receive a notification indicating that a user quits the call.
Untitled
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // The user who quits the call and other users that are in the `Inviting`, `Received`, and `Accept` states receive a notification indicating that a user quits the call。 
}; 
1
Copied!

Terminate a call

After a call invitation is initiated in advanced mode, a user in the Accepted state can call the callEnd operation to terminate the call. Subsequently, states of all users remain unchanged, and the call state is changed to end. The users in the Iniviting, Accepted, and Received states receive a notification returned by the onCallInvitationEnded callback.

  • Terminate a call.
Untitled
// Terminate a call.
ZIMCallEndConfig config = ZIMCallEndConfig();
// Get callID through the callback of creating an advanced mode call invitation.
ZIM.getInstance()!.callEnd("callID", config).then((value) {
    // Logic after the successful termination
}).catchError((onError){
    // Handle errors according to the official error code table
});
1
Copied!
  • The users in the call receive a notification indicating that the call is terminated.
Untitled
ZIMEventHandler.onCallInvitationEnded = (ZIM zim, ZIMCallInvitationEndedInfo info, String callID) {
    
};
1
Copied!

What's more

Check whether the invitation has been delivered

If you want to let the online users in the invitation know whether other users have received the invitation, so as to implement related business logic, please change enableNotReceivedCheck in ZIMCallInviteConfig to YES when initiating a call invitation, so as to start checking whether the invitation has been delivered.

Untitled
ZIMCallInviteConfig inviteConfig = ZIMCallinviteConfig();
// Enable checking whether the invitation is delivered or not
inviteConfig.enableNotReceivedCheck = true;

// Code of call invitation initiation 
1
Copied!

After the caller initiates a call invitation, if the called party does not receive this invitation within 5 seconds (you can contact ZEGOCLOUD Technical Support to adjust the interval to 3 seconds or 4 seconds) due to network disconnection, offline, etc.:

  • If the called party client uses the ZIM SDK version 2.14.0 or later, its user state will flow to ZIMCallUserStateNotYetReceived, indicating that the invitation has not yet been delivered. At this time, the business logic can be implemented to display UI prompts such as "This user may be offline and cannot receive call invitations temporarily" to online users in the call invitation.
  • If the called client uses ZIM SDK version 2.14.0 or earlier, its user state remains ZIMCallUserStateInviting. If this state remains for more than 5 seconds, the above business logic can also be implemented.
Note

Please refer to listen to the state changes of call invitation users for more information.

Afterwards, if the called user goes online and accepts the invitation before the invitation times out, the user state of the member will flow to ZIMCallUserStateReceived.

Query the list of call invitations

A user can call the queryCallInvitationList operation to query the list of call invitations related to the user. The maximum entries for a single query is 100, and any number exceeding 100 will be processed as 100.

Untitled
//Query the list of call invitations.

ZIMCallInvitationQueryConfig queryCallListConfig = ZIMCallInvitationQueryConfig();
// Query 20 entries of call invitation data at a time
// If the count is more than 100, ZIM SDK will query for 100 entries.
queryCallListConfig.count = 20;
queryCallListConfig.nextFlag = 0;

ZIM.getInstance()!.queryCallInvitationList(queryCallListConfig).then((ZIMCallInvitationListQueriedResult result) {
    if(result.nextFlag != 0){
        // If the nextFlag returned by the callback is not 0, it means that the query for all call invitation information is not complete. Next time, you can pass the nextFlag returned by the callback to continue querying the remaining call invitation information.        
        queryCallListConfig.nextFlag = result.nextFlag;
    }
}).catchError((onError){
    // Handle errors accroding to the official error code table
});
1
Copied!

Previous

Reply to a message

Next

Get the conversion list