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.
@Override
public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
    super.onCallUserStateChanged(zim, info, callID);

    for(ZIMCallUserInfo userInfo : info.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
// Send a call invitation to an online user. 
List<String> invitees = new ArrayList<String>(); //The List of the invitees.
invitees.add("421234");    // The IDs of the invitees.
ZIMCallInviteConfig config = new ZIMCallInviteConfig(); 
config.timeout = 200; // The invitation timeout period, in seconds. Valid values: 1 to 600.   
// (Optional) Fill in when it is necessary to initiate a call invitation to offline users and push related offline notifications.
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;

zim.callInvite(invitees, config, new ZIMCallInvitationSentCallback() {
    @Override
    public void onCallInvitationSent(String callID, ZIMCallInvitationSentInfo info, ZIMError errorInfo) {
    // The call invitation ID that is internally generated by ZIM SDK after the call invitation is initiated. The ID uniquely identifies a call invitation. The call invitation ID is required when the inviter wants to cancel the call invitation or when the invitee wants to accept or reject the invitation.
    }
});
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 */
zim.setEventHandler(new ZIMEventHandler() {
      @Override
    public void onCallInvitationCreated(ZIM zim, ZIMCallInvitationCreatedInfo info, String callID) {
    
    }
});
1
Copied!
  • The callback notification after the invitee receives the invitation
Untitled
//  The callback notification after the invitee receives the invitation
zim.setEventHandler(new ZIMEventHandler() {
    @Override
    void onCallInvitationReceived(ZIM zim, ZIMCallInvitationReceivedInfo info, String 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 invitation.
List<String> invitees;  // The list of the invitees.
invitees.add("421234");       // The IDs of the invitees.
String callid = "12352435";         // callid
ZIMCallCancelConfig config = new ZIMCallCancelConfig();

ZIM.getInstance().callCancel(invitees, callid, config, new ZIMCallCancelSentCallback() {
    @Override
    public void onCallCancelSent(String callID, ArrayList<String> errorInvitees, ZIMError errorInfo) {
                
    }
});
1
Copied!
  • The callback notification received by the invitee after the call invitation is canceled.
Untitled
// The callback notification received by the invitee after the call invitation is canceled.
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    void onCallInvitationCancelled(ZIM zim, ZIMCallInvitationCancelledInfo info, String callID) {

    } 

});
1
Copied!

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
String callid = "12352435";        // callid
ZIMCallAcceptConfig config = new ZIMCallAcceptConfig();
ZIM.getInstance().callAccept(callid, config, new ZIMCallAcceptanceSentCallback() {
    @Override
    public void onCallAcceptanceSent(String callID, ZIMError errorInfo) {
                
    }
});
1
Copied!
  • The callback notification returned after the invitee accepts the call invitation.
Untitled
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
    // Users with the states "Inviting", "Accepted", and "Received" will receive notifications here when someone 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 config = new ZIMCallRejectConfig();
ZIM.getInstance().callReject(callid, config, new ZIMCallRejectionSentCallback() {
    @Override
    public void onCallRejectionSent(String callID, ZIMError errorInfo) {
                
    }
});
1
Copied!
  • The callback notification returned after the invitee rejects the call invitation.
Untitled
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
        // Users with the states "Inviting", "Accepted", and "Received" will receive notifications here when someone 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.
Untitled
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID){
        // Users with the state "Inviting", "Accepted", and "Received" will receive notifications here when a call invitation times out.    }

    @Override
    public void onCallInvitationTimeout(ZIM zim, String callID) {
    // After the invitee's response timeout, the "invitee" will receive a callback notification. The timeout duration is measured in seconds.
    }     
});
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 an online user in advanced mode. */
// Send a call invitation.
List<String> invitees;  // The list of the invitees.
invitees.add("421234");       // The IDs of the invitees.
ZIMCallInviteConfig config = new ZIMCallInviteConfig(); 
config.timeout = 200; // The invitation timeout period, in seconds. Valid values: 1 to 600.
//  The mode is set to call invitation mode, and ADVANCED represents advanced mode.
config.mode = ADVANCED;

