From 01dd4f28ca99467164a24e0e3f7cadc8bada1ca7 Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 5 Aug 2025 12:07:20 -0400 Subject: [PATCH 01/10] Added controller for batched events. --- .../Controllers/WebhookEventsController.cs | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs index 308cd51..13cb7f2 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs @@ -3,10 +3,11 @@ using Microsoft.Extensions.Options; using SocketLabs.EventWebhooks.Extensions.Configuration; using SocketLabs.EventWebhooks.Extensions.Models.Events; +using SocketLabs.EventWebhooks.Extensions.Models.Inbound; namespace SocketLabs.EventWebhooks.Extensions.Controllers { - [Route("api/v1/[controller]")] + [Route("api/v1/[controller]/{id}")] [ApiController] public class WebhookEventsController : ControllerBase { @@ -26,7 +27,6 @@ IOptionsMonitor options } [HttpPost] - [Route("{id}")] public async Task Post(WebhookEventBase webhookEvent, string id) { if (!_options.TryGetWebhook(id, out var endpoint) || endpoint?.SecretKey != webhookEvent.SecretKey) @@ -61,6 +61,44 @@ public async Task Post(WebhookEventBase webhookEvent, string id) return Ok(); } + [HttpPost] + public async Task Post(WebhookEventBase[] webhookEvents, string id) + { + foreach (var webhookEvent in webhookEvents) + { + if (!_options.TryGetWebhook(id, out var endpoint) || endpoint?.SecretKey != webhookEvent.SecretKey) + { + return Unauthorized(); + } + + try + { + webhookEvent.WebhookEndpointName = id; + + Task result = webhookEvent switch + { + ComplaintEvent eventItem => ProcessEvent(eventItem), + DeferredEvent eventItem => ProcessEvent(eventItem), + EngagementEvent eventItem => ProcessEvent(eventItem), + FailedEvent eventItem => ProcessEvent(eventItem), + QueuedEvent eventItem => ProcessEvent(eventItem), + SentEvent eventItem => ProcessEvent(eventItem), + ValidationEvent eventItem => ProcessEvent(eventItem), + _ => throw new InvalidOperationException("Unable to convert event type.") + }; + + await result; + } + catch (Exception ex) + { + _logger.LogError(ex, "Unable to process webhook event."); + return BadRequest(); + } + + } + + return Ok(); + } private async Task ProcessEvent(ComplaintEvent webhookEvent) { From ca19c9778f31fc2dd2a6b55f12b36cde704e0fa8 Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 5 Aug 2025 12:19:50 -0400 Subject: [PATCH 02/10] Refactored to use a single action that accepts an array (the model binder will bind a single object as a one-element array). Fixed default event to error more gracefully. --- .../Controllers/WebhookEventsController.cs | 62 +++++-------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs index 13cb7f2..5294c4d 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs @@ -27,42 +27,7 @@ IOptionsMonitor options } [HttpPost] - public async Task Post(WebhookEventBase webhookEvent, string id) - { - if (!_options.TryGetWebhook(id, out var endpoint) || endpoint?.SecretKey != webhookEvent.SecretKey) - { - return Unauthorized(); - } - - try - { - webhookEvent.WebhookEndpointName = id; - - Task result = webhookEvent switch - { - ComplaintEvent eventItem => ProcessEvent(eventItem), - DeferredEvent eventItem => ProcessEvent(eventItem), - EngagementEvent eventItem => ProcessEvent(eventItem), - FailedEvent eventItem => ProcessEvent(eventItem), - QueuedEvent eventItem => ProcessEvent(eventItem), - SentEvent eventItem => ProcessEvent(eventItem), - ValidationEvent eventItem => ProcessEvent(eventItem), - _ => throw new InvalidOperationException("Unable to convert event type.") - }; - - await result; - } - catch (Exception ex) - { - _logger.LogError(ex, "Unable to process webhook event."); - - return BadRequest(); - } - - return Ok(); - } - [HttpPost] - public async Task Post(WebhookEventBase[] webhookEvents, string id) + public async Task Post([FromBody] WebhookEventBase[] webhookEvents, string id) { foreach (var webhookEvent in webhookEvents) { @@ -75,7 +40,7 @@ public async Task Post(WebhookEventBase[] webhookEvents, string i { webhookEvent.WebhookEndpointName = id; - Task result = webhookEvent switch + Task? result = webhookEvent switch { ComplaintEvent eventItem => ProcessEvent(eventItem), DeferredEvent eventItem => ProcessEvent(eventItem), @@ -84,9 +49,14 @@ public async Task Post(WebhookEventBase[] webhookEvents, string i QueuedEvent eventItem => ProcessEvent(eventItem), SentEvent eventItem => ProcessEvent(eventItem), ValidationEvent eventItem => ProcessEvent(eventItem), - _ => throw new InvalidOperationException("Unable to convert event type.") + _ => null }; + if (result == null) + { + _logger.LogError("Unable to convert event type: {EventType} for MessageId: {MessageId}", webhookEvent.GetType().Name, webhookEvent.MessageId); + return BadRequest($"Unknown event type: {webhookEvent.GetType().Name}"); + } await result; } catch (Exception ex) @@ -94,55 +64,55 @@ public async Task Post(WebhookEventBase[] webhookEvents, string i _logger.LogError(ex, "Unable to process webhook event."); return BadRequest(); } - } return Ok(); } - private async Task ProcessEvent(ComplaintEvent webhookEvent) + + private async Task? ProcessEvent(ComplaintEvent webhookEvent) { webhookEvent.Type = "Complaint"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task ProcessEvent(DeferredEvent webhookEvent) + private async Task? ProcessEvent(DeferredEvent webhookEvent) { webhookEvent.Type = "Deferred"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task ProcessEvent(EngagementEvent webhookEvent) + private async Task? ProcessEvent(EngagementEvent webhookEvent) { webhookEvent.Type = "Tracking"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task ProcessEvent(FailedEvent webhookEvent) + private async Task? ProcessEvent(FailedEvent webhookEvent) { webhookEvent.Type = "Failed"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task ProcessEvent(QueuedEvent webhookEvent) + private async Task? ProcessEvent(QueuedEvent webhookEvent) { webhookEvent.Type = "Queued"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task ProcessEvent(SentEvent webhookEvent) + private async Task? ProcessEvent(SentEvent webhookEvent) { webhookEvent.Type = "Delivered"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task ProcessEvent(ValidationEvent webhookEvent) + private async Task? ProcessEvent(ValidationEvent webhookEvent) { webhookEvent.Type = "Validation"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); From 235babed0c4463005e75bf19f420e157251181a1 Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Wed, 6 Aug 2025 09:15:37 -0400 Subject: [PATCH 03/10] Fixed parse endpoint error handling of unknown events. --- .../Controllers/ParsedMessagesController.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/ParsedMessagesController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/ParsedMessagesController.cs index 8fa24ee..25cc5a6 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/ParsedMessagesController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/ParsedMessagesController.cs @@ -41,13 +41,19 @@ public async Task Post(WebhookEventBase webhookEvent, string id) { webhookEvent.WebhookEndpointName = id; - Task result = webhookEvent switch + Task? result = webhookEvent switch { MessageParsedEvent eventItem => ProcessEvent(eventItem), ValidationEvent eventItem => ProcessEvent(eventItem), - _ => throw new InvalidOperationException("Unable to convert event type.") + _ => null }; + if (result == null) + { + _logger.LogError("Unable to convert event type: {EventType} for MessageId: {MessageId}", webhookEvent.GetType().Name, webhookEvent.MessageId); + return BadRequest($"Unknown event type: {webhookEvent.GetType().Name}"); + } + await result; } catch (Exception ex) From 7ddb8a70183467b359a21d5c60b901ca722e8b27 Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Mon, 11 Aug 2025 14:48:41 -0400 Subject: [PATCH 04/10] Added single event endpoint on controller. --- .../Controllers/WebhookEventsController.cs | 6 ++++++ .../SocketLabs.EventWebhooks.Extensions.csproj | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs index 5294c4d..80906dc 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs @@ -26,6 +26,12 @@ IOptionsMonitor options _options = options.CurrentValue; } + [HttpPost] + public async Task Post([FromBody] WebhookEventBase webhookEvents, string id) + { + return await Post([webhookEvents], id); + } + [HttpPost] public async Task Post([FromBody] WebhookEventBase[] webhookEvents, string id) { diff --git a/src/SocketLabs.EventWebhooks.Extensions/SocketLabs.EventWebhooks.Extensions.csproj b/src/SocketLabs.EventWebhooks.Extensions/SocketLabs.EventWebhooks.Extensions.csproj index 660822c..24d8789 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/SocketLabs.EventWebhooks.Extensions.csproj +++ b/src/SocketLabs.EventWebhooks.Extensions/SocketLabs.EventWebhooks.Extensions.csproj @@ -14,7 +14,7 @@ icon.png README.md LICENSE.md - + 13.0 From afc77a0721c60a8ef89fd9d58cb1dd2cd9cf0919 Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 12 Aug 2025 10:07:57 -0400 Subject: [PATCH 05/10] Fixed batching to use a single action method with custom json converter. --- .../Controllers/WebhookEventsController.cs | 14 ++++---- .../Models/Events/WebhookEventBase.cs | 4 +++ .../Models/Events/WebhookEventConverter.cs | 32 +++++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs index 80906dc..536acee 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs @@ -25,16 +25,12 @@ IOptionsMonitor options _logger = logger; _options = options.CurrentValue; } - + [HttpPost] - public async Task Post([FromBody] WebhookEventBase webhookEvents, string id) + public async Task Post(WebhookEventBatch? webhookEvents, string id) { - return await Post([webhookEvents], id); - } + if (webhookEvents == null) return BadRequest(); - [HttpPost] - public async Task Post([FromBody] WebhookEventBase[] webhookEvents, string id) - { foreach (var webhookEvent in webhookEvents) { if (!_options.TryGetWebhook(id, out var endpoint) || endpoint?.SecretKey != webhookEvent.SecretKey) @@ -60,9 +56,11 @@ public async Task Post([FromBody] WebhookEventBase[] webhookEvent if (result == null) { - _logger.LogError("Unable to convert event type: {EventType} for MessageId: {MessageId}", webhookEvent.GetType().Name, webhookEvent.MessageId); + _logger.LogError("Unable to convert event type: {EventType} for MessageId: {MessageId}", + webhookEvent.GetType().Name, webhookEvent.MessageId); return BadRequest($"Unknown event type: {webhookEvent.GetType().Name}"); } + await result; } catch (Exception ex) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventBase.cs b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventBase.cs index 89afef1..5fdecb6 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventBase.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventBase.cs @@ -11,6 +11,10 @@ namespace SocketLabs.EventWebhooks.Extensions.Models.Events //[JsonDerivedType(typeof(QueuedEvent), typeDiscriminator: "Queued")] //[JsonDerivedType(typeof(DeferredEvent), typeDiscriminator: "Deferred")] + [JsonConverter(typeof(SingleOrArrayConverter))] + public class WebhookEventBatch : List + {} + [JsonConverter(typeof(WebhookEventConverter))] public abstract class WebhookEventBase { diff --git a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs index 8fb16ea..6d7dcb6 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs @@ -4,6 +4,38 @@ namespace SocketLabs.EventWebhooks.Extensions.Models.Events { + internal class SingleOrArrayConverter : JsonConverter + { + public override WebhookEventBatch? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.Null: + return null; + case JsonTokenType.StartArray: + var list = new WebhookEventBatch(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndArray) + break; + list.Add(JsonSerializer.Deserialize(ref reader, options)); + } + return list; + default: + return new WebhookEventBatch { JsonSerializer.Deserialize(ref reader, options) }; + } + } + + public override void Write( + Utf8JsonWriter writer, + WebhookEventBatch? objectToWrite, + JsonSerializerOptions options) => + JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); + } + internal class WebhookEventConverter : JsonConverter { public override WebhookEventBase? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) From 7784ba87f5a8bcd33d98df52a89277bf33bfe21c Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 12 Aug 2025 10:15:14 -0400 Subject: [PATCH 06/10] Fixed repetitive id check in loop. --- .../Controllers/WebhookEventsController.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs index 536acee..7200d54 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs @@ -30,13 +30,14 @@ IOptionsMonitor options public async Task Post(WebhookEventBatch? webhookEvents, string id) { if (webhookEvents == null) return BadRequest(); - + + if(!_options.TryGetWebhook(id, out var endpoint)) + return Unauthorized(); + foreach (var webhookEvent in webhookEvents) { - if (!_options.TryGetWebhook(id, out var endpoint) || endpoint?.SecretKey != webhookEvent.SecretKey) - { + if (endpoint?.SecretKey != webhookEvent.SecretKey) return Unauthorized(); - } try { From 476e0178a5ed78181e349dda6f8570fb4d4aa532 Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 12 Aug 2025 10:19:19 -0400 Subject: [PATCH 07/10] Fixed unneeded null tasks. --- .../Controllers/WebhookEventsController.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs index 7200d54..5091143 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs @@ -75,49 +75,49 @@ public async Task Post(WebhookEventBatch? webhookEvents, string i } - private async Task? ProcessEvent(ComplaintEvent webhookEvent) + private async Task ProcessEvent(ComplaintEvent webhookEvent) { webhookEvent.Type = "Complaint"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task? ProcessEvent(DeferredEvent webhookEvent) + private async Task ProcessEvent(DeferredEvent webhookEvent) { webhookEvent.Type = "Deferred"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task? ProcessEvent(EngagementEvent webhookEvent) + private async Task ProcessEvent(EngagementEvent webhookEvent) { webhookEvent.Type = "Tracking"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task? ProcessEvent(FailedEvent webhookEvent) + private async Task ProcessEvent(FailedEvent webhookEvent) { webhookEvent.Type = "Failed"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task? ProcessEvent(QueuedEvent webhookEvent) + private async Task ProcessEvent(QueuedEvent webhookEvent) { webhookEvent.Type = "Queued"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task? ProcessEvent(SentEvent webhookEvent) + private async Task ProcessEvent(SentEvent webhookEvent) { webhookEvent.Type = "Delivered"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); await _webhookEventHandler.ProcessAsync(webhookEvent); } - private async Task? ProcessEvent(ValidationEvent webhookEvent) + private async Task ProcessEvent(ValidationEvent webhookEvent) { webhookEvent.Type = "Validation"; _logger.LogTrace("Begin processing webhook event for {SystemMessageId}", webhookEvent.MessageId); From 7136aeb29fd0e0fd7df60032e99b8248aa94e097 Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 12 Aug 2025 10:26:21 -0400 Subject: [PATCH 08/10] Moved secret key check out of loop so the same batch isn't partially processed over and over with the same error. --- .../Controllers/WebhookEventsController.cs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs index 5091143..84b5d34 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Controllers/WebhookEventsController.cs @@ -31,14 +31,27 @@ public async Task Post(WebhookEventBatch? webhookEvents, string i { if (webhookEvents == null) return BadRequest(); - if(!_options.TryGetWebhook(id, out var endpoint)) + if(!_options.TryGetWebhook(id, out var endpoint) || endpoint==null) return Unauthorized(); - - foreach (var webhookEvent in webhookEvents) + + // Collect all events with mismatched secret keys + var mismatchedEvents = webhookEvents + .Where(e => e.SecretKey != endpoint.SecretKey) + .Select(e => e.MessageId ?? "(no MessageId)") + .ToList(); + + if (mismatchedEvents.Any()) { - if (endpoint?.SecretKey != webhookEvent.SecretKey) - return Unauthorized(); + _logger.LogWarning("SecretKey mismatch for events: {EventIds} on endpoint {Endpoint}", string.Join(", ", mismatchedEvents), id); + return Unauthorized(new + { + error = "One or more events have an invalid SecretKey.", + eventIds = mismatchedEvents + }); + } + foreach (var webhookEvent in webhookEvents) + { try { webhookEvent.WebhookEndpointName = id; From 9e03b40f3af5cc945ea419b2c0c48dbf01e1d83f Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 12 Aug 2025 10:49:12 -0400 Subject: [PATCH 09/10] Removed unneeded write overrides. Simplified array creation. --- .../Models/Events/WebhookEventConverter.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs index 6d7dcb6..3c654b8 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs @@ -25,15 +25,9 @@ internal class SingleOrArrayConverter : JsonConverter } return list; default: - return new WebhookEventBatch { JsonSerializer.Deserialize(ref reader, options) }; + return [JsonSerializer.Deserialize(ref reader, options)]; } } - - public override void Write( - Utf8JsonWriter writer, - WebhookEventBatch? objectToWrite, - JsonSerializerOptions options) => - JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); } internal class WebhookEventConverter : JsonConverter @@ -73,10 +67,5 @@ internal class WebhookEventConverter : JsonConverter throw new JsonException("Unknown event type"); } - - public override void Write(Utf8JsonWriter writer, WebhookEventBase value, JsonSerializerOptions options) - { - JsonSerializer.Serialize(writer, value, options); - } } } From d10dc7c3a46b55a44ead5f0613c0cd941f93e8bd Mon Sep 17 00:00:00 2001 From: Bill Volz Date: Tue, 12 Aug 2025 10:59:14 -0400 Subject: [PATCH 10/10] Added back abstract overrides. --- .../Models/Events/WebhookEventConverter.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs index 3c654b8..1629264 100644 --- a/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs +++ b/src/SocketLabs.EventWebhooks.Extensions/Models/Events/WebhookEventConverter.cs @@ -28,6 +28,12 @@ internal class SingleOrArrayConverter : JsonConverter return [JsonSerializer.Deserialize(ref reader, options)]; } } + + public override void Write( + Utf8JsonWriter writer, + WebhookEventBatch? objectToWrite, + JsonSerializerOptions options) => + JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); } internal class WebhookEventConverter : JsonConverter @@ -67,5 +73,10 @@ internal class WebhookEventConverter : JsonConverter throw new JsonException("Unknown event type"); } + + public override void Write(Utf8JsonWriter writer, WebhookEventBase value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value, options); + } } }