Files
pos-system/services/mkt-whatsapp-service-net/src/WhatsAppService.API/Controllers/ConversationsController.cs

171 lines
5.2 KiB
C#

using MediatR;
using Microsoft.AspNetCore.Mvc;
using WhatsAppService.API.Application.Commands;
using WhatsAppService.Domain.AggregatesModel.ConversationAggregate;
namespace WhatsAppService.API.Controllers;
/// <summary>
/// EN: Controller for managing conversations.
/// VI: Controller để quản lý conversations.
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class ConversationsController : ControllerBase
{
private readonly IMediator _mediator;
private readonly IConversationRepository _repository;
private readonly ILogger<ConversationsController> _logger;
public ConversationsController(
IMediator mediator,
IConversationRepository repository,
ILogger<ConversationsController> logger)
{
_mediator = mediator;
_repository = repository;
_logger = logger;
}
/// <summary>
/// EN: Get conversations by shop with pagination.
/// VI: Lấy conversations theo shop với phân trang.
/// </summary>
[HttpGet]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
public async Task<IActionResult> GetConversations(
[FromQuery] Guid shopId,
[FromQuery] string? status,
[FromQuery] int skip = 0,
[FromQuery] int take = 20)
{
ConversationStatus? statusFilter = null;
if (!string.IsNullOrEmpty(status))
{
statusFilter = ConversationStatus.FromName(status);
}
var conversations = await _repository.GetByShopIdAsync(shopId, skip, take, statusFilter);
return Ok(new
{
success = true,
data = conversations.Select(c => new
{
id = c.Id,
customerWaId = c.CustomerWaId,
status = c.Status.Name,
assignedAgentId = c.AssignedAgentId,
lastMessageAt = c.LastMessageAt,
createdAt = c.CreatedAt,
expiresAt = c.ExpiresAt,
messageCount = c.Messages.Count
})
});
}
/// <summary>
/// EN: Get conversation by ID with messages.
/// VI: Lấy conversation theo ID kèm messages.
/// </summary>
[HttpGet("{id:guid}")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetById(Guid id)
{
var conversation = await _repository.GetByIdAsync(id);
if (conversation == null)
{
return NotFound(new { success = false, error = "Conversation not found" });
}
return Ok(new
{
success = true,
data = new
{
id = conversation.Id,
customerWaId = conversation.CustomerWaId,
status = conversation.Status.Name,
assignedAgentId = conversation.AssignedAgentId,
lastMessageAt = conversation.LastMessageAt,
createdAt = conversation.CreatedAt,
expiresAt = conversation.ExpiresAt,
messages = conversation.Messages.OrderBy(m => m.Timestamp).Select(m => new
{
id = m.Id,
direction = m.Direction,
contentType = m.Content.Type,
text = m.Content.Text,
status = m.Status,
timestamp = m.Timestamp
})
}
});
}
/// <summary>
/// EN: Send a message in conversation.
/// VI: Gửi tin nhắn trong conversation.
/// </summary>
[HttpPost("{id:guid}/messages")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> SendMessage(Guid id, [FromBody] SendMessageRequest request)
{
var command = new SendMessageCommand(
id,
request.Type,
request.Text,
request.MediaUrl,
request.Caption,
request.Interactive);
var result = await _mediator.Send(command);
if (!result.Success)
{
return BadRequest(new { success = false, error = result.Error });
}
return Ok(new
{
success = true,
data = new
{
messageId = result.MessageId,
whatsAppMessageId = result.WhatsAppMessageId
}
});
}
/// <summary>
/// EN: Close a conversation.
/// VI: Đóng conversation.
/// </summary>
[HttpPost("{id:guid}/close")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Close(Guid id)
{
var conversation = await _repository.GetByIdAsync(id);
if (conversation == null)
{
return NotFound(new { success = false, error = "Conversation not found" });
}
conversation.Close();
await _repository.UnitOfWork.SaveEntitiesAsync();
return NoContent();
}
}
public record SendMessageRequest(
string Type,
string? Text,
string? MediaUrl,
string? Caption,
object? Interactive);