Implement WhatsApp connection flow

- Updated database on instance creation.
- Added n8n workflow activation.
- Filtered instance display by user email.
This commit is contained in:
gpt-engineer-app[bot] 2025-06-19 22:28:40 +00:00
parent 020ba4d396
commit ec390787c6
4 changed files with 126 additions and 22 deletions

View File

@ -7,7 +7,7 @@ import { Label } from '@/components/ui/label';
import { MessageCircle, AlertCircle } from 'lucide-react'; import { MessageCircle, AlertCircle } from 'lucide-react';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { createWhatsAppInstance } from '@/services/whatsAppService'; import { createWhatsAppInstance } from '@/services/whatsAppService';
import { updateUserWhatsAppInstance, getUserWhatsAppInstance } from '@/services/whatsAppInstanceService'; import { updateUserWhatsAppInstance, getUserWhatsAppInstance, activateUserWorkflow } from '@/services/whatsAppInstanceService';
import { WhatsAppInstance } from '@/types/whatsAppTypes'; import { WhatsAppInstance } from '@/types/whatsAppTypes';
import { Alert, AlertDescription } from '@/components/ui/alert'; import { Alert, AlertDescription } from '@/components/ui/alert';
@ -104,17 +104,34 @@ const CreateInstanceForm = ({
setLoading(true); setLoading(true);
try { try {
console.log(`Criando instância com nome ${instanceName} e número ${phoneNumber}`); console.log(`🚀 Iniciando criação de instância com nome ${instanceName} e número ${phoneNumber}`);
// 1. Primeiro atualizar o banco de dados com a instância // 1. Criar instância na API
await updateUserWhatsAppInstance(userEmail, instanceName, 'desconectado'); console.log('📡 Passo 1: Criando instância na API...');
console.log('Instância registrada no banco de dados');
// 2. Criar instância na API
const data = await createWhatsAppInstance(instanceName, phoneNumber); const data = await createWhatsAppInstance(instanceName, phoneNumber);
console.log('Resposta da API de criação de instância:', data); console.log('✅ Resposta da API de criação de instância:', data);
// 3. Criar objeto da instância // 2. Atualizar o banco de dados com status "conectado"
console.log('💾 Passo 2: Atualizando banco de dados...');
await updateUserWhatsAppInstance(userEmail, instanceName, 'conectado');
console.log('✅ Instância registrada no banco de dados com status "conectado"');
// 3. Ativar o workflow do usuário no n8n
console.log('🔄 Passo 3: Ativando workflow do usuário no n8n...');
try {
await activateUserWorkflow(userEmail);
console.log('✅ Workflow ativado com sucesso no n8n');
} catch (workflowError) {
console.error('⚠️ Erro ao ativar workflow, mas instância foi criada:', workflowError);
// Não bloquear o fluxo se o workflow falhar, apenas loggar
toast({
title: "Aviso",
description: "Instância criada, mas houve um problema ao ativar a automação. Entre em contato com o suporte.",
variant: "destructive",
});
}
// 4. Criar objeto da instância
const newInstance: WhatsAppInstance = { const newInstance: WhatsAppInstance = {
instanceName, instanceName,
instanceId: instanceName, instanceId: instanceName,
@ -125,31 +142,31 @@ const CreateInstanceForm = ({
connectionState: 'closed' connectionState: 'closed'
}; };
console.log('Nova instância criada:', newInstance); console.log('Nova instância criada:', newInstance);
// 4. Atualizar estado para evitar nova criação // 5. Atualizar estado para evitar nova criação
setHasExistingInstance(true); setHasExistingInstance(true);
// 5. Notificar componente pai // 6. Notificar componente pai
onInstanceCreated(newInstance); onInstanceCreated(newInstance);
toast({ toast({
title: "Sucesso!", title: "Sucesso!",
description: "Instância do WhatsApp criada com sucesso!" description: "Instância do WhatsApp criada e ativada com sucesso!"
}); });
// Reset form fields // Reset form fields
setPhoneNumber(''); setPhoneNumber('');
} catch (error) { } catch (error) {
console.error("Erro ao criar instância WhatsApp:", error); console.error("💥 Erro ao criar instância WhatsApp:", error);
// Se houve erro na API, remover do banco de dados // Se houve erro na API, tentar reverter no banco de dados
try { try {
await updateUserWhatsAppInstance(userEmail, '', 'desconectado'); await updateUserWhatsAppInstance(userEmail, '', 'desconectado');
console.log('Instância removida do banco devido ao erro na API'); console.log('🔄 Instância removida do banco devido ao erro na API');
} catch (dbError) { } catch (dbError) {
console.error('Erro ao remover instância do banco:', dbError); console.error('❌ Erro ao reverter instância no banco:', dbError);
} }
toast({ toast({
@ -260,6 +277,7 @@ const CreateInstanceForm = ({
<li> Apenas uma instância por usuário é permitida</li> <li> Apenas uma instância por usuário é permitida</li>
<li> O nome da instância será seu email de login</li> <li> O nome da instância será seu email de login</li>
<li> Após criar, você precisará escanear o QR Code para conectar</li> <li> Após criar, você precisará escanear o QR Code para conectar</li>
<li> Sua automação financeira será ativada automaticamente</li>
</ul> </ul>
</div> </div>
</CardContent> </CardContent>

View File

@ -3,6 +3,8 @@ import { useInstanceState } from './whatsApp/useInstanceState';
import { useInstanceOperations } from './whatsApp/useInstanceOperations'; import { useInstanceOperations } from './whatsApp/useInstanceOperations';
import { useInstanceStatusCheck } from './whatsApp/useInstanceStatusCheck'; import { useInstanceStatusCheck } from './whatsApp/useInstanceStatusCheck';
import { useInstanceRefresh } from './whatsApp/useInstanceRefresh'; import { useInstanceRefresh } from './whatsApp/useInstanceRefresh';
import { WhatsAppInstance } from '@/types/whatsAppTypes';
import { useMemo } from 'react';
export const useWhatsAppInstances = () => { export const useWhatsAppInstances = () => {
const { const {
@ -34,8 +36,28 @@ export const useWhatsAppInstances = () => {
setIsRefreshing setIsRefreshing
); );
// Filtrar instâncias para mostrar apenas as do usuário logado
const filteredInstances = useMemo(() => {
const userEmail = localStorage.getItem('userEmail');
if (!userEmail) {
console.log('❌ Email do usuário não encontrado, retornando lista vazia');
return [];
}
const filtered = instances.filter((instance: WhatsAppInstance) => {
// Comparar o instanceName com o email do usuário
// Como o instanceName é o email do usuário, podemos fazer a comparação direta
const isUserInstance = instance.instanceName === userEmail;
console.log(`🔍 Verificando instância ${instance.instanceName} para usuário ${userEmail}: ${isUserInstance ? 'INCLUIR' : 'EXCLUIR'}`);
return isUserInstance;
});
console.log(`📋 Total de instâncias: ${instances.length}, Filtradas para usuário ${userEmail}: ${filtered.length}`);
return filtered;
}, [instances]);
return { return {
instances, instances: filteredInstances, // Retornar instâncias filtradas
isRefreshing, isRefreshing,
currentUserId, currentUserId,
addInstance, addInstance,

View File

@ -57,7 +57,7 @@ const WhatsApp = () => {
// Handler para quando o usuário cria uma nova instância // Handler para quando o usuário cria uma nova instância
const handleInstanceCreated = (newInstance: WhatsAppInstance) => { const handleInstanceCreated = (newInstance: WhatsAppInstance) => {
console.log('New instance to be added:', newInstance); console.log('🎉 Nova instância criada:', newInstance);
addInstance(newInstance); addInstance(newInstance);
setInstanceFound(true); setInstanceFound(true);
setShowCreateForm(false); setShowCreateForm(false);
@ -82,7 +82,7 @@ const WhatsApp = () => {
// Handler for when an instance is deleted // Handler for when an instance is deleted
const handleDeleteInstanceWrapper = (instanceId: string) => { const handleDeleteInstanceWrapper = (instanceId: string) => {
console.log(`Instance deletion requested for ID: ${instanceId}`); console.log(`🗑️ Solicitação de exclusão da instância ID: ${instanceId}`);
const instanceToDelete = instances.find(i => i.instanceId === instanceId); const instanceToDelete = instances.find(i => i.instanceId === instanceId);
if (instanceToDelete) { if (instanceToDelete) {
handleDeleteInstance(instanceId, instanceToDelete.instanceName); handleDeleteInstance(instanceId, instanceToDelete.instanceName);
@ -93,18 +93,26 @@ const WhatsApp = () => {
setShowCreateForm(true); setShowCreateForm(true);
} }
} else { } else {
console.error(`Instance with ID ${instanceId} not found for deletion`); console.error(`❌ Instância com ID ${instanceId} não encontrada para exclusão`);
} }
}; };
// Check if we have any instances to show // Check if we have any instances to show
const hasInstances = Array.isArray(instances) && instances.length > 0; const hasInstances = Array.isArray(instances) && instances.length > 0;
const userEmail = localStorage.getItem('userEmail') || '';
return ( return (
<Layout> <Layout>
<div className="space-y-6"> <div className="space-y-6">
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<div>
<h1 className="text-2xl font-bold tracking-tight">Conectar WhatsApp</h1> <h1 className="text-2xl font-bold tracking-tight">Conectar WhatsApp</h1>
{userEmail && (
<p className="text-sm text-muted-foreground mt-1">
Mostrando instâncias para: <strong>{userEmail}</strong>
</p>
)}
</div>
{/* Update List Button - Always visible */} {/* Update List Button - Always visible */}
<Button <Button

View File

@ -169,3 +169,59 @@ export async function getUserDebugInfo(userEmail: string): Promise<any> {
throw error; throw error;
} }
} }
/**
* Ativa o workflow do usuário no n8n
*/
export async function activateUserWorkflow(userEmail: string): Promise<void> {
try {
console.log(`🔄 Iniciando ativação do workflow para usuário: ${userEmail}`);
// Primeiro, buscar o workflow_id do usuário
const { data: userData, error: fetchError } = await supabase
.from('usuarios')
.select('workflow_id')
.eq('email', userEmail.trim().toLowerCase())
.single();
if (fetchError) {
console.error('❌ Erro ao buscar workflow_id do usuário:', fetchError);
throw new Error(`Erro ao buscar workflow_id: ${fetchError.message}`);
}
if (!userData || !userData.workflow_id) {
console.error('⚠️ Usuário não possui workflow_id configurado');
throw new Error('Usuário não possui workflow configurado');
}
const workflowId = userData.workflow_id;
console.log(`📋 Workflow ID encontrado: ${workflowId}`);
// Fazer a requisição para ativar o workflow
const activationUrl = `https://n8n.innova1001.com.br/api/v1/workflows/${workflowId}/activate`;
console.log(`🔗 URL de ativação: ${activationUrl}`);
const response = await fetch(activationUrl, {
method: 'POST',
headers: {
'X-N8N-API-KEY': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2YmM4MjQxOS0zZTk1LTRiYmMtODMwMy0xODAzZjk4YmQ4YjciLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzQ5MjA2NTk1fQ.-5mUcQNbVTjAUyneSun9a-3xpwGEMFHSkK4k59W11wk',
'Content-Type': 'application/json'
}
});
console.log(`📡 Status da resposta da ativação: ${response.status}`);
if (!response.ok) {
const errorText = await response.text();
console.error(`❌ Erro ao ativar workflow: ${response.status} - ${errorText}`);
throw new Error(`Erro ao ativar workflow: ${response.status} - ${errorText}`);
}
const responseData = await response.json();
console.log('✅ Workflow ativado com sucesso:', responseData);
} catch (error) {
console.error('💥 Erro crítico ao ativar workflow do usuário:', error);
throw error;
}
}