// (Optional) Fill in when initiating a call invitation to an offline user.
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
  
zim.callInvite(invitees, config, new ZIMCallInvitationSentCallback() {
    @Override
    public void onCallInvitationSent(String callID, ZIMCallInvitationSentInfo info, ZIMError errorInfo) {

        // The call invitation ID that is internally generated by ZIM SDK after the call invitation is initiated. The ID uniquely identifies a call invitation. The call invitation ID is required when the inviter wants to cancel the call invitation or when the invitee wants to accept or reject the invitation.
    }
 });
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 a user during a call
ArrayList<String> inviteesList = new ArrayList<>();
inviteesList.add("inviteesA");
inviteesList.add("inviteesB");
ZIMCallingInviteConfig inviteConfig = new ZIMCallingInviteConfig();
// callID obtained through the callback of creating an advanced mode call invitation
ZIM.getInstance().callingInvite(inviteesList, callID, inviteConfig, new ZIMCallingInvitationSentCallback() {
    @Override
    public void onCallingInvitationSent(String callID, ZIMCallingInvitationSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code != ZIMErrorCode.SUCCESS){
            //Handle according to the official website's error code table.
        }
        //The business logic after a successful invitation.
    }
});
1
Copied!
  • Call members receive notification that other users are being invited
Untitled
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, 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 the call

ZIMCallJoinConfig config = new ZIMCallJoinConfig();
config.extendedData = "extendedData";
ZIM.getInstance().callJoin(callID, config, new ZIMCallJoinSentCallback() {
    @Override
    public onCallJoinSent(String callID, ZIMCallJoinSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // The business logic after the successful joining.
        } else{
            // Handle according to the official website's 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 = new ZIMCallQuitConfig();
// callID obtained through the callback of creating an advanced mode call invitation
ZIM.getInstance().callQuit(callID, config, new ZIMCallQuitSentCallback() {
    @Override
    public void onCallQuitSent(String callID, ZIMCallQuitSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // The business logic after a successful logout.
        }else {
            // The business logic after a successful logout.
        }
    }
});
1
Copied!
  • The users in the call receive a notification indicating that a user quits the call.
Untitled
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, 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 endConfig = new ZIMCallEndConfig();
// callID obtained through the callback of creating an advanced mode call invitation
ZIM.getInstance().callEnd(callID, endConfig, new ZIMCallEndSentCallback() {
  @Override
  public void onCallEndSent(String callID, ZIMCallEndSentInfo info, ZIMError errorInfo) {
      if(errorInfo.code == ZIMErrorCode.SUCCESS){
          // The business logic after the successful completion.
      }else{
          // Handle according to the official website's error code table.
      }
  }
});
1
Copied!
  • The users in the call receive a notification indicating that the call is terminated.
Untitled
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallInvitationEnded(ZIM zim, ZIMCallInvitationEndedInfo info, String callID) {
        super.onCallInvitationEnded(zim, info, 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 config = new ZIMCallInviteConfig();
//Enable not yet delivered detection
config.enableNotReceivedCheck = true;

//Initiate call invitation related code
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 = new ZIMCallInvitationQueryConfig();
queryCallListConfig.count = 20;
queryCallListConfig.nextFlag = 0;
ZIM.getInstance(). queryCallInvitationList(queryCallListConfig, new ZIMCallInvitationListQueriedCallback() {
    @Override
    public void onCallListQueried(ArrayList<ZIMCallInfo> callList, long nextFlag, ZIMError errorInfo) {
        if(errorInfo.code != ZIMErrorCode.SUCCESS){
            // Handle according to the official website's error code table.
            return;
        }
        if(nextFlag != 0){
            // If the nextFlag returned by the callback is not 0, it means that the query for all call invitation information is not completed. The next time you query, you can pass the nextFlag returned by the callback to continue querying the remaining call invitation information.
            queryCallListConfig.nextFlag = nextFlag;
        }
    }
});
1
Copied!

Previous

Reply to a message

Next

Get the conversion list