using AcaMate.Common.Models; using AcaMate.V1.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Update.Internal; using AcaMate.Common.Data; using AcaMate.V1.Services; namespace AcaMate.V1.Controllers; [ApiController] [Route("/api/v1/in/push")] [ApiExplorerSettings(GroupName = "공통")] public class PushController : ControllerBase { private readonly ILogger _logger; private readonly IPushQueue _pushQueue; private readonly AppDbContext _dbContext; private readonly IRepositoryService _repositoryService; public PushController(ILogger logger, IPushQueue pushQueue, AppDbContext dbContext, IRepositoryService repositoryService) { _logger = logger; _pushQueue = pushQueue; _dbContext = dbContext; _repositoryService = repositoryService; } [HttpGet()] [CustomOperation("푸시 확인", "저장된 양식을 확인 할 수 있다..", "푸시")] public IActionResult GetPushData() { return Ok("SEND"); } /// /// Sends a push notification to the specified device token with the provided payload. /// /// /// An IActionResult indicating the result of the operation. /// Push notification sent successfully. /// Invalid input parameters. /// Internal server error occurred. /// Service unavailable. [HttpPost("send")] [CustomOperation("푸시전송", "저장된 양식으로, 사용자에게 푸시를 전송한다.(로컬 테스트 불가)", "푸시")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(APIResponseStatus))] public async Task SendPush([FromBody] PushRequest pushRequest) { if (!ModelState.IsValid) return BadRequest(APIResponse.InvalidInputError()); try { var payload = await _dbContext.DBPayload .Where(p => p.pid == pushRequest.pid) .Select(p => new Payload { aps = new Aps { alert = new Alert { title = p.title, body = p.body, subtitle = p.subtitle ?? "" }, category = p.category }, pid = pushRequest.pid, content = p.content ?? "", }) .FirstOrDefaultAsync(); await Task.Run(async () => { foreach (var uid in pushRequest.uids) { var badge = await _dbContext.PushCabinet .Where(c => c.uid == uid && c.check_yn == false && c.pid != pushRequest.pid) .CountAsync(); var pushToken = await _dbContext.User .Where(u => u.uid == uid) .Select(u => u.push_token) .FirstOrDefaultAsync() ?? ""; var pushCabinet = new PushCabinet { uid = uid, pid = pushRequest.pid, send_date = DateTime.Now, }; if (payload != null) payload.aps.badge = badge + 1; var pushData = new PushData { pushToken = pushToken, payload = payload ?? throw new PushInvalidException("payload is NULL") }; await _repositoryService.SaveDataFK(pushCabinet); _pushQueue.Enqueue(pushData); } }); return Ok(APIResponse.Send("000", "정상", Empty)); } catch (PushInvalidException ex) { _logger.LogError(ex.Message); return Ok(APIResponse.Send("001", "푸시 송신: 푸시 전송 중 문제 발생",Empty)); } catch (Exception ex) { _logger.LogError($"[푸시] {ex.Message}"); return StatusCode(500, APIResponse.UnknownError()); } } }