Skip to content

Conversation

@thoven87
Copy link
Contributor

Introduces comprehensive models for SendGrid webhook event types, including delivery, engagement, and account status change events. Adds ECDSA signature verification for webhook security, updates Package.swift to include swift-crypto, and provides extensive documentation and tests for event parsing and verification.

Closes #28

Introduces comprehensive models for SendGrid webhook event types, including delivery, engagement, and account status change events. Adds ECDSA signature verification for webhook security, updates Package.swift to include swift-crypto, and provides extensive documentation and tests for event parsing and verification.
@thoven87 thoven87 mentioned this pull request Oct 22, 2025
@codecov
Copy link

codecov bot commented Oct 22, 2025

Codecov Report

❌ Patch coverage is 38.20034% with 364 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.54%. Comparing base (cae5b09) to head (17aae6e).

Files with missing lines Patch % Lines
Sources/SendGridKit/SendGridClient.swift 2.71% 251 Missing ⚠️
Sources/SendGridKit/Models/WebhookEvent.swift 65.89% 88 Missing ⚠️
...es/SendGridKit/Webhook+SignatureVerification.swift 65.75% 25 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main      #29       +/-   ##
===========================================
- Coverage   86.86%   53.54%   -33.32%     
===========================================
  Files          12       14        +2     
  Lines         274      861      +587     
===========================================
+ Hits          238      461      +223     
- Misses         36      400      +364     
Files with missing lines Coverage Δ
...es/SendGridKit/Webhook+SignatureVerification.swift 65.75% <65.75%> (ø)
Sources/SendGridKit/Models/WebhookEvent.swift 65.89% <65.89%> (ø)
Sources/SendGridKit/SendGridClient.swift 12.84% <2.71%> (-87.16%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@fpseverino
Copy link
Member

So this basically only adds structs that a Vapor/Hummingbird server should decode and methods to verify their signature, right?

@thoven87
Copy link
Contributor Author

So this basically only adds structs that a Vapor/Hummingbird server should decode and methods to verify their signature, right?

I just noticed that I am missing the received case. I will fix this shortly along with the CRUD operations https://www.twilio.com/docs/sendgrid/api-reference/webhooks/create-an-event-webhook

Introduces methods for managing SendGrid Event Webhooks (create, test, retrieve, update, delete, signature verification, public key retrieval) and Parse Webhook settings/statistics in SendGridClient. Also updates SendGridError to include url and id fields for improved error context, and fixes the base API URL to support new endpoints.
Introduces SendGridReceivedEvent to handle inbound email 'received' events, updates SendGridWebhookEvent and related enums for the new event type, and adds models for event webhook input, settings, signature verification, and parse webhook statistics. Also adds sgContentType to engagement events and improves documentation for uniqueArgs.
Added unit tests to verify decoding of SendGrid 'received' webhook events, including support for both Unix and ISO 8601 timestamps, additional fields, and v3_payload_details. Also updated existing test data to use generic test values for consistency.
Updated several public method signatures in SendGridClient to use multiline formatting for parameters, improving readability and consistency. Also adjusted body encoding and decoding calls to multiline style.
Changed the expected sgEventId value in the delivered event decoding test to 'test_delivered_event_id' for consistency or improved test clarity.
@thoven87
Copy link
Contributor Author

So this basically only adds structs that a Vapor/Hummingbird server should decode and methods to verify their signature, right?

@fpseverino all the failing tests are related to the email validation API

Copy link
Member

@fpseverino fpseverino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A very well designed API, great work!
You tested it with real SendGrid API keys, right?


```swift
import SendGridKit
import NIO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be Vapor, right? The example uses Vapor APIs it seems

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I will look at the Vapor doc to update this example.

}
```

### Webhook Event Processing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add this excellent documentation as an article in the DocC catalog?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do so shortly.

/// Delivery events: bounce, delivered, deferred, dropped, processed, blocked
public struct SendGridDeliveryEvent: Codable, Sendable {
/// ID of the unsubscribe group that includes the recipient's email address.
public let asmGroupId: Int?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here with all the properties that end with "Id"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to split this file into smaller ones, you should create a subfolder (inside the "Models" one) called "Webhooks" or something like that

/// - Parameters:
/// - input: The request body
/// - onbehalfOf: The on-behalf-of header allows you to make API calls from a parent account on behalf of the parent's Subusers or customer accounts.
public func createEventWebhook(_ input: EventWebhookInput, onbehalfOf: String? = nil) async throws -> WebhookSettingsResponse {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make a separate client, just like for the email validation API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough! I will do that.

@thoven87
Copy link
Contributor Author

A very well designed API, great work!

You tested it with real SendGrid API keys, right?

Yes!

thoven87 and others added 5 commits October 27, 2025 21:17
Co-authored-by: Francesco Paolo Severino <[email protected]>
Co-authored-by: Francesco Paolo Severino <[email protected]>
Co-authored-by: Francesco Paolo Severino <[email protected]>
Co-authored-by: Francesco Paolo Severino <[email protected]>
Co-authored-by: Francesco Paolo Severino <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Webhook

2 participants