Add detailed API: - Complete API documentation for In Format Usage flow diagrams for authentication and booking processes - Comprehensive endpoint descriptions with request/response examples - Detailed authentication and booking flow explanations - Structured documentation for health checks, authentication, and booking endpoints -: - Includes JWT authentication details usage - Provides clear API usage patterns for users and clients and administrators system interactions - Enhances project documentation with provides clear, structured API reference - Improves developer and user understanding of system capabilities
9.0 KiB
Personalized Meeting Links Implementation
Overview
All meeting links are now personalized with the user's name and role-specific settings. This ensures users join meetings with their actual names instead of generic identifiers, and admins get appropriate moderator privileges.
Changes Made
1. API Endpoints with Personalized Links
GET /api/bookings
Returns the authenticated user's bookings with personalized meeting links.
Response Example:
{
"bookings": [
{
"id": 123,
"user_id": 45,
"scheduled_at": "2024-01-15T10:00:00Z",
"duration": 60,
"status": "scheduled",
"jitsi_room_id": "booking-123-1234567890-abc123",
"jitsi_room_url": "https://meet.jit.si/booking-123-1234567890-abc123",
"personalized_meeting_url": "https://meet.jit.si/booking-123-1234567890-abc123#userInfo.displayName=\"John Doe\"",
"amount": 100.00,
"payment_status": "succeeded"
}
]
}
Key Fields:
jitsi_room_url: Original Jitsi room URL (kept for backward compatibility)personalized_meeting_url: User-specific URL with their name pre-filled
GET /api/admin/bookings
Returns all bookings with admin's personalized meeting links.
Response Example:
{
"bookings": [
{
"id": 123,
"user_id": 45,
"scheduled_at": "2024-01-15T10:00:00Z",
"duration": 60,
"status": "scheduled",
"jitsi_room_id": "booking-123-1234567890-abc123",
"jitsi_room_url": "https://meet.jit.si/booking-123-1234567890-abc123",
"admin_meeting_url": "https://meet.jit.si/booking-123-1234567890-abc123#userInfo.displayName=\"Dr. Smith\"&config.startWithAudioMuted=false&config.startWithVideoMuted=false",
"amount": 100.00,
"payment_status": "succeeded"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
Key Fields:
admin_meeting_url: Admin-specific URL with moderator privileges
GET /api/meetings/:id/link
Returns a personalized meeting link for a specific booking.
Response Example:
{
"booking_id": 123,
"meeting_url": "https://meet.jit.si/booking-123-1234567890-abc123#userInfo.displayName=\"John Doe\"",
"display_name": "John Doe",
"is_admin": false,
"scheduled_at": "2024-01-15T10:00:00Z",
"duration": 60,
"status": "scheduled"
}
2. Email Notifications
All email notifications now include personalized meeting links:
Meeting Info Email (After Booking)
- Sent to: User
- Link includes: User's name
- Example:
https://meet.jit.si/room-id#userInfo.displayName="John Doe"
Reminder Email (Before Meeting)
- Sent to: User
- Link includes: User's name
- Example:
https://meet.jit.si/room-id#userInfo.displayName="John Doe"
Note: Admin users receive emails with admin privileges in the link if they book for themselves.
3. Display Name Logic
The system determines display names in this order:
- First Name + Last Name:
"John Doe" - Email: If name fields are empty, uses email address
- Fallback: Email as last resort
4. Admin vs Regular User Differences
Regular User Link
https://meet.jit.si/room-id#userInfo.displayName="John Doe"
Features:
- Name pre-filled
- Standard participant permissions
- Default audio/video settings
Admin User Link
https://meet.jit.si/room-id#userInfo.displayName="Dr. Smith"&config.startWithAudioMuted=false&config.startWithVideoMuted=false
Features:
- Name pre-filled
- Moderator privileges
- Audio and video enabled by default
- Can manage participants
- Can start/stop recording (if configured)
Frontend Implementation Guide
Using Personalized Links from /api/bookings
// Fetch user's bookings
async function fetchMyBookings() {
const response = await fetch('/api/bookings', {
headers: {
'Authorization': `Bearer ${userToken}`
}
});
const data = await response.json();
// Use personalized_meeting_url instead of jitsi_room_url
data.bookings.forEach(booking => {
if (booking.personalized_meeting_url) {
console.log(`Join link: ${booking.personalized_meeting_url}`);
}
});
}
Using Admin Links from /api/admin/bookings
// Fetch all bookings as admin
async function fetchAllBookings() {
const response = await fetch('/api/admin/bookings', {
headers: {
'Authorization': `Bearer ${adminToken}`
}
});
const data = await response.json();
// Use admin_meeting_url for admin access
data.bookings.forEach(booking => {
if (booking.admin_meeting_url) {
console.log(`Admin join link: ${booking.admin_meeting_url}`);
}
});
}
React Component Example
function BookingCard({ booking, isAdmin }) {
const getMeetingLink = () => {
if (isAdmin && booking.admin_meeting_url) {
return booking.admin_meeting_url;
}
return booking.personalized_meeting_url || booking.jitsi_room_url;
};
const handleJoinMeeting = () => {
const meetingLink = getMeetingLink();
window.open(meetingLink, '_blank');
};
return (
<div className="booking-card">
<h3>Booking #{booking.id}</h3>
<p>Scheduled: {new Date(booking.scheduled_at).toLocaleString()}</p>
{booking.status === 'scheduled' && (
<button onClick={handleJoinMeeting}>
{isAdmin ? 'Join as Moderator' : 'Join Meeting'}
</button>
)}
</div>
);
}
Migration Guide
Before (Old Implementation)
// Direct use of jitsi_room_url
<a href={booking.jitsi_room_url} target="_blank">
Join Meeting
</a>
Problems:
- Users join as "Booking ID" or generic name
- No admin differentiation
- Same link for everyone
After (New Implementation)
// Use personalized_meeting_url for users
<button onClick={() => window.open(booking.personalized_meeting_url, '_blank')}>
Join Meeting
</button>
// Use admin_meeting_url for admins
<button onClick={() => window.open(booking.admin_meeting_url, '_blank')}>
Join as Moderator
</button>
Benefits:
- Users join with their actual names
- Admins get moderator privileges
- Better user experience
Testing Checklist
Test as Regular User
- ✅ Login as regular user
- ✅ Create a booking
- ✅ Call
GET /api/bookings - ✅ Verify
personalized_meeting_urlcontains your name - ✅ Open the URL and confirm name appears in Jitsi
- ✅ Check email notification has personalized link
Test as Admin
- ✅ Login as admin
- ✅ Call
GET /api/admin/bookings - ✅ Verify
admin_meeting_urlcontains admin name and moderator config - ✅ Open the URL and confirm moderator privileges
- ✅ Verify audio/video enabled by default
- ✅ Check email notification has admin link (if admin books for themselves)
Test Email Notifications
- ✅ Create a booking
- ✅ Check "Meeting Info" email
- ✅ Verify "Join Meeting" button uses personalized link
- ✅ Click link and confirm name is pre-filled
- ✅ Wait for reminder email
- ✅ Verify reminder also has personalized link
Security Considerations
Authorization
- Regular users can only access their own bookings via
/api/bookings - Admins can access all bookings via
/api/admin/bookings /api/meetings/:id/linkenforces ownership or admin check
Link Sharing
- Personalized links include user-specific information
- Links are generated on-demand, not stored
- Original
jitsi_room_urlremains unchanged in database
Token Expiration
- All endpoints require valid JWT authentication
- Expired tokens require re-authentication
- Meeting links remain valid regardless of token expiration
Backward Compatibility
The jitsi_room_url field is still present in all responses for backward compatibility. However, frontends should migrate to using:
personalized_meeting_urlfor regular usersadmin_meeting_urlfor admins/api/meetings/:id/linkendpoint for dynamic link generation
Troubleshooting
Issue: Name still shows as "Booking ID"
Solution: Ensure you're using personalized_meeting_url or admin_meeting_url instead of jitsi_room_url
Issue: Admin doesn't have moderator privileges
Solution:
- Verify user's
is_adminfield istruein database - Check that
admin_meeting_urlincludes moderator config parameters - Ensure using
/api/admin/bookingsendpoint, not/api/bookings
Issue: Email links don't have personalized URLs
Solution:
- Verify notification service is generating personalized URLs
- Check email template uses
{{.JoinURL}}field - Ensure user has valid first/last name or email
Issue: Display name is email instead of name
Solution: Update user's first_name and last_name fields in the database
Future Enhancements
Potential improvements:
- Custom Display Names: Allow users to set custom display names
- Meeting Roles: Support different roles beyond admin/user (e.g., observer, presenter)
- Link Expiration: Add time-based expiration to meeting links
- Waiting Room: Implement waiting room for participants before admin joins
- Custom Branding: Add organization-specific branding to Jitsi interface