public async Task PublishAsync(EventMessage message, CancellationToken ct = default) { if (string.IsNullOrWhiteSpace(message.AppId)) { return; } if (string.IsNullOrWhiteSpace(message.Topic)) { await logStore.LogAsync(message.AppId, Texts.Events_NoTopic, ct); return; } if (string.IsNullOrWhiteSpace(message.TemplateCode) && message.Formatting?.HasSubject() != true) { await logStore.LogAsync(message.AppId, Texts.Events_NoSubjectOrTemplateCode, ct); return; } var count = 0; await foreach (var subscription in GetSubscriptions(message).WithCancellation(ct)) { if (count == 0) { if (!string.IsNullOrWhiteSpace(message.TemplateCode)) { var template = await templateStore.GetAsync(message.AppId, message.TemplateCode, ct); if (template != null && !template.IsAutoCreated) { message.Formatting = template.Formatting; if (template.Settings != null && template.Settings.Count > 0) { var settings = new NotificationSettings(); settings.OverrideBy(template.Settings); settings.OverrideBy(message.Settings); message.Settings = settings; } } } if (message.Formatting?.HasSubject() != true) { await logStore.LogAsync(message.AppId, string.Format(Texts.Template_NoSubject, message.TemplateCode), ct); return; } message.Formatting = message.Formatting.Format(message.Properties); try { await eventStore.InsertAsync(message, ct); } catch (UniqueConstraintException) { await logStore.LogAsync(message.AppId, Texts.Events_AlreadyProcessed, ct); break; } } var userEventMessage = CreateUserEventMessage(message, subscription); await userEventProducer.ProduceAsync(subscription.UserId, userEventMessage); count++; } if (count > 0) { var counterMap = CounterMap.ForNotification(ProcessStatus.Attempt, count); var counterKey = CounterKey.ForEvent(message); await counters.CollectAsync(counterKey, counterMap, ct); } else { await logStore.LogAsync(message.AppId, Texts.Events_NoSubscriber, ct); } }
public async Task PublishAsync(EventMessage @event, CancellationToken ct) { using (var activity = Telemetry.Activities.StartActivity("HandleUserEvent")) { log.LogInformation("Received event for app {appId} with ID {id} to topic {topic}.", @event.AppId, @event.Id, @event.Topic); if (string.IsNullOrWhiteSpace(@event.AppId)) { log.LogInformation("Received invalid event with ID {id} to topic {topic}: No app id found.", @event.Id, @event.Topic); return; } if (string.IsNullOrWhiteSpace(@event.Topic)) { await logStore.LogAsync(@event.AppId, Texts.Events_NoTopic); return; } if (string.IsNullOrWhiteSpace(@event.TemplateCode) && @event.Formatting?.HasSubject() != true) { await logStore.LogAsync(@event.AppId, Texts.Events_NoSubjectOrTemplateCode); return; } var count = 0; await foreach (var subscription in GetSubscriptions(@event, ct)) { ct.ThrowIfCancellationRequested(); if (count == 0) { var templateCode = (string?)null; if (@event.TemplateVariants?.Count > 0) { var random = randomizer.NextDouble(); var propability = 0d; foreach (var(key, value) in @event.TemplateVariants) { propability += value; if (random <= propability) { templateCode = key; break; } } } if (string.IsNullOrWhiteSpace(templateCode)) { templateCode = @event.TemplateCode; } if (!string.IsNullOrWhiteSpace(templateCode)) { var template = await templateStore.GetAsync(@event.AppId, templateCode, ct); if (template?.IsAutoCreated == false) { if (@event.Formatting != null) { @event.Formatting = template.Formatting.MergedWith(@event.Formatting); } else { @event.Formatting = template.Formatting; } @event.Settings = ChannelSettings.Merged(template.Settings, @event.Settings); } } if (@event.Formatting?.HasSubject() != true) { await logStore.LogAsync(@event.AppId, string.Format(CultureInfo.InvariantCulture, Texts.Template_NoSubject, templateCode)); return; } if (@event.Properties != null) { @event.Formatting = @event.Formatting.Format(@event.Properties); } try { await eventStore.InsertAsync(@event, ct); } catch (UniqueConstraintException) { await logStore.LogAsync(@event.AppId, Texts.Events_AlreadyProcessed); break; } } var userEventMessage = CreateUserEventMessage(@event, subscription); if (activity != null) { userEventMessage.UserEventActivity = activity.Context; } await ProduceAsync(subscription, userEventMessage); count++; } if (count > 0) { var counterMap = CounterMap.ForNotification(ProcessStatus.Attempt, count); var counterKey = CounterKey.ForEvent(@event); await counters.CollectAsync(counterKey, counterMap, ct); } else { await logStore.LogAsync(@event.AppId, Texts.Events_NoSubscriber); } log.LogInformation("Processed event for app {appId} with ID {id} to topic {topic}.", @event.AppId, @event.Id, @event.Topic); } }