import React, { useState, useEffect } from ‘react’;
import { Copy, Download, Send } from ‘lucide-react’;
const GoogleAdsGenerator = () => {
// Estados para los campos de entrada
const [rubro, setRubro] = useState(»);
const [customRubro, setCustomRubro] = useState(»);
const [keywords, setKeywords] = useState([», », », », »]);
const [objetivo, setObjetivo] = useState(‘leads’);
const [url, setUrl] = useState(»);
const [negocio, setNegocio] = useState(»);
const [anuncios, setAnuncios] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(»);
const [isGenerated, setIsGenerated] = useState(false);
// Lista de rubros comunes
const rubrosComunes = [
‘Selecciona un rubro’,
‘Inmobiliaria’,
‘Educación’,
‘Salud’,
‘Tecnología’,
‘Automotriz’,
‘Servicios Financieros’,
‘Gastronomía’,
‘Turismo’,
‘Retail’,
‘Construcción’,
‘Servicios Profesionales’,
‘Belleza y Estética’,
‘Deportes y Fitness’,
‘Moda’,
‘Mascotas’,
‘Hogar y Decoración’,
‘Arte y Entretenimiento’,
‘Legal’,
‘Marketing Digital’,
‘Otro’
];
// Manejador de cambio para keywords
const handleKeywordChange = (index, value) => {
const newKeywords = […keywords];
newKeywords[index] = value;
setKeywords(newKeywords);
};
// Validar formulario
const validateForm = () => {
// Verificar que el rubro esté seleccionado o ingresado
if (rubro === ‘Selecciona un rubro’ || (rubro === ‘Otro’ && !customRubro)) {
setError(‘Por favor selecciona un rubro o ingresa uno personalizado.’);
return false;
}
// Verificar que haya 5 keywords
const validKeywords = keywords.filter(kw => kw.trim() !== »);
if (validKeywords.length !== 5) {
setError(‘Por favor ingresa exactamente 5 palabras clave.’);
return false;
}
// Validar URL si se ingresó
if (url && !isValidUrl(url)) {
setError(‘Por favor ingresa una URL válida.’);
return false;
}
setError(»);
return true;
};
// Validar URL
const isValidUrl = (urlString) => {
try {
new URL(urlString);
return true;
} catch (_) {
return false;
}
};
// Generar URL visible
const generateVisibleUrl = (keyword) => {
if (url) {
// Extraer el dominio de la URL
try {
const urlObj = new URL(url);
const domain = urlObj.hostname;
// Crear slug a partir de la keyword principal
const slug = keyword.toLowerCase().replace(/\s+/g, ‘-‘);
return `${domain}/${slug}`;
} catch (_) {
return url;
}
} else {
// URL genérica con dominio basado en el nombre del negocio o rubro
const base = negocio ? negocio.toLowerCase().replace(/\s+/g, ») :
(rubro !== ‘Otro’ ? rubro.toLowerCase().replace(/\s+/g, ») :
customRubro.toLowerCase().replace(/\s+/g, »));
const slug = keyword.toLowerCase().replace(/\s+/g, ‘-‘);
return `${base}.cl/${slug}`;
}
};
// Formato de palabras clave para los tipos de concordancia de Google Ads
const formatKeywords = (keyword) => {
return {
exacta: `[${keyword.toLowerCase()}]`,
frase: `»${keyword.toLowerCase()}»`,
ampliada: `+${keyword.toLowerCase().split(‘ ‘).join(‘ +’)}`
};
};
// Generar extensiones basadas en el objetivo y rubro
const generateExtensions = (objetivo, rubroActual) => {
const extensions = [];
// Extensiones comunes basadas en el objetivo
if (objetivo === ‘leads’) {
extensions.push(‘Solicita información’, ‘Cotiza ahora’, ‘Contáctanos’);
} else if (objetivo === ‘trafico’) {
extensions.push(‘Conoce más’, ‘Visita nuestra web’, ‘Descubre servicios’);
} else if (objetivo === ‘ventas’) {
extensions.push(‘Compra ahora’, ‘Ver ofertas’, ‘Productos destacados’);
} else if (objetivo === ‘contacto’) {
extensions.push(‘Llámanos’, ‘Escríbenos’, ‘Agenda una cita’);
}
// Extensiones específicas basadas en el rubro
if (rubroActual === ‘Inmobiliaria’) {
extensions.push(‘Proyectos disponibles’, ‘Agenda una visita’);
} else if (rubroActual === ‘Educación’) {
extensions.push(‘Proceso de admisión’, ‘Descarga malla curricular’);
} else if (rubroActual === ‘Salud’) {
extensions.push(‘Reserva tu hora’, ‘Especialidades’);
}
// Añadir extensión de WhatsApp para M&P
extensions.push(‘Agenda en WhatsApp +56992258137’);
// Seleccionar 3 extensiones aleatorias (excluyendo WhatsApp) si hay más de 3
if (extensions.length > 4) { // 3 + WhatsApp
// Separar la extensión de WhatsApp
const whatsappExt = extensions.pop();
// Ordenar aleatoriamente las demás extensiones
const shuffled = […extensions].sort(() => 0.5 – Math.random());
// Tomar las primeras 3 y añadir WhatsApp de nuevo
return […shuffled.slice(0, 3), whatsappExt];
}
return extensions;
};
// Función principal para generar anuncios
const generateAds = () => {
if (!validateForm()) return;
setIsLoading(true);
// Timeout simulado para dar sensación de procesamiento
setTimeout(() => {
try {
// Verificar si el rubro es válido (no es el valor inicial del dropdown)
if (rubro === ‘Selecciona un rubro’) {
setError(‘Por favor selecciona un rubro válido.’);
setIsLoading(false);
return;
}
const rubroActual = rubro === ‘Otro’ ? customRubro : rubro;
const generatedAds = [];
// Templates de título basados en el objetivo
const titleTemplates = {
leads: [
‘{keyword}’,
‘Solicita Información {beneficio}’,
‘Contáctanos Hoy’,
‘{negocio} | {keyword}’,
‘Expertos en {keyword}’,
‘¿Buscas {keyword}?’,
‘{beneficio} Garantizado’,
‘{keyword} Profesionales’,
‘Servicio de {keyword}’,
‘{keyword} en {ubicacion}’
],
trafico: [
‘Descubre {keyword}’,
‘Todo sobre {keyword}’,
‘Información de {keyword}’,
‘{keyword} | {negocio}’,
‘Guía de {keyword}’,
‘{keyword} Actualizados’,
‘Blog de {keyword}’,
‘Recursos de {keyword}’,
‘{keyword} Explicados’,
‘Novedades en {keyword}’
],
ventas: [
‘{keyword} en Oferta’,
‘Compra {keyword}’,
‘Desde ${precio}’,
‘{descuento}% Descuento en {keyword}’,
‘{keyword} Exclusivos’,
‘Mejores {keyword}’,
‘{keyword} Envío Gratis’,
‘Catálogo de {keyword}’,
‘{keyword} Garantizados’,
‘Nuevos {keyword} 2025’
],
contacto: [
‘Contacta con {negocio}’,
‘Servicio de {keyword}’,
‘Respuesta en 24h’,
‘Consulta por {keyword}’,
‘Asesoría en {keyword}’,
‘Expertos en {keyword}’,
‘Llámanos | {keyword}’,
‘Agenda tu {servicio}’,
‘{keyword} Personalizado’,
‘Cotiza tu {keyword}’
]
};
// Templates de descripción basados en el objetivo
const descTemplates = {
leads: [
‘Obtén toda la información sobre {keyword} que necesitas. Completa el formulario y te contactaremos.’,
‘Especialistas en {keyword} con años de experiencia. Déjanos tus datos y recibirás asesoría personalizada.’,
‘{negocio} te ofrece los mejores servicios de {keyword}. Solicita información sin compromiso.’,
‘Descubre cómo podemos ayudarte con {keyword}. Formulario rápido, respuesta inmediata.’,
‘Servicios profesionales de {keyword} adaptados a tus necesidades. Consulta gratis.’
],
trafico: [
‘Todo lo que necesitas saber sobre {keyword}. Visita nuestra web y mantente informado con los últimos contenidos.’,
‘Artículos, guías y recursos sobre {keyword}. Contenido actualizado por expertos para ti.’,
‘Descubre más sobre {keyword} en nuestra web especializada. Información completa y detallada.’,
‘Blog especializado en {keyword} con tips, consejos y novedades. Visítanos y aprende más.’,
‘Recursos gratuitos sobre {keyword} para que estés siempre al día. Visita nuestra página web.’
],
ventas: [
‘Las mejores ofertas en {keyword}. Envío a todo Chile. Garantía de satisfacción y devolución sin costo.’,
‘Compra {keyword} al mejor precio. Hasta 12 cuotas sin interés. Despacho express disponible.’,
‘Catálogo completo de {keyword} con descuentos exclusivos. Aprovecha nuestras promociones limitadas.’,
‘Venta online de {keyword} con garantía oficial. Stock disponible y envío inmediato.’,
‘{negocio}: Calidad garantizada en {keyword}. Ofertas especiales, atención personalizada.’
],
contacto: [
‘Comunícate con nuestros especialistas en {keyword}. Respuesta rápida y atención personalizada.’,
‘¿Necesitas ayuda con {keyword}? Estamos a un clic de distancia. Contacto directo con expertos.’,
‘Servicio de atención al cliente especializado en {keyword}. Contacta ahora mismo.’,
‘Resolvemos tus dudas sobre {keyword}. Diferentes canales de contacto disponibles 24/7.’,
‘Agenda una consulta sobre {keyword} con nuestros profesionales. Respuesta en menos de 24h.’
]
};
// Beneficios por rubro para usar en plantillas
const beneficios = {
‘Inmobiliaria’: [‘Sin comisión’, ‘Financiamiento directo’, ‘Entrega inmediata’, ‘Ubicación privilegiada’],
‘Educación’: [‘Becas disponibles’, ‘Clases personalizadas’, ‘Profesores certificados’, ‘Metodología única’],
‘Salud’: [‘Sin lista de espera’, ‘Atención integral’, ‘Especialistas certificados’, ‘Tecnología avanzada’],
‘Tecnología’: [‘Soporte 24/7’, ‘Tecnología de punta’, ‘Soluciones a medida’, ‘Integración completa’],
‘Automotriz’: [‘Garantía extendida’, ‘Financiamiento exclusivo’, ‘Servicio postventa’, ‘Test drive a domicilio’],
‘default’: [‘Premium’, ‘Profesional’, ‘Personalizado’, ‘Garantizado’]
};
// Ubicaciones generales para Chile
const ubicaciones = [‘Santiago’, ‘Región Metropolitana’, ‘Chile’, ‘Online’, ‘Todo Chile’];
// Precio ficticio según rubro (para plantillas de ventas)
const precios = {
‘Inmobiliaria’: ‘2.500 UF’,
‘Educación’: ‘50.000’,
‘Salud’: ‘25.000’,
‘Tecnología’: ‘99.990’,
‘Automotriz’: ‘9.990.000’,
‘default’: ‘19.990’
};
// Descuentos ficticios
const descuentos = [’10’, ’15’, ’20’, ’25’, ’30’, ’40’, ’50’];
// Servicios comunes según rubros
const servicios = {
‘Inmobiliaria’: [‘visita’, ‘tasación’, ‘asesoría’, ‘cotización’],
‘Educación’: [‘clase’, ‘asesoría’, ‘evaluación’, ‘matrícula’],
‘Salud’: [‘consulta’, ‘evaluación’, ‘examen’, ‘control’],
‘Tecnología’: [‘demostración’, ‘diagnóstico’, ‘implementación’, ‘soporte’],
‘default’: [‘consulta’, ‘asesoría’, ‘servicio’, ‘demostración’]
};
// Generar 5 anuncios diferentes
for (let i = 0; i < 5; i++) {
// Seleccionar una keyword diferente para cada anuncio
const mainKeyword = keywords[i];
// Variables para reemplazar en las plantillas
const beneficio = beneficios[rubroActual] || beneficios['default'];
const beneficioRandom = beneficio[Math.floor(Math.random() * beneficio.length)];
const ubicacion = ubicaciones[Math.floor(Math.random() * ubicaciones.length)];
const precio = precios[rubroActual] || precios['default'];
const descuento = descuentos[Math.floor(Math.random() * descuentos.length)];
const servicio = (servicios[rubroActual] || servicios['default'])[Math.floor(Math.random() * (servicios[rubroActual] || servicios['default']).length)];
// Seleccionar plantillas aleatorias para títulos
const titleTemplatesCopy = [...titleTemplates[objetivo]];
const shuffledTitles = titleTemplatesCopy.sort(() => 0.5 – Math.random()).slice(0, 3);
// Generar títulos (máximo 30 caracteres cada uno)
const titles = shuffledTitles.map(template => {
let title = template
.replace(‘{keyword}’, mainKeyword)
.replace(‘{negocio}’, negocio)
.replace(‘{beneficio}’, beneficioRandom)
.replace(‘{ubicacion}’, ubicacion)
.replace(‘{precio}’, precio)
.replace(‘{descuento}’, descuento)
.replace(‘{servicio}’, servicio);
// Asegurar que no exceda 30 caracteres
if (title.length > 30) {
title = title.substring(0, 27) + ‘…’;
}
return title;
});
// Seleccionar plantillas aleatorias para descripciones
const descTemplatesCopy = […descTemplates[objetivo]];
const shuffledDescs = descTemplatesCopy.sort(() => 0.5 – Math.random()).slice(0, 2);
// Generar descripciones (máximo 90 caracteres cada una)
const descriptions = shuffledDescs.map(template => {
let desc = template
.replace(‘{keyword}’, mainKeyword)
.replace(‘{negocio}’, negocio)
.replace(‘{beneficio}’, beneficioRandom)
.replace(‘{ubicacion}’, ubicacion);
// Asegurar que no exceda 90 caracteres
if (desc.length > 90) {
desc = desc.substring(0, 87) + ‘…’;
}
return desc;
});
// Generar URL visible
const visibleUrl = generateVisibleUrl(mainKeyword);
// Formatear keywords para los diferentes tipos de concordancia
const keywordFormats = formatKeywords(mainKeyword);
// Generar extensiones recomendadas
const extensions = generateExtensions(objetivo, rubroActual);
// Crear el anuncio completo
const anuncio = {
id: i + 1,
titulos: titles,
descripciones: descriptions,
urlVisible: visibleUrl,
keywordFormats,
extensiones: extensions
};
generatedAds.push(anuncio);
}
setAnuncios(generatedAds);
setIsGenerated(true);
setIsLoading(false);
} catch (err) {
setError(‘Ocurrió un error al generar los anuncios. Por favor intenta nuevamente.’);
setIsLoading(false);
}
}, 1500);
};
// Copiar todos los anuncios al portapapeles
const copyAllAds = () => {
const text = anuncios.map(anuncio => {
return `🎯 Anuncio ${anuncio.id}:\n` +
`Título 1: ${anuncio.titulos[0]}\n` +
`Título 2: ${anuncio.titulos[1]}\n` +
`Título 3: ${anuncio.titulos[2]}\n` +
`Descripción 1: ${anuncio.descripciones[0]}\n` +
`Descripción 2: ${anuncio.descripciones[1]}\n` +
`URL visible: ${anuncio.urlVisible}\n` +
`Palabras clave sugeridas:\n` +
`- ${anuncio.keywordFormats.exacta}\n` +
`- ${anuncio.keywordFormats.frase}\n` +
`- ${anuncio.keywordFormats.ampliada}\n` +
`Extensiones recomendadas:\n` +
anuncio.extensiones.map(ext => `- ${ext}`).join(‘\n’);
}).join(‘\n\n’);
navigator.clipboard.writeText(text)
.then(() => {
alert(‘¡Anuncios copiados al portapapeles!’);
})
.catch(err => {
console.error(‘Error al copiar: ‘, err);
alert(‘No se pudieron copiar los anuncios. Intenta seleccionarlos manualmente.’);
});
};
// Descargar anuncios como PDF (simulado con alert)
const downloadAsPDF = () => {
alert(‘Funcionalidad de descarga en PDF disponible en la versión completa.’);
};
// Reiniciar generador
const resetGenerator = () => {
setAnuncios([]);
setIsGenerated(false);
};
return (
{/* Panel de entrada */}
Generador de Anuncios Google Ads
{error && (
)}
{/* Selector de rubro */}
{/* Campo de texto para rubro personalizado */}
{rubro === ‘Otro’ && (
setCustomRubro(e.target.value)}
placeholder=»Ingresa tu rubro personalizado»
/>
)}
{/* Campos para palabras clave */}
{/* Objetivo del anuncio */}
{/* URL destino */}
setUrl(e.target.value)}
placeholder=»https://ejemplo.com»
/>
{/* Nombre del negocio */}
setNegocio(e.target.value)}
placeholder=»Nombre de tu empresa»
/>
{/* Botón de generar */}
{/* Logo M&P y disclaimer */}
Herramienta desarrollada por Müller & Pérez
Agencia de Marketing Digital y Performance
{/* Resultados – solo se muestran cuando hay anuncios generados */}
{isGenerated && (
Anuncios Generados (5)
{/* Anuncios */}
{anuncios.map((anuncio) => (
🎯 Anuncio {anuncio.id}
{/* Preview del anuncio estilo Google Ads */}
Anuncio
www.{anuncio.urlVisible}
{anuncio.titulos[0]} | {anuncio.titulos[1]}
{anuncio.titulos[2]}
{anuncio.descripciones[0]}
{anuncio.descripciones[1]}
{anuncio.extensiones.map((ext, idx) => (
{ext}
))}
{/* Detalles técnicos del anuncio */}
Títulos:
{anuncio.titulos.map((titulo, idx) => (
- {titulo} ({titulo.length}/30)
))}
Descripciones:
{anuncio.descripciones.map((desc, idx) => (
- {desc} ({desc.length}/90)
))}
URL visible:
{anuncio.urlVisible}
Palabras clave sugeridas:
- Concordancia exacta: {anuncio.keywordFormats.exacta}
- Concordancia de frase: {anuncio.keywordFormats.frase}
- Concordancia amplia modificada: {anuncio.keywordFormats.ampliada}
Extensiones recomendadas:
{anuncio.extensiones.map((ext, idx) => (
- {ext}
))}
))}
{/* CTA final */}
¿Quieres que creemos la campaña por ti?
Nuestro equipo de expertos puede implementar estos anuncios y optimizarlos para obtener los mejores resultados.
{/* Formulario de contacto WhatsApp */}
Agenda una reunión con nosotros
* Te contactaremos al WhatsApp +56 9 92258137
Solicitar cotización
)}
);
};
export default GoogleAdsGenerator;