From 3b0313d5c09e09a8cf2b572916cb4efe1d639449 Mon Sep 17 00:00:00 2001 From: Sidney Gomes Date: Sat, 25 Jul 2026 21:19:48 -0300 Subject: [PATCH] Adicionado endpoint e botao para Testar Envio de Template do WhatsApp --- server.ts | 54 ++++++++++++++++++++++++++++ src/components/AdminMessagesView.tsx | 54 +++++++++++++++++++++++++--- 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/server.ts b/server.ts index e4a4dae..e5c41ca 100644 --- a/server.ts +++ b/server.ts @@ -2562,6 +2562,60 @@ app.post('/api/admin/reply-message', authenticateToken, requireAdmin, async (req } }); +// Admin: Test WhatsApp template message +app.post('/api/admin/whatsapp/test-template', authenticateToken, requireAdmin, async (req: AuthenticatedRequest, res: Response) => { + try { + const { templateId } = req.body; + if (!templateId) return res.status(400).json({ error: 'templateId é obrigatório' }); + + const adminUser = await prisma.user.findUnique({ where: { id: req.user!.id } }); + if (!adminUser?.whatsapp) { + return res.status(400).json({ error: 'Você precisa ter um número de WhatsApp configurado no seu perfil para receber o teste.' }); + } + + const settings = await prisma.systemSettings.findFirst(); + let templateStr = ''; + + switch(templateId) { + case 'whatsappTemplatePayment': + templateStr = settings?.whatsappTemplatePayment || ''; + break; + case 'whatsappTemplateWelcome': + templateStr = settings?.whatsappTemplateWelcome || ''; + break; + case 'whatsappTemplateNewContent': + templateStr = settings?.whatsappTemplateNewContent || ''; + break; + case 'whatsappTemplatePromo': + templateStr = settings?.whatsappTemplatePromo || ''; + break; + } + + if (!templateStr) { + return res.status(400).json({ error: 'Este modelo de mensagem ainda não foi configurado ou está vazio.' }); + } + + const firstName = adminUser.name.split(' ')[0]; + const msg = processTemplate(templateStr, { + nome: firstName, + curso: 'Curso de Informática (TESTE)', + plano: 'Plano Premium (TESTE)', + valor: 'R$ 49,90' + }); + + const success = await sendWhatsappNotification(adminUser.whatsapp, msg); + + if (success) { + res.json({ success: true, message: 'Mensagem de teste enviada com sucesso para o seu número!' }); + } else { + res.status(500).json({ error: 'Falha ao enviar mensagem pela Evolution API. Verifique a conexão e o status da instância.' }); + } + } catch (error) { + console.error('Error testing template:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + // Admin: Broadcast WhatsApp message to all students with anti-spam delay app.post('/api/admin/whatsapp/broadcast', authenticateToken, requireAdmin, async (req: AuthenticatedRequest, res: Response) => { try { diff --git a/src/components/AdminMessagesView.tsx b/src/components/AdminMessagesView.tsx index 8ec0f8b..1917bdf 100644 --- a/src/components/AdminMessagesView.tsx +++ b/src/components/AdminMessagesView.tsx @@ -107,6 +107,7 @@ export default function AdminMessagesView() { const [activeTemplateModal, setActiveTemplateModal] = useState(null); const [currentTemplateText, setCurrentTemplateText] = useState(''); const [isSavingTemplate, setIsSavingTemplate] = useState(false); + const [isTestingTemplate, setIsTestingTemplate] = useState(null); const [showEmojiPicker, setShowEmojiPicker] = useState(false); const textareaRef = useRef(null); @@ -202,6 +203,30 @@ export default function AdminMessagesView() { } }; + const handleTestTemplate = async (templateId: string, e: React.MouseEvent) => { + e.stopPropagation(); + setIsTestingTemplate(templateId); + try { + const token = localStorage.getItem('admin_token'); + const res = await fetch('/api/admin/whatsapp/test-template', { + method: 'POST', + headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, + body: JSON.stringify({ templateId }) + }); + const data = await res.json(); + if (res.ok) { + setAlertModal({isOpen: true, title: 'Enviado! 📱', message: data.message}); + } else { + setAlertModal({isOpen: true, title: 'Erro no Teste', message: data.error, isError: true}); + } + } catch (error) { + console.error('Error testing template:', error); + setAlertModal({isOpen: true, title: 'Erro', message: 'Erro interno ao testar template.', isError: true}); + } finally { + setIsTestingTemplate(null); + } + }; + const insertEmoji = (emoji: string, isForBroadcast = false) => { const ref = isForBroadcast ? broadcastRef : textareaRef; const setter = isForBroadcast ? setBroadcastText : setCurrentTemplateText; @@ -452,11 +477,30 @@ export default function AdminMessagesView() { {tag} ))} -
-
- - {settings?.[t.id] ? 'Ativo' : 'Não configurado'} - +
+
+
+ + {settings?.[t.id] ? 'Ativo' : 'Não configurado'} + +
+ + {settings?.[t.id] && ( + + )}
))}