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:
42
src/Http/Controllers/LeadMailWebhookController.php
Normal file
42
src/Http/Controllers/LeadMailWebhookController.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace LeadM\LeadMail\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use LeadM\LeadMail\Events\LeadMailWebhookReceived;
|
||||
use LeadM\LeadMail\Exceptions\InvalidWebhookSignatureException;
|
||||
use LeadM\LeadMail\Webhooks\LeadMailWebhook;
|
||||
|
||||
/**
|
||||
* Default receiver for LeadMail webhooks, auto-registered by the service
|
||||
* provider. Verifies the signature, logs failures, and dispatches a
|
||||
* LeadMailWebhookReceived event for custom handling.
|
||||
*/
|
||||
class LeadMailWebhookController
|
||||
{
|
||||
public function __invoke(Request $request, LeadMailWebhook $webhook): Response
|
||||
{
|
||||
try {
|
||||
$event = $webhook->parse($request);
|
||||
} catch (InvalidWebhookSignatureException) {
|
||||
Log::warning('LeadMail webhook rejected: invalid or missing signature.');
|
||||
|
||||
return response('Invalid signature.', 403);
|
||||
}
|
||||
|
||||
if ($event->isFailure()) {
|
||||
Log::warning('LeadMail reported a failed email.', [
|
||||
'log_id' => $event->logId,
|
||||
'to' => $event->to,
|
||||
'error_code' => $event->errorCode,
|
||||
'error_message' => $event->errorMessage,
|
||||
]);
|
||||
}
|
||||
|
||||
event(new LeadMailWebhookReceived($event));
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user