✨ Implement realtime chat
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
using DysonNetwork.Sphere.Chat.Realtime;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -6,16 +7,60 @@ namespace DysonNetwork.Sphere.Chat;
|
||||
|
||||
public class RealtimeChatConfiguration
|
||||
{
|
||||
public string Provider { get; set; } = null!;
|
||||
public string Endpoint { get; set; } = null!;
|
||||
}
|
||||
|
||||
[ApiController]
|
||||
[Route("/chat/realtime")]
|
||||
public class RealtimeCallController(IConfiguration configuration, AppDatabase db, ChatService cs) : ControllerBase
|
||||
public class RealtimeCallController(IConfiguration configuration, AppDatabase db, ChatService cs, IRealtimeService realtime) : ControllerBase
|
||||
{
|
||||
private readonly RealtimeChatConfiguration _config =
|
||||
configuration.GetSection("RealtimeChat").Get<RealtimeChatConfiguration>()!;
|
||||
|
||||
[HttpGet("{roomId:guid}/join")]
|
||||
[Authorize]
|
||||
public async Task<IActionResult> JoinCall(Guid roomId)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized();
|
||||
|
||||
// Check if the user is a member of the chat room
|
||||
var member = await db.ChatMembers
|
||||
.Where(m => m.AccountId == currentUser.Id && m.ChatRoomId == roomId)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (member == null || member.Role < ChatMemberRole.Member)
|
||||
return StatusCode(403, "You need to be a member to join a call.");
|
||||
|
||||
// Get ongoing call
|
||||
var ongoingCall = await cs.GetCallOngoingAsync(roomId);
|
||||
if (ongoingCall is null)
|
||||
return NotFound("There is no ongoing call in this room.");
|
||||
|
||||
// Check if session ID exists
|
||||
if (string.IsNullOrEmpty(ongoingCall.SessionId))
|
||||
return BadRequest("Call session is not properly configured.");
|
||||
|
||||
var isAdmin = member.Role >= ChatMemberRole.Moderator;
|
||||
var userToken = realtime.GetUserToken(currentUser, ongoingCall.SessionId, isAdmin);
|
||||
|
||||
// Get LiveKit endpoint from configuration
|
||||
string endpoint = _config.Endpoint ??
|
||||
throw new InvalidOperationException("LiveKit endpoint configuration is missing");
|
||||
|
||||
// Create response model
|
||||
var response = new JoinCallResponse
|
||||
{
|
||||
Provider = realtime.ProviderName,
|
||||
Endpoint = endpoint,
|
||||
Token = userToken,
|
||||
CallId = ongoingCall.Id,
|
||||
RoomName = ongoingCall.SessionId,
|
||||
IsAdmin = isAdmin
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
[HttpPost("{roomId:guid}")]
|
||||
[Authorize]
|
||||
public async Task<IActionResult> StartCall(Guid roomId)
|
||||
@ -57,4 +102,38 @@ public class RealtimeCallController(IConfiguration configuration, AppDatabase db
|
||||
return BadRequest(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Response model for joining a call
|
||||
public class JoinCallResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The service provider name (e.g., "LiveKit")
|
||||
/// </summary>
|
||||
public string Provider { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The LiveKit server endpoint
|
||||
/// </summary>
|
||||
public string Endpoint { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Authentication token for the user
|
||||
/// </summary>
|
||||
public string Token { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The call identifier
|
||||
/// </summary>
|
||||
public Guid CallId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The room name in LiveKit
|
||||
/// </summary>
|
||||
public string RoomName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the user is the admin of the call
|
||||
/// </summary>
|
||||
public bool IsAdmin { get; set; }
|
||||
}
|
Reference in New Issue
Block a user