netgescon-day0/app/Http/Controllers/Api/PanasonicCstaController.php

155 lines
5.7 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\ChiamataPostIt;
use App\Models\RubricaUniversale;
use App\Support\PhoneNumber;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
class PanasonicCstaController extends Controller
{
public function incoming(Request $request): JsonResponse
{
if (! $this->isAuthorized($request)) {
return response()->json(['ok' => false, 'message' => 'Unauthorized'], 401);
}
$payload = $request->validate([
'phone' => ['required', 'string', 'max:64'],
'name' => ['nullable', 'string', 'max:255'],
'direction' => ['nullable', 'in:in_arrivo,in_uscita,persa'],
'outcome' => ['nullable', 'string', 'max:255'],
'event_id' => ['nullable', 'string', 'max:100'],
'called_extension' => ['nullable', 'string', 'max:30'],
'note' => ['nullable', 'string'],
'called_at' => ['nullable', 'date'],
]);
$normalized = PhoneNumber::normalizeForMatch((string) $payload['phone']);
$rubrica = $this->findRubricaByPhone($normalized);
$postIt = null;
if (Schema::hasTable('chiamate_post_it')) {
$postIt = ChiamataPostIt::query()->create([
'stabile_id' => null,
'rubrica_id' => $rubrica?->id,
'ticket_id' => null,
'creato_da_user_id' => null,
'telefono' => $normalized !== '' ? $normalized : (string) $payload['phone'],
'nome_chiamante' => $rubrica?->nome_completo ?: ($payload['name'] ?? null),
'direzione' => $payload['direction'] ?? 'in_arrivo',
'esito' => $payload['outcome'] ?? null,
'origine' => 'panasonic_ns1000',
'origine_id' => $payload['event_id'] ?? null,
'oggetto' => 'Chiamata ' . (($payload['direction'] ?? 'in_arrivo') === 'in_arrivo' ? 'in arrivo' : 'telefonica'),
'nota' => $this->buildNote($payload),
'priorita' => 'Media',
'stato' => 'post_it',
'chiamata_il' => $payload['called_at'] ?? now(),
]);
}
return response()->json([
'ok' => true,
'source' => 'panasonic_ns1000',
'phone_normalized' => $normalized,
'matched' => (bool) $rubrica,
'rubrica' => $rubrica ? [
'id' => $rubrica->id,
'nome_completo' => $rubrica->nome_completo,
'categoria' => $rubrica->categoria,
] : null,
'post_it_id' => $postIt?->id,
'called_extension' => $payload['called_extension'] ?? null,
]);
}
public function lookup(Request $request): JsonResponse
{
if (! $this->isAuthorized($request)) {
return response()->json(['ok' => false, 'message' => 'Unauthorized'], 401);
}
$data = $request->validate([
'phone' => ['required', 'string', 'max:64'],
]);
$normalized = PhoneNumber::normalizeForMatch((string) $data['phone']);
$rubrica = $this->findRubricaByPhone($normalized);
return response()->json([
'ok' => true,
'phone_normalized' => $normalized,
'matched' => (bool) $rubrica,
'rubrica' => $rubrica ? [
'id' => $rubrica->id,
'nome_completo' => $rubrica->nome_completo,
'telefono_ufficio' => $rubrica->telefono_ufficio,
'telefono_cellulare' => $rubrica->telefono_cellulare,
'telefono_casa' => $rubrica->telefono_casa,
'categoria' => $rubrica->categoria,
] : null,
]);
}
private function isAuthorized(Request $request): bool
{
$configured = (string) env('NETGESCON_CTI_SHARED_TOKEN', '');
if ($configured === '') {
return false;
}
$token = (string) ($request->header('X-CTI-Token') ?: $request->input('token', ''));
return hash_equals($configured, $token);
}
private function findRubricaByPhone(string $phone): ?RubricaUniversale
{
$digits = PhoneNumber::normalizeDigits($phone);
if ($digits === '') {
return null;
}
$tail = substr($digits, -7);
if ($tail === false || $tail === '') {
return null;
}
return RubricaUniversale::query()
->where(function ($q) use ($tail) {
$q->orWhere('telefono_cellulare', 'like', '%' . $tail . '%')
->orWhere('telefono_ufficio', 'like', '%' . $tail . '%')
->orWhere('telefono_casa', 'like', '%' . $tail . '%')
->orWhere('telefono_cellulare_nazionale', 'like', '%' . $tail . '%');
})
->orderByDesc('updated_at')
->first();
}
private function buildNote(array $payload): string
{
$lines = [
'Origine: Panasonic NS1000 (CSTA)',
];
if (! empty($payload['called_extension'])) {
$lines[] = 'Interno chiamato: ' . $payload['called_extension'];
}
if (! empty($payload['event_id'])) {
$lines[] = 'Event ID: ' . $payload['event_id'];
}
if (! empty($payload['note'])) {
$lines[] = 'Note PBX: ' . $payload['note'];
}
return implode("\n", $lines);
}
}