Overview
The Osmium Chat Protocol invite system enables users to join communities, groups, and connect with other users through shareable invite codes.
Invite Types
Three types of invites are supported:
enum InviteType {
UNKNOWN = 0 ;
COMMUNITY = 1 ;
GROUP = 2 ;
USER = 3 ;
}
Unknown or invalid invite type
Invite to join a community (server)
Invite to join a group chat
Invite to connect with another user (friend request)
Lookup Invite
Preview invite details before accepting it.
Method : auth.lookupInvite → auth.InvitePreview
Request Message
message LookupInvite {
string code = 1 ;
}
Parameters
The invite code to lookup
Response Message
message InvitePreview {
string code = 1 ;
// @snowflake<User>
fixed64 creator_id = 2 ;
// @snowflake<Keyable>
fixed64 target_id = 3 ;
InviteType target_type = 4 ;
optional fixed64 expires_at = 5 ;
optional tangle.client.types.User creator = 6 ;
oneof target_info {
tangle.client.types.Community community = 7 ;
tangle.client.types.Group chat = 8 ;
tangle.client.types.User user = 9 ;
}
}
Response Fields
Snowflake ID of the user who created the invite
Snowflake ID of the target (community, group, or user)
Type of invite: COMMUNITY, GROUP, or USER
Optional expiration timestamp (Unix timestamp in milliseconds). If not set, the invite never expires.
Optional user object for the invite creator, including profile information
Detailed information about the invite target. Contains one of:
community: Community object if target_type is COMMUNITY
chat: Group object if target_type is GROUP
user: User object if target_type is USER
Example Usage
const inviteCode = "abc123xyz" ;
const preview = await client . auth . lookupInvite ({ code: inviteCode });
console . log ( `Invite Type: ${ preview . target_type } ` );
console . log ( `Created by: ${ preview . creator ?. name || preview . creator_id } ` );
if ( preview . expires_at ) {
const expiresAt = new Date ( Number ( preview . expires_at ));
console . log ( `Expires: ${ expiresAt . toLocaleString () } ` );
} else {
console . log ( "Expires: Never" );
}
// Check invite type and display appropriate information
switch ( preview . target_type ) {
case InviteType . COMMUNITY :
console . log ( `Community: ${ preview . community . name } ` );
console . log ( `Members have ${ preview . community . permissions } permissions` );
break ;
case InviteType . GROUP :
console . log ( `Group: ${ preview . chat . name } ` );
console . log ( `Participants: ${ preview . chat . participant_ids . length } ` );
break ;
case InviteType . USER :
console . log ( `User: ${ preview . user . name } ` );
if ( preview . user . username ) {
console . log ( `Username: @ ${ preview . user . username } ` );
}
break ;
}
Always lookup an invite before using it to show users what they’re about to join.
Use Invite
Accept an invite to join a community, group, or connect with a user.
Method : auth.useInvite → ()
Request Message
message UseInvite {
string code = 1 ;
}
Parameters
The invite code to accept
Response
Returns an empty response on success.
Example Usage
Complete Flow
With Expiration Check
Python
// Step 1: Lookup the invite
const inviteCode = "abc123xyz" ;
const preview = await client . auth . lookupInvite ({ code: inviteCode });
// Step 2: Show preview to user
console . log ( `You've been invited to join: ${ preview . community ?. name || preview . chat ?. name || preview . user ?. name } ` );
// Step 3: User confirms, use the invite
await client . auth . useInvite ({ code: inviteCode });
console . log ( "Successfully joined!" );
Once an invite is used, the user immediately joins the target community/group or connects with the user. Ensure the user confirms before calling this method.
Created Invite
Response model returned when creating an invite (for communities, groups, or users).
message CreatedInvite {
string code = 1 ;
}
The generated invite code that can be shared
Invite creation endpoints are defined in their respective service modules (communities, groups, users). This message is the standard response format for all invite creation operations.
Invite List
Container for multiple invite previews.
message InviteList {
repeated InvitePreview invites = 1 ;
}
Array of invite preview objects
This message is used when retrieving multiple invites, such as getting all invites for a community or group.
Common Patterns
Invite Link Validation
async function validateInviteLink ( inviteCode ) {
try {
const preview = await client . auth . lookupInvite ({ code: inviteCode });
// Check expiration
if ( preview . expires_at ) {
if ( Number ( preview . expires_at ) < Date . now ()) {
return { valid: false , reason: "Invite has expired" };
}
}
// Check invite type
if ( preview . target_type === InviteType . UNKNOWN ) {
return { valid: false , reason: "Invalid invite type" };
}
return { valid: true , preview };
} catch ( error ) {
return { valid: false , reason: "Invite not found" };
}
}
const validation = await validateInviteLink ( "abc123" );
if ( validation . valid ) {
// Show invite preview to user
} else {
console . error ( validation . reason );
}
Display Invite Preview
function formatInvitePreview ( preview ) {
const expiresText = preview . expires_at
? `Expires ${ new Date ( Number ( preview . expires_at )). toLocaleDateString () } `
: "Never expires" ;
const creatorText = preview . creator
? `Invited by ${ preview . creator . name } `
: "" ;
let targetInfo = {};
switch ( preview . target_type ) {
case InviteType . COMMUNITY :
targetInfo = {
type: "Community" ,
name: preview . community . name ,
icon: preview . community . photo ,
subtitle: "Join this community"
};
break ;
case InviteType . GROUP :
targetInfo = {
type: "Group Chat" ,
name: preview . chat . name ,
subtitle: ` ${ preview . chat . participant_ids . length } members`
};
break ;
case InviteType . USER :
targetInfo = {
type: "User" ,
name: preview . user . name ,
icon: preview . user . photo ,
subtitle: preview . user . username ? `@ ${ preview . user . username } ` : ""
};
break ;
}
return {
... targetInfo ,
creator: creatorText ,
expiration: expiresText ,
code: preview . code
};
}
Auto-Accept Invite from Deep Link
// Handle invite deep links like: osmium://invite/abc123xyz
async function handleInviteDeepLink ( url ) {
const inviteCode = url . split ( '/' ). pop ();
try {
// Lookup first
const preview = await client . auth . lookupInvite ({ code: inviteCode });
// Show confirmation dialog to user
const confirmed = await showConfirmDialog (
`Join ${ preview . community ?. name || preview . chat ?. name || preview . user ?. name } ?`
);
if ( confirmed ) {
await client . auth . useInvite ({ code: inviteCode });
// Navigate to the joined community/group/user
navigateTo ( preview . target_type , preview . target_id );
}
} catch ( error ) {
showError ( "Invalid or expired invite link" );
}
}