Estoy enviando con phpmailer a una cuenta de email y leads a tokko pero cuando agrego el campo mail se me rompe el envio y no me llega ni al mail ni se crea el contacto en tokko, me podrán indicar cual puede ser el problema, dejo el php donde hace el flujo a tokko
$success, 'message' => $message]);
exit;
}
function enviarATokko(array $config, array $lead): void
{
$apiKey = trim((string) ($config['tokko_api_key'] ?? ''));
if ($apiKey === '') {
return;
}
if (!function_exists('curl_init')) {
throw new RuntimeException('La extensión cURL de PHP no está disponible');
}
$text = sprintf(
'Tipo: %s | Ubicación: %s | Metros: %s | Objetivo: %s',
$lead['tipoPropiedad'],
$lead['direccion'],
$lead['metros'],
$lead['objetivoTexto']
);
try {
$payload = json_encode([
'name' => $lead['nombre'],
'cellphone' => $lead['telefono'],
'email' => $lead['email'],
'text' => $text,
'tags' => json_encode([$config['tokko_origen'] ?? 'Landing Tasaciones'], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR),
'agent_mail' => $config['tokko_agent_mail'] ?? $config['smtp_user'] ?? '',
'status' => 1,
], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
throw new RuntimeException('No se pudo codificar el lead para Tokko', 0, $e);
}
$endpoint = 'https://www.tokkobroker.com/api/v1/webcontact/?' . http_build_query(['key' => $apiKey]);
$curl = curl_init($endpoint);
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json; charset=utf-8',
'Accept: application/json',
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($curl);
$error = curl_error($curl);
$status = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($response === false || $error !== '' || $status < 200 || $status >= 300) {
throw new RuntimeException('Tokko no respondió correctamente');
}
$result = json_decode($response, true);
if (is_array($result) && isset($result['status']) && strtoupper((string) $result['status']) !== 'OK') {
throw new RuntimeException('Tokko rechazó el lead');
}
}
// --- Config ---
if (!file_exists(__DIR__ . '/config.php')) {
responder(false, 'Falta el archivo config.php (copiá config.example.php)', 500);
}
$config = require __DIR__ . '/config.php';
// --- CORS básico (opcional, útil si el front y el PHP no están en el mismo dominio) ---
if (!empty($config['origen_permitido'])) {
header('Access-Control-Allow-Origin: ' . $config['origen_permitido']);
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
}
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
// --- Solo POST ---
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
responder(false, 'Método no permitido', 405);
}
// --- Honeypot anti-spam (debe llegar vacío) ---
if (!empty($_POST['website'])) {
responder(true, 'OK'); // respondemos éxito falso para no delatar el filtro
}
// --- Listas de valores válidos (deben coincidir con el formulario) ---
$TIPOS_PROPIEDAD_VALIDOS = ['Casa', 'Departamento', 'Lote', 'Local', 'Campo', 'Otro'];
$OBJETIVOS_VALIDOS = [
'vender' => 'Quiero vender',
'evaluando' => 'Estoy evaluando vender',
'valor' => 'Solo quiero conocer el valor',
];
// --- Validación y sanitización de datos ---
$tipoPropiedad = trim(filter_input(INPUT_POST, 'tipoPropiedad', FILTER_SANITIZE_SPECIAL_CHARS) ?? '');
$direccion = trim(filter_input(INPUT_POST, 'direccion', FILTER_SANITIZE_SPECIAL_CHARS) ?? '');
$metros = trim(filter_input(INPUT_POST, 'metros', FILTER_SANITIZE_SPECIAL_CHARS) ?? '');
$objetivo = trim(filter_input(INPUT_POST, 'objetivo', FILTER_SANITIZE_SPECIAL_CHARS) ?? '');
$nombre = trim(filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS) ?? '');
$telefono = trim(filter_input(INPUT_POST, 'telefono', FILTER_SANITIZE_SPECIAL_CHARS) ?? '');
$email = trim(filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL) ?? '');
if (!in_array($tipoPropiedad, $TIPOS_PROPIEDAD_VALIDOS, true)) {
responder(false, 'Tipo de propiedad inválido', 422);
}
if (strlen($direccion) < 3) {
responder(false, 'La dirección es inválida', 422);
}
if (!ctype_digit($metros) || (int) $metros <= 0) {
responder(false, 'Los metros cuadrados son inválidos', 422);
}
if (!array_key_exists($objetivo, $OBJETIVOS_VALIDOS)) {
responder(false, 'Opción inválida', 422);
}
if (strlen($nombre) < 2) {
responder(false, 'El nombre es inválido', 422);
}
if (strlen(preg_replace('/[^0-9]/', '', $telefono)) < 6) {
responder(false, 'El teléfono es inválido', 422);
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
responder(false, 'El correo electrónico es inválido', 422);
}
$objetivoTexto = $OBJETIVOS_VALIDOS[$objetivo];
try {
enviarATokko($config, [
'tipoPropiedad' => $tipoPropiedad,
'direccion' => $direccion,
'metros' => $metros,
'objetivoTexto' => $objetivoTexto,
'nombre' => $nombre,
'telefono' => $telefono,
'email' => $email,
]);
} catch (RuntimeException $e) {
responder(false, 'No se pudo registrar la solicitud en Tokko', 502);
}
// --- Envío por SMTP ---
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = $config['smtp_host'];
$mail->SMTPAuth = true;
$mail->Username = $config['smtp_user'];
$mail->Password = $config['smtp_pass'];
$mail->SMTPSecure = $config['smtp_secure']; // 'ssl' o 'tls'
$mail->Port = $config['smtp_port'];
$mail->CharSet = 'UTF-8';
// El From debe ser tu propia casilla DonWeb para evitar que el mail
// sea marcado como spam o rebotado por SPF/DKIM.
$mail->setFrom($config['smtp_user'], $config['destino_nombre']);
$mail->addReplyTo($email, $nombre);
$mail->addAddress($config['destino_email'], $config['destino_nombre']);
$mail->Subject = "Nuevo mensaje recibido desde kerlintasaciones.com.ar | {$nombre}";
$mail->isHTML(true);
$mail->Body =
"
Tipo de propiedad: {$tipoPropiedad}
" .
"
Barrio o dirección aproximada: {$direccion}
" .
"
Metros cuadrados aproximados: {$metros}
" .
"
Qué quiere hacer: {$objetivoTexto}
" .
"
Nombre y apellido: {$nombre}
" .
"
Correo electrónico: {$email}
" .
"
Teléfono: {$telefono}
";
$mail->send();
responder(true, 'Solicitud enviada correctamente');
} catch (Exception $e) {
responder(false, 'No se pudo enviar la solicitud', 500);
}