webhooks library

Verify and parse AhaSend webhook and route deliveries.

Create a WebhookVerifier with the secret returned when the webhook or route was created, then call WebhookVerifier.verify with the raw request body and headers. It checks the Standard Webhooks signature and timestamp and returns a typed WebhookEvent.

This library has no dependency on dart:io, so it works on the Dart VM, in Flutter and on the web.

import 'package:ahasend/webhooks.dart';

final verifier = WebhookVerifier(webhookSecret);

int handle(String body, Map<String, String> headers) {
  final WebhookEvent event;
  try {
    event = verifier.verify(body: body, headers: headers);
  } on WebhookVerificationException {
    return 400; // Not from AhaSend, or replayed.
  } on InvalidPayloadException {
    return 204; // Authentic, but not decodable: store it and move on.
  }
  switch (event) {
    case MessageBouncedEvent(:final data):
      print('Bounced: ${data.recipient}');
    case SuppressionCreatedEvent(:final data):
      print('Suppressed: ${data.recipient}');
    default:
      break;
  }
  return 204;
}

Classes

DomainDnsErrorEvent
The periodic DNS check found problems that block sending for a domain (domain.dns_error).
DomainDnsErrorEventData
The data of a DomainDnsErrorEvent.
MessageBouncedEvent
The message bounced, either rejected permanently during SMTP or reported later by a bounce notification (message.bounced).
MessageClickedEvent
The recipient clicked a tracked link (message.clicked).
MessageClickedEventData
The data of a MessageClickedEvent.
MessageDeliveredEvent
The recipient's mail server accepted the message (message.delivered).
MessageEventData
The data of a MessageWebhookEvent.
MessageFailedEvent
The message ran out of retries without being delivered (message.failed). It carries no delivery attempt.
MessageOpenedEvent
The recipient opened the message (message.opened).
MessageReceptionEvent
A message was received and queued (message.reception).
MessageRoutingAttachment
A MIME part of a routed message: an attachment or an inline part.
MessageRoutingEvent
An inbound message matched a route (message.routing).
MessageRoutingEventData
The inbound message of a MessageRoutingEvent.
MessageSuppressedEvent
The message was not sent because the recipient is suppressed (message.suppressed).
MessageTransientErrorEvent
Delivery was deferred by a temporary problem and will be retried (message.transient_error).
MessageWebhookEvent
An event about an outbound message that shares the common message data shape: reception, delivery, transient error, failure, bounce, suppression or open.
SuppressionCreatedEvent
An address was added to the suppression list (suppression.created).
SuppressionCreatedEventData
The data of a SuppressionCreatedEvent.
UnknownWebhookEvent
An event whose type this version of the package does not know.
WebhookDeliveryAttempt
Diagnostics from a single delivery attempt.
WebhookEvent
An event delivered to a webhook or route URL.
WebhookVerifier
Verifies the signatures of webhook and route deliveries.

Extension Types

MessageEventTrigger
The trigger reported in MessageEventData.event.

Typedefs

JsonMap = Map<String, Object?>
A decoded JSON object.

Exceptions / Errors

InvalidPayloadException
The body is not a valid webhook payload, for example not JSON or without a type.
InvalidSignatureException
No signature in webhook-signature matches the payload, or the signature headers are malformed.
MissingHeaderException
A required header, such as webhook-signature, is missing or empty.
TimestampOutOfToleranceException
The webhook-timestamp is further from the current time than the verifier's tolerance, in the past or in the future.
WebhookException
Base class for every exception thrown by the webhook library.
WebhookVerificationException
Thrown when a webhook delivery cannot be verified: a header is missing, no signature matches, or the timestamp is too old or too new.