Event RSVP
Handle event attendance through RSVP responses, track attendees, and manage user participation in scheduled events.
Overview
The RSVP system allows users to respond to event invitations with two status types:
Going : Confirmed attendance
Not Going : Declined invitation
Each event tracks RSVP counts and provides APIs to manage responses and query attendees.
RSVP Response Types
Status Description Impact Going User will attend Counted in rsvpCount, included in attendee list Not Going User won’t attend Recorded but not counted in attendance
Creating an RSVP
RSVP as Going
Task { @MainActor in
do {
let event = try await AmityEventRepository. shared . getEvent ( id : "event-123" )
let rsvp = try await event. createRSVP ( status : . going )
print ( "RSVP created: \( rsvp. status ) " )
} catch {
print ( "Failed to RSVP: \( error ) " )
}
}
RSVP as Not Going
let event = try await AmityEventRepository. shared . getEvent ( id : "event-123" )
let rsvp = try await event. createRSVP ( status : . notGoing )
Updating an RSVP
Change existing RSVP response:
Task { @MainActor in
do {
let event = try await AmityEventRepository. shared . getEvent ( id : "event-123" )
let updatedRSVP = try await event. updateRSVP ( status : . notGoing )
print ( "RSVP updated to: \( updatedRSVP. status ) " )
} catch {
print ( "Failed to update RSVP: \( error ) " )
}
}
Getting My RSVP
Check current user’s RSVP status for an event:
Task { @MainActor in
do {
let event = try await AmityEventRepository. shared . getEvent ( id : "event-123" )
let myRSVP = try await event. getMyRSVP ()
print ( "My RSVP status: \( myRSVP. status ) " )
print ( "Responded at: \( myRSVP. respondedAt ) " )
} catch {
print ( "Failed to get RSVP: \( error ) " )
}
}
Querying Event Attendees
Get All Going Attendees
let event = try await AmityEventRepository. shared . getEvent ( id : "event-123" )
let attendees = event. getRSVPs ( status : . going )
attendees. observe { responses in
responses. forEach { rsvp in
print ( "Attendee: \( rsvp. user . displayName ) " )
print ( "Responded at: \( rsvp. respondedAt ) " )
}
print ( "Total going: \( responses. count ) " )
}
Get Not Going Users
let event = try await AmityEventRepository. shared . getEvent ( id : "event-123" )
let notGoing = event. getRSVPs ( status : . notGoing )
notGoing. observe { responses in
print ( "Not going count: \( responses. count ) " )
}
RSVP Data Model
The AmityEventResponse object contains:
interface AmityEventResponse {
status : AmityEventResponseStatus ; // going | not_going
eventId : string ;
event ?: AmityEvent ; // Linked event object
userId : string ; // User who RSVP'd
user ?: AmityUser ; // Linked user object
createdAt : string ; // ISO 8601 timestamp
respondedAt : string ; // ISO 8601 timestamp
}
Common Use Cases
import { EventRepository , AmityEventResponseStatus } from '@amityco/ts-sdk' ;
// Get current user's RSVP and display appropriate button
const unsubscribe = EventRepository . getEvent (
eventId ,
async ({ data : event , loading , error }) => {
if ( event && ! loading ) {
const myRSVP = await event . getMyRSVP ();
if ( ! myRSVP ) {
// Show RSVP options
displayRSVPOptions ();
} else if ( myRSVP . status === AmityEventResponseStatus . Going ) {
// Show "Going" button, allow change
displayGoingButton ( myRSVP );
} else {
// Show "Not Going" button, allow change
displayNotGoingButton ( myRSVP );
}
}
}
);
Attendee List with Real-Time Updates
import { EventRepository , AmityEventResponseStatus } from '@amityco/ts-sdk' ;
let rsvpUnsubscribe : (() => void ) | undefined ;
// Display attendee list that updates in real-time
const unsubscribe = EventRepository . getEvent (
eventId ,
({ data : event , loading , error }) => {
if ( event && ! loading ) {
rsvpUnsubscribe = event . getRSVPs (
{ status: AmityEventResponseStatus . Going },
({ data : responses , loading , error }) => {
if ( responses ) {
const attendeeList = responses . map ( rsvp => ({
userId: rsvp . userId ,
name: rsvp . user ?. displayName ,
avatar: rsvp . user ?. avatar ,
respondedAt: rsvp . respondedAt
}));
updateAttendeeUI ( attendeeList );
updateCountBadge ( responses . length );
}
}
);
}
}
);
// Call unsubscribe() and rsvpUnsubscribe() when component unmounts
RSVP Summary
import { EventRepository , AmityEventResponseStatus } from '@amityco/ts-sdk' ;
let rsvpUnsubscribe : (() => void ) | undefined ;
// Get comprehensive RSVP summary
const unsubscribe = EventRepository . getEvent (
eventId ,
({ data : event , loading , error }) => {
if ( event && ! loading ) {
console . log ( `RSVP Summary for: ${ event . title } ` );
console . log ( `Going: ${ event . rsvpCount } ` );
// Optionally get detailed attendee list
rsvpUnsubscribe = event . getRSVPs (
{ status: AmityEventResponseStatus . Going },
({ data : responses }) => {
if ( responses ) {
console . log ( "Attendees:" , responses . map ( r => r . user ?. displayName ));
}
}
);
}
}
);
Toggle RSVP Status
import { EventRepository , AmityEventResponseStatus } from '@amityco/ts-sdk' ;
// Toggle between Going and Not Going
function toggleRSVP ( eventId : string ) {
const unsubscribe = EventRepository . getEvent (
eventId ,
async ({ data : event , loading , error }) => {
if ( event && ! loading ) {
const myRSVP = await event . getMyRSVP ();
if ( ! myRSVP || myRSVP . status !== AmityEventResponseStatus . Going ) {
// Create or update to Going
if ( ! myRSVP ) {
await event . createRSVP ( AmityEventResponseStatus . Going );
} else {
await event . updateRSVP ( AmityEventResponseStatus . Going );
}
showNotification ( "You're going to this event!" );
} else {
// Update to Not Going
await event . updateRSVP ( AmityEventResponseStatus . NotGoing );
showNotification ( "RSVP updated" );
}
// Unsubscribe after operation
unsubscribe ();
}
}
);
}
Best Practices
Maintain UI state based on RSVP status: // Check RSVP status before showing options
const myRSVP = await event . getMyRSVP ();
if ( myRSVP ) {
// User has RSVP'd - show update options
showRSVPUpdateUI ( myRSVP . status );
} else {
// User hasn't RSVP'd - show create options
showRSVPCreateUI ();
}
Subscribe to attendee lists for live updates:
Use live collections for attendee lists
Update counts automatically
Unsubscribe when view is dismissed
Handle network disconnections gracefully
Handle RSVP errors appropriately: try {
await event . createRSVP ( status );
} catch ( error ) {
if ( error . code === 'ALREADY_EXISTS' ) {
// User already RSVP'd, use update instead
await event . updateRSVP ( status );
} else if ( error . code === 'EVENT_ENDED' ) {
showError ( "This event has ended" );
} else {
showError ( "Failed to RSVP" );
}
}
Notifications
RSVP actions may trigger notifications:
Action Notification Trigger User RSVPs “Going” Event creator notified of new attendee User changes to “Not Going” Event creator may be notified Event updates All “Going” attendees notified of changes Event reminder All “Going” users notified
Notification Settings : Notification behavior is configurable at the network level through the Admin Console.
Error Handling
do {
try await event. createRSVP ( status : . going )
} catch AmityError. alreadyExists {
// RSVP already exists, use update instead
try await event. updateRSVP ( status : . going )
} catch AmityError. eventEnded {
showError ( "Cannot RSVP to ended event" )
} catch AmityError. eventCancelled {
showError ( "This event has been cancelled" )
} catch {
showError ( "Failed to RSVP: \( error. localizedDescription ) " )
}