feat(templates): add localized push templates and actions
Share template keys across email and push with independent editors and revisions. Render localized actions and preserve version-one delivery. Ref: IT-1627
This commit is contained in:
@@ -4,24 +4,40 @@ using HrynCo.NotificationService.Contracts.Messages;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Push;
|
||||
using HrynCo.NotificationService.DAL.Abstract.PushChannels;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Templates;
|
||||
|
||||
namespace HrynCo.NotificationService.Worker.Services.Push;
|
||||
|
||||
public sealed class FcmPushSender(
|
||||
INotificationServiceRepository services, IPushChannelRepository channels, IFirebasePushClient client) : IPushSender
|
||||
INotificationServiceRepository services, IPushChannelRepository channels, IFirebasePushClient client,
|
||||
IPushTemplateDefinitionRepository templates) : IPushSender
|
||||
{
|
||||
public async Task<PushDeliveryOutcome> SendAsync(Guid messageId, SendPushMessageData data, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!PushMessageValidator.IsSupportedVersion(data.Version))
|
||||
return new PushDeliveryOutcome("Unsupported push payload version. Supported versions are 1 and 2.");
|
||||
if (!PushMessageValidator.IsValidContent(data)) return new PushDeliveryOutcome("Invalid push content for the requested version.");
|
||||
if (data.ExpiresAt <= DateTimeOffset.UtcNow) return new PushDeliveryOutcome("Push expired.");
|
||||
var service = await services.GetByNameAsync(data.ServiceName, cancellationToken);
|
||||
if (service is null) return new PushDeliveryOutcome("Push service is not configured.");
|
||||
RenderedPushMessageData rendered;
|
||||
try { rendered = await RenderAsync(service.Id, data, cancellationToken); }
|
||||
catch (EmailTemplateWriteException) { return new PushDeliveryOutcome("Push template data or action configuration is invalid."); }
|
||||
var channel = await channels.GetActiveForServiceAsync(service.Id, cancellationToken);
|
||||
if (channel is null) return new PushDeliveryOutcome("No active push channel is configured for this service.");
|
||||
var credentials = await channels.GetCredentialsAsync(channel.Id, cancellationToken);
|
||||
return await SendWithCredentialsAsync(messageId, data, channel.FirebaseProjectId, credentials, cancellationToken);
|
||||
return await SendWithCredentialsAsync(messageId, rendered, channel.FirebaseProjectId, credentials, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<PushDeliveryOutcome> SendWithCredentialsAsync(Guid messageId, SendPushMessageData data,
|
||||
private async Task<RenderedPushMessageData> RenderAsync(Guid serviceId, SendPushMessageData data, CancellationToken ct)
|
||||
{
|
||||
if (data.Version == 1) return new RenderedPushMessageData(data, data.Title!, data.Body!, null, []);
|
||||
var template = await templates.GetAsync(serviceId, data.TemplateKey!, ct)
|
||||
?? throw new EmailTemplateWriteException("Push template is not configured.", false);
|
||||
return PushTemplateRenderer.Render(template, data);
|
||||
}
|
||||
|
||||
private async Task<PushDeliveryOutcome> SendWithCredentialsAsync(Guid messageId, RenderedPushMessageData data,
|
||||
string projectId, string? json, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user