@ -53,89 +53,94 @@ class CourseLiveSessionRoomCreateAPIView(GenericAPIView):
# 2. Setup ID and Metadata
room_id = f " room-{course.id}-imamjavad "
subject = f " {course.title} Live Session "
metadata = self . _build_metadata ( subject )
# 3. Use your CLEAN PlugNMeetClient
try :
client = PlugNMeetClient ( ) # Loads keys from settings automatically
# This uses the keys internally to talk to the server
plugnmeet_response = client . create_room ( {
' room_id ' : room_id ,
' metadata ' : metadata ,
} )
# 4. Generate the JOIN TOKEN (The Entry Ticket)
# Users CANNOT enter without this.
token_payload = {
" room_id " : room_id ,
" user_info " : {
" name " : f " {request.user.first_name} {request.user.last_name} " ,
" user_id " : str ( request . user . id ) ,
" is_admin " : True ,
" is_hidden " : False
}
}
# Check if your client has a method for this, otherwise use manual:
# access_token = client.get_join_token(token_payload)
# If not, we do it manually here using the SAME secret from settings:
pnm_token = jwt . encode (
{
" iss " : settings . PLUGNMEET_API_KEY ,
" exp " : int ( time . time ( ) ) + 3600 ,
" sub " : str ( request . user . id ) ,
* * token_payload
} ,
settings . PLUGNMEET_API_SECRET ,
algorithm = " HS256 "
)
except Exception as exc :
logger . error ( f " PlugNMeet Error: {exc} " )
raise AppAPIException ( { ' message ' : str ( exc ) } , status_code = 500 )
# 5. Database Logic
# 3. Database Logic - Check FIRST before calling PlugNMeet
# Strategy:
# 1. Try to find active session (ended_at is NULL)
# 2. If not found, try to find ended session with same room_id and reactivate it
# 3. If not found, create new session
session = None
needs_room_creation = False
try :
# Try to get active session first
session = CourseLiveSession . objects . get (
course = course , room_id = room_id , ended_at__isnull = True
)
created = False
logger . info ( f " [LiveSession Create] Reusing active session - session_id={session.id} room_id={room_id} " )
needs_room_creation = False
logger . info ( f " [LiveSession Create] Found active session - session_id={session.id} room_id={room_id} " )
except CourseLiveSession . DoesNotExist :
# No active session, check if there's an old one with same room_id
try :
session = CourseLiveSession . objects . get (
course = course , room_id = room_id
)
# Reactivate the old session
# Reactivate the old session and mark for room recreation
session . ended_at = None
session . started_at = timezone . now ( )
session . subject = subject
session . save ( update_fields = [ ' ended_at ' , ' started_at ' , ' subject ' , ' updated_at ' ] )
created = Fals e
needs_room_creation = Tru e
logger . info ( f " [LiveSession Create] Reactivated ended session - session_id={session.id} room_id={room_id} " )
except CourseLiveSession . DoesNotExist :
# No session exists at all, create new one
# No session exists at all, create new one and mark for room creation
session = CourseLiveSession . objects . create (
course = course ,
room_id = room_id ,
subject = subject ,
started_at = timezone . now ( )
)
created = True
needs_room_creation = True
logger . info ( f " [LiveSession Create] Created new session - session_id={session.id} room_id={room_id} " )
# 4. Create room in PlugNMeet ONLY if needed
if needs_room_creation :
metadata = self . _build_metadata ( subject )
try :
client = PlugNMeetClient ( )
plugnmeet_response = client . create_room ( {
' room_id ' : room_id ,
' metadata ' : metadata ,
} )
logger . info ( f " [LiveSession Create] Room created in PlugNMeet - room_id={room_id} " )
except Exception as exc :
logger . error ( f " [LiveSession Create] PlugNMeet Error: {exc} " )
# If room creation fails, revert the session changes
if session . ended_at is None :
session . ended_at = timezone . now ( )
session . save ( update_fields = [ ' ended_at ' , ' updated_at ' ] )
raise AppAPIException ( { ' message ' : f ' Failed to create room: {str(exc)} ' } , status_code = 500 )
else :
logger . info ( f " [LiveSession Create] Skipping room creation - room already exists - room_id={room_id} " )
# 5. Generate the JOIN TOKEN (The Entry Ticket)
token_payload = {
" room_id " : room_id ,
" user_info " : {
" name " : f " {request.user.first_name} {request.user.last_name} " ,
" user_id " : str ( request . user . id ) ,
" is_admin " : True ,
" is_hidden " : False
}
}
pnm_token = jwt . encode (
{
" iss " : settings . PLUGNMEET_API_KEY ,
" exp " : int ( time . time ( ) ) + 3600 ,
" sub " : str ( request . user . id ) ,
* * token_payload
} ,
settings . PLUGNMEET_API_SECRET ,
algorithm = " HS256 "
)
logger . info ( f " [LiveSession Create] Success - session_id={session.id} room_id={room_id} user_id={request.user.id} " )
return Response ( {
' success ' : True ,
' session ' : { ' id ' : session . id , ' room_id ' : session . room_id } ,
' access_token ' : pnm_token # <--- REQUIRED for frontend
' access_token ' : pnm_token
} , status = 201 )