64 lines
2.1 KiB
PHP
64 lines
2.1 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\WebhookEndpoint;
|
|
use App\Models\WebhookRequest;
|
|
use Illuminate\Console\Attributes\Description;
|
|
use Illuminate\Console\Attributes\Signature;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Support\Carbon;
|
|
|
|
#[Signature('webhooks:prune')]
|
|
#[Description('Remove expired endpoints and old webhook requests')]
|
|
class PruneWebhookData extends Command
|
|
{
|
|
public function handle(): int
|
|
{
|
|
$now = now();
|
|
$deletedRequests = WebhookRequest::query()
|
|
->where('received_at', '<', $now->copy()->subDays((int) config('webhooks.request_retention_days', 7)))
|
|
->delete();
|
|
|
|
$this->pruneEndpointLimits();
|
|
$deletedEndpoints = $this->deleteExpiredAnonymousEndpoints($now);
|
|
|
|
$this->info("Deleted {$deletedRequests} old requests and {$deletedEndpoints} expired endpoints.");
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function pruneEndpointLimits(): void
|
|
{
|
|
WebhookEndpoint::query()
|
|
->select('id')
|
|
->chunkById(100, function (Collection $endpoints): void {
|
|
foreach ($endpoints as $endpoint) {
|
|
$requestIds = WebhookRequest::query()
|
|
->whereBelongsTo($endpoint, 'endpoint')
|
|
->select('id')
|
|
->orderByDesc('received_at')
|
|
->orderByDesc('id')
|
|
->skip((int) config('webhooks.max_requests_per_endpoint', 1000))
|
|
->take(1_000_000_000)
|
|
->pluck('id');
|
|
|
|
if ($requestIds->isNotEmpty()) {
|
|
WebhookRequest::query()->whereKey($requestIds)->delete();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private function deleteExpiredAnonymousEndpoints(Carbon $now): int
|
|
{
|
|
return WebhookEndpoint::query()
|
|
->public()
|
|
->whereNull('user_id')
|
|
->whereNotNull('expires_at')
|
|
->where('expires_at', '<', $now)
|
|
->delete();
|
|
}
|
|
}
|