Add typed error handling, retries, and webhook receiver
- Typed exceptions: LeadMailException base with LeadMailRequestException (structured statusCode/errorCode/logId/validationErrors) and LeadMailConnectionException; sendEmail/getDomains now throw these instead of raw Guzzle exceptions, and a malformed body is no longer a silent null. - Automatic retry with exponential backoff on idempotent calls (getDomains, verifyEmail); sends are never retried to avoid duplicates. - Webhook receiver: auto-registered route + LeadMailWebhookController that verifies the HMAC signature, logs failures, and dispatches a LeadMailWebhookReceived event. WebhookSignature/WebhookEvent/LeadMailWebhook helpers for manual handling. - Webhook self-registration client methods (registerWebhook/getWebhook/ deleteWebhook) and a promptless `leadmail:install` command that registers the URL and writes LEADMAIL_WEBHOOK_SECRET to .env. - Null-safe client binding when LEADMAIL_TOKEN is unset. - Test suite (Pest + Testbench) covering all of the above.
This commit is contained in:
@@ -52,4 +52,55 @@ return [
|
||||
|
|
||||
*/
|
||||
'auto_tenant' => env('LEADMAIL_AUTO_TENANT', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Retries
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| How many times to retry a request that fails transiently (connection
|
||||
| errors and 429/5xx responses) before giving up. The delay between
|
||||
| attempts grows exponentially from the base delay (in milliseconds).
|
||||
|
|
||||
*/
|
||||
'retries' => env('LEADMAIL_RETRIES', 2),
|
||||
|
||||
'retry_delay' => env('LEADMAIL_RETRY_DELAY_MS', 200),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Webhook Secret
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The signing secret for verifying incoming failure webhooks. This must
|
||||
| match the webhook secret shown for this client app in the leadMail admin
|
||||
| dashboard. Set automatically by `php artisan leadmail:install`.
|
||||
|
|
||||
*/
|
||||
'webhook_secret' => env('LEADMAIL_WEBHOOK_SECRET'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Webhook Route
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The path the SDK automatically registers to receive failure webhooks.
|
||||
| The registered endpoint verifies the signature, logs failures, and fires
|
||||
| a LeadMailWebhookReceived event you can listen for. Set to null to
|
||||
| disable auto-registration and handle the route yourself.
|
||||
|
|
||||
*/
|
||||
'webhook_route' => env('LEADMAIL_WEBHOOK_ROUTE', '/webhooks/leadmail'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Webhook Route Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Middleware applied to the auto-registered webhook route. The endpoint is
|
||||
| already authenticated by HMAC signature, so it deliberately runs outside
|
||||
| the "web" group (no CSRF, no session).
|
||||
|
|
||||
*/
|
||||
'webhook_middleware' => ['throttle:60,1'],
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user