Files
whatsapp/api/save_survey_response.php
2026-01-21 23:55:49 -05:00

149 lines
5.3 KiB
PHP

<?php
require_once __DIR__ . '/../config/config.php';
if (php_sapi_name() !== 'cli') header('Content-Type: application/json; charset=utf-8');
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
// minimal auth or debug
$debug = isset($_GET['debug']) && $_GET['debug'] === 'true';
if (!$debug && function_exists('requireAuthentication')) requireAuthentication();
$phone = $input['phone'] ?? ($input['phone_number'] ?? null);
$user_id = isset($input['user_id']) ? intval($input['user_id']) : null;
$raw = $input['text'] ?? $input['raw'] ?? null;
if (!$raw || (!$phone && !$user_id)) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'phone/user_id and text are required']);
exit;
}
// Normalize encoding - try to ensure UTF-8
if (!function_exists('normalize_text')) {
function normalize_text($s) {
if (empty($s)) return $s;
// If valid UTF-8, attempt to repair common mojibake (Ã, Â) before returning
if (mb_check_encoding($s, 'UTF-8')) {
if (preg_match('/Ã|Â/', $s)) {
$step = @iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $s);
if ($step) {
$step2 = @iconv('ISO-8859-1', 'UTF-8//TRANSLIT', $step);
if ($step2 && mb_check_encoding($step2, 'UTF-8')) return $step2;
}
}
return $s;
}
// Try latin1 -> utf8
$try = @iconv('ISO-8859-1', 'UTF-8//TRANSLIT', $s);
if ($try && mb_check_encoding($try, 'UTF-8')) return $try;
// Try CP1252
$try2 = @iconv('CP1252', 'UTF-8//TRANSLIT', $s);
if ($try2 && mb_check_encoding($try2, 'UTF-8')) return $try2;
// Fallback: utf8_decode then re-encode
$auto = mb_convert_encoding($s, 'UTF-8', 'auto');
// Try to repair common double-encoding mojibake (look for sequences like à or Â)
if (preg_match('/[\xC2\xC3][\x80-\xBF]/', $s) || preg_match('/Ã|Â/', $s)) {
$step = @iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $s);
if ($step) {
$step2 = @iconv('ISO-8859-1', 'UTF-8//TRANSLIT', $step);
if ($step2 && mb_check_encoding($step2, 'UTF-8')) return $step2;
}
}
return $auto;
}
}
$rawClean = normalize_text($raw);
// Parse key: value lines
$lines = preg_split('/\r?\n/', $rawClean);
$parsed = [];
foreach ($lines as $line) {
$line = trim($line);
if ($line === '') continue;
// Try separator ':' or '-'
if (strpos($line, ':') !== false) {
list($k,$v) = explode(':', $line, 2);
} elseif (strpos($line, '?') !== false && preg_match('/^\s*([^\?]+\?)\s*(.+)$/', $line, $m)) {
$k = $m[1]; $v = $m[2];
} else {
// last resort split by whitespace before last token
$parts = preg_split('/\s{2,}/', $line);
if (count($parts) === 2) { $k = $parts[0]; $v = $parts[1]; } else { continue; }
}
$k = trim($k);
$v = trim($v);
// normalize key and value encoding
$k = normalize_text($k);
$v = normalize_text($v);
$parsed[$k] = $v;
}
// Map expected questions (in Spanish) to fields
if (!function_exists('yesno_to_bool')) {
function yesno_to_bool($s) {
$s = mb_strtolower($s);
// Normalize common utf8 artifacts
$s = str_replace(['\u00a0','\xa0'], ' ', $s);
$s = trim($s);
if (in_array($s, ['si','sí','s','yes','y','true','1'])) return 1;
if (in_array($s, ['no','n','false','0'])) return 0;
return null;
}
}
$qeasy = null; $qhuman = null; $rating = null; $comment = null;
// try keys in parsed
foreach ($parsed as $k => $v) {
$kl = mb_strtolower($k);
if (strpos($kl, 'fue') !== false && strpos($kl, 'facil') !== false) {
$qeasy = yesno_to_bool($v);
} elseif (strpos($kl, 'asesor') !== false || strpos($kl, 'humano') !== false) {
$qhuman = yesno_to_bool($v);
} elseif (strpos($kl, 'calificaci') !== false || strpos($kl, 'calificacion') !== false || strpos($kl, 'calificaci') !== false) {
$rating = intval(preg_replace('/[^0-9]/','',$v));
} elseif (strpos($kl, 'coment') !== false) {
$comment = $v;
}
}
// fallback: try regex in raw
if ($qeasy === null) {
if (preg_match('/fue\s+([^,:\?]+)\s+interact/i', $rawClean, $m)) { $qeasy = yesno_to_bool($m[1]); }
}
if ($qhuman === null) {
if (preg_match('/asesor.*:\s*([^,\n]+)/i', $rawClean, $m)) { $qhuman = yesno_to_bool($m[1]); }
}
if ($rating === null) {
if (preg_match('/calificaci[oó]n[:\s]*([0-9]+)/i', $rawClean, $m)) { $rating = intval($m[1]); }
}
if ($comment === null) {
if (preg_match('/comentario[:\s]*(.+)$/i', $rawClean, $m)) { $comment = trim($m[1]); }
}
// Insert into DB
try {
$db = Database::getInstance();
$phoneNormalized = $phone ? preg_replace('/[^0-9+]/','',$phone) : null;
$now = date('Y-m-d H:i:s');
$data = [
'user_id' => $user_id,
'phone_number' => $phoneNormalized,
'q_easy_interact' => $qeasy,
'q_human_resolved' => $qhuman,
'rating' => $rating,
'comment' => $comment,
'raw_text' => $rawClean,
'created_at' => $now
];
$id = $db->insert('survey_responses', $data);
if (function_exists('writeLog')) writeLog('INFO', 'Survey response saved', ['id'=>$id, 'phone'=>$phoneNormalized, 'parsed'=>$parsed]);
echo json_encode(['success'=>true,'id'=>$id,'parsed'=>$parsed]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['success'=>false,'error'=>$e->getMessage()]);
}