using System.Text.Json; using SPMS.Application.DTOs.Push; using SPMS.Application.Interfaces; using SPMS.Domain.Common; using SPMS.Domain.Exceptions; using SPMS.Domain.Interfaces; namespace SPMS.Application.Services; public class PushService : IPushService { private readonly IMessageRepository _messageRepository; private readonly IPushQueueService _pushQueueService; public PushService(IMessageRepository messageRepository, IPushQueueService pushQueueService) { _messageRepository = messageRepository; _pushQueueService = pushQueueService; } public async Task SendAsync(long serviceId, PushSendRequestDto request) { var message = await _messageRepository.GetByMessageCodeAndServiceAsync(request.MessageCode, serviceId); if (message == null) throw new SpmsException(ErrorCodes.MessageNotFound, "존재하지 않는 메시지 코드입니다.", 404); var title = ApplyVariables(message.Title, request.Variables); var body = ApplyVariables(message.Body, request.Variables); var requestId = Guid.NewGuid().ToString("N"); var pushMessage = new PushMessageDto { MessageId = message.Id.ToString(), RequestId = requestId, ServiceId = serviceId, SendType = "single", Title = title, Body = body, ImageUrl = message.ImageUrl, LinkUrl = message.LinkUrl, CustomData = ParseCustomData(message.CustomData), Target = new PushTargetDto { Type = "device_ids", Value = JsonSerializer.SerializeToElement(new[] { request.DeviceId }) }, CreatedBy = message.CreatedBy, CreatedAt = DateTime.UtcNow.ToString("o") }; await _pushQueueService.PublishPushMessageAsync(pushMessage); return new PushSendResponseDto { RequestId = requestId, SendType = "single", Status = "queued" }; } public async Task SendByTagAsync(long serviceId, PushSendTagRequestDto request) { var message = await _messageRepository.GetByMessageCodeAndServiceAsync(request.MessageCode, serviceId); if (message == null) throw new SpmsException(ErrorCodes.MessageNotFound, "존재하지 않는 메시지 코드입니다.", 404); var requestId = Guid.NewGuid().ToString("N"); var pushMessage = new PushMessageDto { MessageId = message.Id.ToString(), RequestId = requestId, ServiceId = serviceId, SendType = "group", Title = message.Title, Body = message.Body, ImageUrl = message.ImageUrl, LinkUrl = message.LinkUrl, CustomData = ParseCustomData(message.CustomData), Target = new PushTargetDto { Type = "tags", Value = JsonSerializer.SerializeToElement(new { tags = request.Tags, match = request.TagMatch }) }, CreatedBy = message.CreatedBy, CreatedAt = DateTime.UtcNow.ToString("o") }; await _pushQueueService.PublishPushMessageAsync(pushMessage); return new PushSendResponseDto { RequestId = requestId, SendType = "group", Status = "queued" }; } private static string ApplyVariables(string template, Dictionary? variables) { if (variables == null || variables.Count == 0) return template; var result = template; foreach (var (key, value) in variables) { result = result.Replace($"{{{{{key}}}}}", value); } return result; } private static Dictionary? ParseCustomData(string? customData) { if (string.IsNullOrWhiteSpace(customData)) return null; return JsonSerializer.Deserialize>(customData); } }