authorize('viewAny', Webhook::class); return WebhookResource::collection( Webhook::query()->latest('id')->paginate(perPage: min($request->integer('per_page', 25), 100)), ); } /** * The secret is in the answer once, when it is made (or rotated), and * never again. */ public function store(WebhookRequest $request): JsonResponse { $this->authorize('create', Webhook::class); $secret = $request->input('secret') ?: Str::random(40); $webhook = new Webhook([...$request->validated(), 'secret' => $secret]); $webhook->forceFill(['created_by' => $request->user()->id])->save(); return WebhookResource::make($webhook->refresh()) ->additional(['secret' => $secret]) ->response() ->setStatusCode(201); } public function show(Webhook $webhook): WebhookResource { $this->authorize('view', $webhook); return WebhookResource::make($webhook); } /** * Switching it back on starts its failure count again. */ public function update(WebhookRequest $request, Webhook $webhook): JsonResponse { $this->authorize('update', $webhook); $data = $request->validated(); $rotated = $request->boolean('rotate_secret') ? Str::random(40) : null; unset($data['rotate_secret']); $webhook->fill($data); if ($rotated !== null) { $webhook->secret = $rotated; } if ($webhook->isDirty('is_active') && $webhook->is_active) { $webhook->consecutive_failures = 0; } $webhook->save(); return WebhookResource::make($webhook) ->additional($rotated !== null ? ['secret' => $rotated] : []) ->response(); } public function destroy(Webhook $webhook): JsonResponse { $this->authorize('delete', $webhook); $webhook->delete(); return response()->json(status: 204); } /** * Newest first. Filter: status. */ public function deliveries(Request $request, Webhook $webhook): AnonymousResourceCollection { $this->authorize('view', $webhook); return WebhookDeliveryResource::collection( $webhook->deliveries() ->when($request->filled('status'), fn ($q) => $q->where('status', $request->string('status'))) ->paginate(perPage: min($request->integer('per_page', 25), 100)) ->withQueryString(), ); } /** * A `ping`, to check the receiving end before anything real happens. */ public function ping(Webhook $webhook): JsonResponse { $this->authorize('update', $webhook); $delivery = $webhook->deliveries()->create([ 'uuid' => (string) Str::uuid(), 'event' => 'ping', 'payload' => ['webhook' => $webhook->id, 'events' => $webhook->events], ]); DeliverWebhook::dispatch($delivery); return WebhookDeliveryResource::make($delivery->refresh())->response()->setStatusCode(202); } /** * Send one again, as a new delivery of the same event and payload. */ public function redeliver(WebhookDelivery $delivery): JsonResponse { $this->authorize('update', $delivery->webhook); $again = $delivery->webhook->deliveries()->create([ 'uuid' => (string) Str::uuid(), 'event' => $delivery->event, 'payload' => $delivery->payload, ]); DeliverWebhook::dispatch($again); return WebhookDeliveryResource::make($again->refresh())->response()->setStatusCode(202); } }