Invitation System
Send real-time invitations to users and handle call requests with BaxCloud's invitation system
Overview
BaxCloud's Invitation System provides a seamless way to send real-time call invitations between users. Whether you're building a one-on-one calling app, a video conferencing platform, or a live streaming service with viewer-to-host calls, the invitation system handles the signaling, delivery, and response workflow for you.
The system works independently of the room connection, meaning you can send invitations before users join a room. This makes it perfect for implementing traditional "calling" experiences where one user initiates contact and the other accepts or declines.
Call Someone
Initiate 1-on-1 calls by sending invitations to specific users with custom messages
Invite to Meeting
Invite multiple participants to join an ongoing video conference or meeting room
Real-time Notifications
Recipients receive instant notifications with invitation details and can respond immediately
How It Works
The invitation system uses BaxCloud's real-time signaling infrastructure to deliver invitations instantly. Here's how the flow works:
Invitation Flow
- Sender calls
sendCallInvitation()with recipient user ID and invitation details - BaxCloud delivers the invitation to the recipient in real-time via their active connection
- Recipient's
onInvitationReceivedevent handler is triggered with invitation data - Recipient can call
acceptCallInvitation()ordeclineCallInvitation() - Sender receives callback with the response via
onInvitationAcceptedoronInvitationDeclined - If accepted, both parties can join the specified room using the room URL or name
Sending Invitations
Initiate a call by sending an invitation to another user
Use the sendCallInvitation() method to send an invitation. You can specify the call type, room details, and a custom message.
1import { BaxCloudClient } from '@baxcloud/react-sdk';
2
3const client = new BaxCloudClient({
4 projectId: 'your-project-id',
5 apiKey: 'your-api-key',
6});
7
8// Send a call invitation
9const invitation = await client.sendCallInvitation({
10 to: 'user-456', // Recipient's user ID
11 roomName: 'call-room-123',
12 callType: 'video_call', // 'video_call', 'audio_call', or 'live_streaming'
13 message: 'Hey! Want to hop on a quick video call?',
14 roomUrl: 'https://yourapp.com/room/call-room-123', // Optional deep link
15});
16
17console.log('Invitation sent:', invitation.invitationId);
18
19// Listen for responses
20client.onInvitationAccepted((data) => {
21 console.log('User accepted!', data);
22 // Join the room
23 client.connect({
24 roomName: data.roomName,
25 participant: { /* ... */ },
26 liveType: 'video_call',
27 });
28});
29
30client.onInvitationDeclined((data) => {
31 console.log('User declined:', data);
32});roomUrl parameter is useful for deep linking. When the recipient accepts on mobile, you can use this to navigate them directly to the call screen in your app.Receiving Invitations
Handle incoming call invitations from other users
Register an event listener for onInvitationReceived to be notified when someone sends you a call invitation. The event provides all the invitation details including sender info, call type, and message.
1// Listen for incoming invitations
2client.onInvitationReceived((invitation) => {
3 console.log('Incoming call from:', invitation.from);
4 console.log('Call type:', invitation.callType);
5 console.log('Message:', invitation.message);
6 console.log('Room:', invitation.roomName);
7
8 // Show UI notification to user
9 showCallNotification({
10 invitationId: invitation.invitationId,
11 callerName: invitation.fromUser.name,
12 callerAvatar: invitation.fromUser.avatarUrl,
13 callType: invitation.callType,
14 message: invitation.message,
15 onAccept: () => acceptInvitation(invitation.invitationId),
16 onDecline: () => declineInvitation(invitation.invitationId),
17 });
18});
19
20// Example: React component for incoming call UI
21function IncomingCallModal({ invitation, onAccept, onDecline }) {
22 return (
23 <div className="modal">
24 <img src={invitation.fromUser.avatarUrl} alt={invitation.fromUser.name} />
25 <h2>{invitation.fromUser.name} is calling...</h2>
26 <p>{invitation.message}</p>
27 <div className="buttons">
28 <button onClick={onAccept} className="accept">
29 <Check /> Accept
30 </button>
31 <button onClick={onDecline} className="decline">
32 <X /> Decline
33 </button>
34 </div>
35 </div>
36 );
37}Accepting Invitations
Accept a call invitation and join the room
When a user wants to accept an invitation, call acceptCallInvitation() with the invitation ID. This notifies the sender and you can then proceed to join the room.
1// Accept the invitation
2await client.acceptCallInvitation(invitationId);
3
4// Then join the room
5await client.connect({
6 roomName: invitation.roomName,
7 participant: {
8 userId: 'user-123',
9 name: 'Jane Doe',
10 avatarUrl: 'https://example.com/avatar.jpg',
11 isHost: false,
12 },
13 liveType: invitation.callType, // 'video_call', 'audio_call', etc.
14});
15
16// Enable camera/microphone
17await client.enableCamera();
18await client.enableMicrophone();Declining Invitations
Reject a call invitation
If the user doesn't want to accept the call, use declineCallInvitation() to notify the sender that the invitation was rejected.
1// Decline the invitation
2await client.declineCallInvitation(invitationId);
3
4// Optional: Provide a reason
5await client.declineCallInvitation(invitationId, {
6 reason: 'busy', // 'busy', 'declined', 'unavailable'
7 message: 'Sorry, I\'m in a meeting right now',
8});Canceling Invitations
Cancel an invitation you sent before it's answered
If the sender wants to cancel an invitation (for example, if the recipient is taking too long to respond), use cancelCallInvitation().
1// Cancel the invitation
2await client.cancelCallInvitation(invitationId);
3
4// Example: Auto-cancel after 30 seconds
5const invitation = await client.sendCallInvitation({ /* ... */ });
6
7const timeoutId = setTimeout(async () => {
8 try {
9 await client.cancelCallInvitation(invitation.invitationId);
10 console.log('Invitation timed out');
11 } catch (error) {
12 // Already accepted/declined
13 console.log('Invitation already answered');
14 }
15}, 30000);
16
17// Clear timeout if user responds
18client.onInvitationAccepted((data) => {
19 clearTimeout(timeoutId);
20});
21
22client.onInvitationDeclined((data) => {
23 clearTimeout(timeoutId);
24});onInvitationCanceled event when the sender cancels the invitation. You can use this to dismiss any UI notifications showing the incoming call.Complete Invitation Flow Example
Full implementation showing both sender and receiver sides
1import { useState, useEffect } from 'react';
2import { BaxCloudClient } from '@baxcloud/react-sdk';
3
4function CallApp() {
5 const [client] = useState(() => new BaxCloudClient({
6 projectId: 'your-project-id',
7 apiKey: 'your-api-key',
8 }));
9 const [incomingInvitation, setIncomingInvitation] = useState(null);
10 const [outgoingInvitation, setOutgoingInvitation] = useState(null);
11
12 useEffect(() => {
13 // Listen for incoming invitations
14 client.onInvitationReceived((invitation) => {
15 setIncomingInvitation(invitation);
16 });
17
18 // Listen for invitation responses
19 client.onInvitationAccepted((data) => {
20 console.log('User accepted! Joining room...');
21 setOutgoingInvitation(null);
22 joinRoom(data.roomName);
23 });
24
25 client.onInvitationDeclined((data) => {
26 alert('User declined the call');
27 setOutgoingInvitation(null);
28 });
29
30 client.onInvitationCanceled((data) => {
31 setIncomingInvitation(null);
32 });
33
34 return () => client.disconnect();
35 }, [client]);
36
37 const callUser = async (userId: string) => {
38 const invitation = await client.sendCallInvitation({
39 to: userId,
40 roomName: `call-${Date.now()}`,
41 callType: 'video_call',
42 message: 'Join me for a video call!',
43 });
44 setOutgoingInvitation(invitation);
45
46 // Auto-cancel after 30 seconds
47 setTimeout(() => {
48 if (outgoingInvitation?.invitationId === invitation.invitationId) {
49 client.cancelCallInvitation(invitation.invitationId);
50 setOutgoingInvitation(null);
51 }
52 }, 30000);
53 };
54
55 const acceptInvitation = async () => {
56 if (!incomingInvitation) return;
57
58 await client.acceptCallInvitation(incomingInvitation.invitationId);
59 setIncomingInvitation(null);
60 joinRoom(incomingInvitation.roomName);
61 };
62
63 const declineInvitation = async () => {
64 if (!incomingInvitation) return;
65
66 await client.declineCallInvitation(incomingInvitation.invitationId);
67 setIncomingInvitation(null);
68 };
69
70 const joinRoom = async (roomName: string) => {
71 await client.connect({
72 roomName,
73 participant: {
74 userId: 'current-user-id',
75 name: 'Current User',
76 isHost: false,
77 },
78 liveType: 'video_call',
79 });
80 await client.enableCamera();
81 await client.enableMicrophone();
82 };
83
84 return (
85 <div>
86 {/* Incoming call UI */}
87 {incomingInvitation && (
88 <div className="incoming-call-modal">
89 <img src={incomingInvitation.fromUser.avatarUrl} />
90 <h2>{incomingInvitation.fromUser.name} is calling...</h2>
91 <p>{incomingInvitation.message}</p>
92 <button onClick={acceptInvitation}>Accept</button>
93 <button onClick={declineInvitation}>Decline</button>
94 </div>
95 )}
96
97 {/* Outgoing call UI */}
98 {outgoingInvitation && (
99 <div className="outgoing-call-modal">
100 <p>Calling...</p>
101 <button onClick={() => {
102 client.cancelCallInvitation(outgoingInvitation.invitationId);
103 setOutgoingInvitation(null);
104 }}>
105 Cancel
106 </button>
107 </div>
108 )}
109
110 {/* Call button */}
111 <button onClick={() => callUser('target-user-id')}>
112 Call User
113 </button>
114 </div>
115 );
116}Best Practices
1. Implement Timeouts
Always set a timeout for outgoing invitations (typically 30-60 seconds). If the recipient doesn't respond in time, automatically cancel the invitation to avoid hanging states.
2. Handle Offline Users
Check if the recipient is online before sending an invitation. BaxCloud provides presence APIs to query user online status. If a user is offline, show an appropriate message instead of sending an invitation that won't be delivered.
3. Provide Clear UI Feedback
Show clear visual and audio notifications for incoming invitations. Include the caller's name, avatar, and message. Use distinctive ringtones and vibrations on mobile to ensure users don't miss calls.
4. Support Background Notifications
Integrate push notifications (FCM for Android, APNS for iOS) to deliver invitations when your app is in the background or closed. BaxCloud can send webhook events to your backend to trigger push notifications.
5. Track Invitation State
Maintain invitation state in your UI to prevent duplicate invitations and handle edge cases like network disconnections. Use the invitation ID to track which invitation corresponds to which UI element.
6. Add Call History
Keep a record of sent and received invitations in your database. This allows users to see missed calls and call back later, similar to traditional phone apps.