Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 55 additions & 41 deletions src/Resend.Webhooks/Json/WebhookEventConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,54 +33,74 @@ public WebhookEventConverter()
/*
*
*/
reader.Read();

if ( reader.TokenType != JsonTokenType.PropertyName )
throw new JsonException( "Expected PropertyName" );
bool hasType = false;
bool hasCreatedAt = false;
bool hasData = false;

if ( reader.GetString() != "type" )
throw new JsonException( "Expected 'type' property" );
JsonElement rawData = default;

reader.Read();
value.EventType = _wet.Read( ref reader, typeof( WebhookEventType ), options );
// Read the 3 webhook payload properties
for ( int i = 0; i < 3; i++ )
{
reader.Read();

if ( reader.TokenType != JsonTokenType.PropertyName )
throw new JsonException( "Expected PropertyName" );

string? propertyName = reader.GetString();

if ( propertyName == "type" )
{
if ( hasType )
throw new JsonException( "Duplicate 'type' property" );

hasType = true;

reader.Read();
value.EventType = _wet.Read( ref reader, typeof( WebhookEventType ), options );
}
else if ( propertyName == "created_at" )
{
if ( hasCreatedAt )
throw new JsonException( "Duplicate 'created_at' property" );

hasCreatedAt = true;

reader.Read();
value.MomentCreated = _utc.Read( ref reader, typeof( DateTime ), options );
}
else if ( propertyName == "data" )
{
if ( hasData )
throw new JsonException( "Duplicate 'data' property" );

hasData = true;

reader.Read();
rawData = JsonElement.ParseValue( ref reader );
}
else
{
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
throw new JsonException( "Invalid property name" );
}
}

var category = value.EventType.Category();
if ( !hasType || !hasCreatedAt || !hasData )
throw new JsonException( "Missing required webhook properties" );


/*
*
*/
reader.Read();

if ( reader.TokenType != JsonTokenType.PropertyName )
throw new JsonException( "Expected PropertyName" );

if ( reader.GetString() != "created_at" )
throw new JsonException( "Expected 'created_at' property" );

reader.Read();
value.MomentCreated = _utc.Read( ref reader, typeof( DateTime ), options );
var category = value.EventType.Category();


/*
*
*/
reader.Read();

if ( reader.TokenType != JsonTokenType.PropertyName )
throw new JsonException( "Expected PropertyName" );

if ( reader.GetString() != "data" )
throw new JsonException( "Expected 'data' property" );

reader.Read();

if ( category == WebhookEventTypeCategory.Email )
{
var t1 = typeof( EmailEventData );
var o1 = (JsonConverter<EmailEventData>) options.GetConverter( t1 );

var data = o1.Read( ref reader, t1, options );
var data = rawData.Deserialize<EmailEventData>( options );

if ( data == null )
throw new JsonException( "Expected non-null data" );
Expand All @@ -89,10 +109,7 @@ public WebhookEventConverter()
}
else if ( category == WebhookEventTypeCategory.Contact )
{
var t2 = typeof( ContactEventData );
var o2 = (JsonConverter<ContactEventData>) options.GetConverter( t2 );

var data = o2.Read( ref reader, t2, options );
var data = rawData.Deserialize<ContactEventData>( options );

if ( data == null )
throw new JsonException( "Expected non-null data" );
Expand All @@ -101,10 +118,7 @@ public WebhookEventConverter()
}
else if ( category == WebhookEventTypeCategory.Domain )
{
var t3 = typeof( DomainEventData );
var o2 = (JsonConverter<DomainEventData>) options.GetConverter( t3 );

var data = o2.Read( ref reader, t3, options );
var data = rawData.Deserialize<DomainEventData>( options );

if ( data == null )
throw new JsonException( "Expected non-null data" );
Expand Down
4 changes: 4 additions & 0 deletions src/Resend/ResendExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ public static WebhookEventTypeCategory Category( this WebhookEventType @event )
case WebhookEventType.EmailComplained:
case WebhookEventType.EmailDelivered:
case WebhookEventType.EmailDeliveryDelay:
case WebhookEventType.EmailFailed:
case WebhookEventType.EmailOpened:
case WebhookEventType.EmailReceived:
case WebhookEventType.EmailScheduled:
case WebhookEventType.EmailSent:
case WebhookEventType.EmailSuppressed:
return WebhookEventTypeCategory.Email;

default:
Expand Down
Loading