feat(push): add service-owned firebase channels and delivery
Add push contracts, provider delivery and channel diagnostics. Link email channels to services and document migration and validation. Ref: IT-1074
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using HrynCo.NotificationService.Contracts.Messages;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Push;
|
||||
using HrynCo.NotificationService.DAL.Abstract.PushChannels;
|
||||
using HrynCo.NotificationService.DAL.Abstract.Repositories;
|
||||
|
||||
namespace HrynCo.NotificationService.Worker.Services.Push;
|
||||
|
||||
public sealed class FcmPushSender(
|
||||
INotificationServiceRepository services, IPushChannelRepository channels, IFirebasePushClient client) : IPushSender
|
||||
{
|
||||
public async Task<PushDeliveryOutcome> SendAsync(Guid messageId, SendPushMessageData data, CancellationToken cancellationToken)
|
||||
{
|
||||
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.");
|
||||
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);
|
||||
}
|
||||
|
||||
private async Task<PushDeliveryOutcome> SendWithCredentialsAsync(Guid messageId, SendPushMessageData data,
|
||||
string projectId, string? json, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var credentials = FirebaseServiceAccountCredentials.Parse(json ?? string.Empty, projectId);
|
||||
return await client.SendAsync(messageId, data, credentials, ct);
|
||||
}
|
||||
catch (Exception error) when (error is JsonException or FormatException or ArgumentException or CryptographicException)
|
||||
{
|
||||
// Never propagate credential parser details into broker retry logs or replies.
|
||||
return new PushDeliveryOutcome("The push channel Firebase configuration is invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user