HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: //home/xedaptot/be.naniguide.com/app/Http/Controllers/SendingServerWebhookController.php
<?php

namespace App\Http\Controllers;

use App\Model\SendingServer;
use App\Notifications\Admin\SendingServerWebhookReceived;
use App\SendingServers\Capabilities\ReceivesWebhooks;
use App\Services\Notifications\Notifier;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

/**
 * Single skinny entry point for vendor sending-server webhook callbacks
 * (bounces, feedback loops, delivery confirmations, handshakes).
 *
 * Per-instance URL: `/webhook/{driverType}/{serverUid}` so tenant scope
 * resolves directly from the URL — no need to look up customer via
 * `runtime_message_id` like the legacy DeliveryController did. That
 * approach failed for handshake events (Amazon SNS SubscriptionConfirmation)
 * which have no msg id.
 *
 * Flow:
 *   1. Resolve server by uid; abort 404 on type mismatch (cross-tenant guard).
 *   2. Driver implements ReceivesWebhooks → delegate verify + parse.
 *   3. Each parsed WebhookEvent → dispatch via Laravel event bus.
 *   4. Listeners (RecordBounce, RecordComplaint, ConfirmSnsSubscription)
 *      handle side effects asynchronously (ShouldQueue) so the vendor
 *      sees a fast 200 even when DB / blacklist write is slow.
 */
class SendingServerWebhookController extends Controller
{
    public function handle(Request $req, string $driverType, string $serverUid): JsonResponse
    {
        Log::info('SendingServer webhook received', [
            'driver'     => $driverType,
            'server_uid' => $serverUid,
            'body'       => $req->getContent(),
            'query'      => $req->query(),
        ]);

        $server = SendingServer::findByUid($serverUid);
        if (is_null($server)) {
            abort(404);
        }

        if ($server->type !== $driverType) {
            // URL → server.type mismatch. Avoids cross-tenant accident.
            abort(404);
        }

        $driver = $server->driver();
        if (!$driver instanceof ReceivesWebhooks) {
            // Driver doesn't accept webhooks. Admin form only renders
            // webhookUrl() for drivers that implement the interface, so this
            // path should not be reachable in practice.
            abort(404);
        }

        // Per-event notification — debug + monitor every inbound POST.
        app(Notifier::class)->dispatch(new SendingServerWebhookReceived(
            $server,
            $req->getContent()
        ));

        $driver->verifyWebhook($req);

        foreach ($driver->parseWebhook($req) as $event) {
            event($event);
        }

        return response()->json(['ok' => true]);
    }
}