Deploy Ladill Care / deploy (push) Failing after 13s
Healthcare management app: patients, appointments, consultations, lab, pharmacy inventory, billing, and reports at care.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
3.4 KiB
PHP
97 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Integrations;
|
|
|
|
use App\Models\Employee;
|
|
use App\Models\EmployeePresence;
|
|
use App\Models\Visit;
|
|
use App\Models\WebhookEndpoint;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class WebhookDispatcher
|
|
{
|
|
public function dispatch(string $event, Visit $visit): void
|
|
{
|
|
$visit->loadMissing('organization');
|
|
|
|
$payload = [
|
|
'event' => $event,
|
|
'visit' => [
|
|
'id' => $visit->id,
|
|
'public_id' => $visit->public_id,
|
|
'external_ref' => $visit->external_ref,
|
|
'source' => $visit->source,
|
|
'status' => $visit->status,
|
|
'visitor_type' => $visit->visitor_type,
|
|
'badge_code' => $visit->badge_code,
|
|
'checked_in_at' => $visit->checked_in_at?->toIso8601String(),
|
|
'checked_out_at' => $visit->checked_out_at?->toIso8601String(),
|
|
'visitor_name' => $visit->visitor?->full_name,
|
|
'host_name' => $visit->host?->name,
|
|
],
|
|
'timestamp' => now()->toIso8601String(),
|
|
];
|
|
|
|
$this->dispatchPayload($visit->organization_id, $event, $payload);
|
|
}
|
|
|
|
public function dispatchEmployee(string $event, Employee $employee, ?EmployeePresence $presence = null): void
|
|
{
|
|
$presence ??= $employee->presence;
|
|
|
|
$payload = [
|
|
'event' => $event,
|
|
'employee' => [
|
|
'id' => $employee->id,
|
|
'employee_code' => $employee->employee_code,
|
|
'full_name' => $employee->full_name,
|
|
'department' => $employee->department,
|
|
'branch_id' => $employee->branch_id,
|
|
'status' => $presence?->status,
|
|
'destination' => $presence?->destination,
|
|
'signed_in_at' => $presence?->signed_in_at?->toIso8601String(),
|
|
'expected_return_at' => $presence?->expected_return_at?->toIso8601String(),
|
|
],
|
|
'timestamp' => now()->toIso8601String(),
|
|
];
|
|
|
|
$this->dispatchPayload($employee->organization_id, $event, $payload);
|
|
}
|
|
|
|
/** @param array<string, mixed> $payload */
|
|
protected function dispatchPayload(int $organizationId, string $event, array $payload): void
|
|
{
|
|
$endpoints = WebhookEndpoint::query()
|
|
->where('organization_id', $organizationId)
|
|
->where('is_active', true)
|
|
->get()
|
|
->filter(fn (WebhookEndpoint $endpoint) => $endpoint->subscribesTo($event));
|
|
|
|
foreach ($endpoints as $endpoint) {
|
|
$this->send($endpoint, $payload);
|
|
}
|
|
}
|
|
|
|
/** @param array<string, mixed> $payload */
|
|
protected function send(WebhookEndpoint $endpoint, array $payload): void
|
|
{
|
|
$body = json_encode($payload);
|
|
$headers = ['Content-Type' => 'application/json'];
|
|
|
|
if ($endpoint->secret) {
|
|
$headers['X-Frontdesk-Signature'] = hash_hmac('sha256', $body, $endpoint->secret);
|
|
}
|
|
|
|
try {
|
|
Http::timeout(10)->withHeaders($headers)->withBody($body, 'application/json')->post($endpoint->url);
|
|
} catch (\Throwable $e) {
|
|
Log::warning('Frontdesk webhook delivery failed', [
|
|
'endpoint_id' => $endpoint->id,
|
|
'url' => $endpoint->url,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
}
|
|
}
|
|
}
|