Bypass de pruebas: solo se llaman números en RETELL_ALLOWED_NUMBERS
Guarda en iniciarLlamadaSaliente: si RETELL_ALLOWED_NUMBERS tiene valor (CSV de E.164), solo se lanza la llamada a esos números; el resto se omite (devuelve null, funnel en simulado). Vacío = se llama a todos. Protege tanto el form (procesarLead) como el canal llamada (pedirLlamada). En prod = +34651194617. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,9 @@ DATABASE_URL="postgresql://postgres:reformix@localhost:5432/reformix"
|
|||||||
RETELL_API_KEY=""
|
RETELL_API_KEY=""
|
||||||
RETELL_AGENT_ID=""
|
RETELL_AGENT_ID=""
|
||||||
RETELL_FROM_NUMBER="" # número de origen en E.164, p. ej. +34910000000
|
RETELL_FROM_NUMBER="" # número de origen en E.164, p. ej. +34910000000
|
||||||
|
# Allowlist de pruebas: si tiene valor (CSV de E.164), SOLO se llama a esos números; el resto se
|
||||||
|
# omite (la llamada no se lanza). Vaciar para volver a llamar a todos. Ej: "+34651194617"
|
||||||
|
RETELL_ALLOWED_NUMBERS=""
|
||||||
|
|
||||||
# EP de ingesta del lead (/api/leads/:id/ingesta). Clave compartida que valida al llamante
|
# EP de ingesta del lead (/api/leads/:id/ingesta). Clave compartida que valida al llamante
|
||||||
# externo (Authorization: Bearer ...). Sin ella, el EP responde 401.
|
# externo (Authorization: Bearer ...). Sin ella, el EP responde 401.
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ const schema = z.object({
|
|||||||
RETELL_API_KEY: opcional,
|
RETELL_API_KEY: opcional,
|
||||||
RETELL_AGENT_ID: opcional,
|
RETELL_AGENT_ID: opcional,
|
||||||
RETELL_FROM_NUMBER: opcional,
|
RETELL_FROM_NUMBER: opcional,
|
||||||
|
// Allowlist de pruebas: si tiene valor (CSV de números), SOLO se llaman esos; vacío = todos.
|
||||||
|
RETELL_ALLOWED_NUMBERS: opcional,
|
||||||
// EP de ingesta del lead: clave compartida que valida al llamante externo.
|
// EP de ingesta del lead: clave compartida que valida al llamante externo.
|
||||||
FUNNEL_API_KEY: opcional,
|
FUNNEL_API_KEY: opcional,
|
||||||
// SMTP para enviar el presupuesto y el enlace al formulario.
|
// SMTP para enviar el presupuesto y el enlace al formulario.
|
||||||
@@ -32,6 +34,7 @@ export const env = schema.parse({
|
|||||||
RETELL_API_KEY: process.env.RETELL_API_KEY,
|
RETELL_API_KEY: process.env.RETELL_API_KEY,
|
||||||
RETELL_AGENT_ID: process.env.RETELL_AGENT_ID,
|
RETELL_AGENT_ID: process.env.RETELL_AGENT_ID,
|
||||||
RETELL_FROM_NUMBER: process.env.RETELL_FROM_NUMBER,
|
RETELL_FROM_NUMBER: process.env.RETELL_FROM_NUMBER,
|
||||||
|
RETELL_ALLOWED_NUMBERS: process.env.RETELL_ALLOWED_NUMBERS,
|
||||||
FUNNEL_API_KEY: process.env.FUNNEL_API_KEY,
|
FUNNEL_API_KEY: process.env.FUNNEL_API_KEY,
|
||||||
SMTP_HOST: process.env.SMTP_HOST,
|
SMTP_HOST: process.env.SMTP_HOST,
|
||||||
SMTP_PORT: process.env.SMTP_PORT,
|
SMTP_PORT: process.env.SMTP_PORT,
|
||||||
|
|||||||
@@ -50,6 +50,18 @@ export async function iniciarLlamadaSaliente(opts: {
|
|||||||
const toNumber = normalizarTelefonoEs(opts.telefono);
|
const toNumber = normalizarTelefonoEs(opts.telefono);
|
||||||
if (!toNumber) return null;
|
if (!toNumber) return null;
|
||||||
|
|
||||||
|
// Bypass de seguridad (fase de pruebas): si RETELL_ALLOWED_NUMBERS tiene valor, SOLO se llama a
|
||||||
|
// esos números; cualquier otro se omite (devuelve null, el funnel sigue en simulado). Vaciar la
|
||||||
|
// variable para volver a llamar a todos.
|
||||||
|
const allow = (env.RETELL_ALLOWED_NUMBERS ?? '')
|
||||||
|
.split(',')
|
||||||
|
.map((s) => normalizarTelefonoEs(s.trim()))
|
||||||
|
.filter((n): n is string => Boolean(n));
|
||||||
|
if (allow.length > 0 && !allow.includes(toNumber)) {
|
||||||
|
console.warn(`Retell: ${toNumber} no está en RETELL_ALLOWED_NUMBERS; llamada omitida (bypass).`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const body: Record<string, unknown> = {
|
const body: Record<string, unknown> = {
|
||||||
from_number: env.RETELL_FROM_NUMBER,
|
from_number: env.RETELL_FROM_NUMBER,
|
||||||
to_number: toNumber,
|
to_number: toNumber,
|
||||||
|
|||||||
Reference in New Issue
Block a user