From 417c24089b002b855fe86f976780f43ffb0b4b6a Mon Sep 17 00:00:00 2001
From: "gpt-engineer-app[bot]"
<159125892+gpt-engineer-app[bot]@users.noreply.github.com>
Date: Sat, 24 May 2025 14:02:02 +0000
Subject: [PATCH] Run SQL to add WhatsApp columns
Adds `instancia_zap` and `status_instancia` columns to the `usuarios` table.
---
src/components/ui/alert.tsx | 1 +
.../whatsapp/CreateInstanceForm.tsx | 35 ++--
.../whatsappGroups/CreateGroupForm.tsx | 190 ++++++++++++------
src/integrations/supabase/types.ts | 6 +
src/services/whatsAppGroupCreationService.ts | 81 ++++++++
src/services/whatsAppInstanceService.ts | 58 ++++++
6 files changed, 299 insertions(+), 72 deletions(-)
create mode 100644 src/services/whatsAppGroupCreationService.ts
create mode 100644 src/services/whatsAppInstanceService.ts
diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx
index 41fa7e0..c5acc6f 100644
--- a/src/components/ui/alert.tsx
+++ b/src/components/ui/alert.tsx
@@ -1,3 +1,4 @@
+
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
diff --git a/src/components/whatsapp/CreateInstanceForm.tsx b/src/components/whatsapp/CreateInstanceForm.tsx
index 3ce88bc..4626e6b 100644
--- a/src/components/whatsapp/CreateInstanceForm.tsx
+++ b/src/components/whatsapp/CreateInstanceForm.tsx
@@ -7,6 +7,7 @@ import { Label } from '@/components/ui/label';
import { MessageCircle } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
import { createWhatsAppInstance } from '@/services/whatsAppService';
+import { updateUserWhatsAppInstance } from '@/services/whatsAppInstanceService';
import { WhatsAppInstance } from '@/types/whatsAppTypes';
interface CreateInstanceFormProps {
@@ -20,23 +21,19 @@ const CreateInstanceForm = ({
}: CreateInstanceFormProps) => {
const { toast } = useToast();
const [loading, setLoading] = useState(false);
- const [instanceName, setInstanceName] = useState(initialInstanceName || '');
const [phoneNumber, setPhoneNumber] = useState('');
const currentUserId = localStorage.getItem('userId') || '';
+ const userEmail = localStorage.getItem('userEmail') || '';
- // Update instance name if initial value changes
- useEffect(() => {
- if (initialInstanceName) {
- setInstanceName(initialInstanceName);
- }
- }, [initialInstanceName]);
+ // Nome da instância será sempre o email do usuário
+ const instanceName = userEmail;
const handleCreateInstance = async () => {
// Validate form fields
- if (!instanceName.trim()) {
+ if (!userEmail) {
toast({
title: "Erro",
- description: "O nome da instância é obrigatório",
+ description: "Email do usuário não encontrado. Faça login novamente.",
variant: "destructive",
});
return;
@@ -82,6 +79,15 @@ const CreateInstanceForm = ({
console.log('New instance created:', newInstance);
+ // Atualizar o banco de dados com a instância
+ try {
+ await updateUserWhatsAppInstance(userEmail, instanceName, 'desconectado');
+ console.log('Instância salva no banco de dados');
+ } catch (dbError) {
+ console.error('Erro ao salvar instância no banco:', dbError);
+ // Não bloquear o processo se falhar ao salvar no banco
+ }
+
// Notify parent component about the new instance
onInstanceCreated(newInstance);
@@ -122,11 +128,12 @@ const CreateInstanceForm = ({
setInstanceName(e.target.value)}
- placeholder="Digite um nome para a instância"
- required
+ disabled
+ className="bg-gray-100"
/>
-
O nome será usado para identificar esta conexão
+
+ O nome da instância será automaticamente seu email de login
+
@@ -144,7 +151,7 @@ const CreateInstanceForm = ({
diff --git a/src/components/whatsappGroups/CreateGroupForm.tsx b/src/components/whatsappGroups/CreateGroupForm.tsx
index 912e298..e4b4a1a 100644
--- a/src/components/whatsappGroups/CreateGroupForm.tsx
+++ b/src/components/whatsappGroups/CreateGroupForm.tsx
@@ -1,11 +1,14 @@
-import { useState } from 'react';
+import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
-import { Loader2, Plus } from 'lucide-react';
+import { Loader2, Plus, AlertCircle } from 'lucide-react';
+import { Alert, AlertDescription } from '@/components/ui/alert';
import { cadastrarGrupoWhatsApp } from '@/services/gruposWhatsAppService';
+import { getUserWhatsAppInstance } from '@/services/whatsAppInstanceService';
+import { createWhatsAppGroup, updateGroupRemoteJid } from '@/services/whatsAppGroupCreationService';
import { useToast } from '@/hooks/use-toast';
interface CreateGroupFormProps {
@@ -17,14 +20,45 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
const { toast } = useToast();
const [cadastrando, setCadastrando] = useState
(false);
const [nomeGrupo, setNomeGrupo] = useState('');
- const [errorMessage, setErrorMessage] = useState(null);
- const [debugInfo, setDebugInfo] = useState(null);
+ const [hasWhatsAppInstance, setHasWhatsAppInstance] = useState(false);
+ const [checkingInstance, setCheckingInstance] = useState(true);
+ const [userInstance, setUserInstance] = useState<{
+ instancia_zap: string | null;
+ status_instancia: string | null;
+ whatsapp: string | null;
+ } | null>(null);
- // Cadastrar novo grupo ou atualizar workflow se necessário
+ // Verificar se o usuário tem instância WhatsApp
+ useEffect(() => {
+ const checkUserInstance = async () => {
+ if (!userEmail) return;
+
+ setCheckingInstance(true);
+ try {
+ const instanceData = await getUserWhatsAppInstance(userEmail);
+ console.log('Dados da instância do usuário:', instanceData);
+
+ if (instanceData && instanceData.instancia_zap && instanceData.instancia_zap.trim() !== '') {
+ setHasWhatsAppInstance(true);
+ setUserInstance(instanceData);
+ } else {
+ setHasWhatsAppInstance(false);
+ setUserInstance(null);
+ }
+ } catch (error) {
+ console.error('Erro ao verificar instância do usuário:', error);
+ setHasWhatsAppInstance(false);
+ setUserInstance(null);
+ } finally {
+ setCheckingInstance(false);
+ }
+ };
+
+ checkUserInstance();
+ }, [userEmail]);
+
+ // Cadastrar novo grupo
const handleCadastrarGrupo = async () => {
- setErrorMessage(null);
- setDebugInfo(null);
-
if (!userEmail) {
toast({
title: 'Erro',
@@ -43,61 +77,78 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
return;
}
+ if (!userInstance || !userInstance.instancia_zap || !userInstance.whatsapp) {
+ toast({
+ title: 'Erro',
+ description: 'Dados da instância WhatsApp não encontrados',
+ variant: 'destructive',
+ });
+ return;
+ }
+
setCadastrando(true);
try {
console.log("Iniciando processo de cadastro de grupo...");
+
+ // 1. Cadastrar grupo no banco de dados local
const grupo = await cadastrarGrupoWhatsApp(nomeGrupo.trim());
- if (grupo) {
- let successMessage = 'Grupo registrado com sucesso';
- let variant: 'default' | 'destructive' = 'default';
+ if (!grupo) {
+ throw new Error('Não foi possível cadastrar o grupo no banco de dados');
+ }
+
+ // 2. Criar grupo no WhatsApp via API
+ try {
+ const groupResponse = await createWhatsAppGroup(
+ userInstance.instancia_zap,
+ userEmail,
+ userInstance.whatsapp
+ );
- if (grupo.workflow_id) {
- successMessage = 'Grupo cadastrado e workflow criado com sucesso!';
+ console.log('Resposta da criação do grupo:', groupResponse);
+
+ // 3. Atualizar remote_jid no banco de dados
+ if (groupResponse.id) {
+ await updateGroupRemoteJid(grupo.id, groupResponse.id);
+
+ toast({
+ title: 'Sucesso!',
+ description: `Grupo "${groupResponse.subject}" criado com sucesso no seu WhatsApp!`,
+ variant: 'default',
+ });
} else {
- successMessage = 'Grupo cadastrado, mas falha ao criar workflow de automação.';
- setDebugInfo('O grupo foi criado no Supabase, mas houve um problema ao criar o workflow no n8n. Verifique os logs do console para mais detalhes.');
- variant = 'destructive';
+ toast({
+ title: 'Atenção',
+ description: 'Grupo cadastrado no sistema, mas não foi possível criar no WhatsApp',
+ variant: 'destructive',
+ });
}
+ } catch (apiError) {
+ console.error('Erro ao criar grupo via API:', apiError);
toast({
- title: grupo.workflow_id ? 'Sucesso' : 'Atenção',
- description: successMessage,
- variant: variant,
- });
-
- // Resetar o campo de nome
- setNomeGrupo('');
-
- // Atualizar a lista de grupos
- onSuccess();
- } else {
- setErrorMessage('Não foi possível registrar o grupo. Verifique a conexão com o Supabase.');
- toast({
- title: 'Erro',
- description: 'Não foi possível registrar o grupo',
+ title: 'Atenção',
+ description: 'Grupo cadastrado no sistema, mas houve erro ao criar no WhatsApp. Verifique sua conexão.',
variant: 'destructive',
});
}
+
+ // Resetar o campo de nome
+ setNomeGrupo('');
+
+ // Atualizar a lista de grupos
+ onSuccess();
+
} catch (error) {
console.error('Erro ao cadastrar grupo:', error);
let errorMsg = 'Erro desconhecido';
if (error instanceof Error) {
errorMsg = error.message;
-
- // Tentar extrair detalhes específicos do erro se existirem
- if (errorMsg.includes('Status')) {
- const statusMatch = errorMsg.match(/Status (\d+)/);
- if (statusMatch && statusMatch[1]) {
- setDebugInfo(`Código de status HTTP da API: ${statusMatch[1]}`);
- }
- }
}
- setErrorMessage('Erro ao cadastrar grupo: ' + errorMsg);
toast({
title: 'Erro',
- description: 'Não foi possível registrar o grupo',
+ description: `Não foi possível registrar o grupo: ${errorMsg}`,
variant: 'destructive',
});
} finally {
@@ -105,6 +156,39 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
}
};
+ if (checkingInstance) {
+ return (
+
+
+
+ Verificando instância WhatsApp...
+
+
+ );
+ }
+
+ if (!hasWhatsAppInstance) {
+ return (
+
+
+ Cadastrar novo grupo
+
+ Para criar um grupo é necessário ter uma instância do WhatsApp conectada
+
+
+
+
+
+
+ Para criar um grupo é necessário cadastrar e conectar sua instância do WhatsApp.
+ Acesse o menu de conexão e realize este processo primeiro.
+
+
+
+
+ );
+ }
+
return (
@@ -129,7 +213,7 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
-
Após cadastrar:
-
- - Adicione o número (61)99244-4275 ao grupo do WhatsApp que deseja automatizar
- - Envie uma mensagem neste grupo com o seguinte texto:
-
-
-
- {userEmail}
-
-
-
- Copie e cole o email exatamente como aparece acima
-
+
Informações importantes:
+
+ - O grupo será criado automaticamente no seu WhatsApp
+ - Você será adicionado como participante do grupo
+ - O grupo terá o nome: FinDash - {userEmail.split('@')[0]}
+
-
- {errorMessage && {errorMessage}
}
- {debugInfo && {debugInfo}
}
);
diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts
index 7539330..12e3391 100644
--- a/src/integrations/supabase/types.ts
+++ b/src/integrations/supabase/types.ts
@@ -293,9 +293,11 @@ export type Database = {
email: string
empresa: string | null
id: string
+ instancia_zap: string | null
nome: string
remote_jid: string | null
senha: string
+ status_instancia: string | null
whatsapp: string
}
Insert: {
@@ -303,9 +305,11 @@ export type Database = {
email: string
empresa?: string | null
id?: string
+ instancia_zap?: string | null
nome: string
remote_jid?: string | null
senha: string
+ status_instancia?: string | null
whatsapp: string
}
Update: {
@@ -313,9 +317,11 @@ export type Database = {
email?: string
empresa?: string | null
id?: string
+ instancia_zap?: string | null
nome?: string
remote_jid?: string | null
senha?: string
+ status_instancia?: string | null
whatsapp?: string
}
Relationships: []
diff --git a/src/services/whatsAppGroupCreationService.ts b/src/services/whatsAppGroupCreationService.ts
new file mode 100644
index 0000000..d17127b
--- /dev/null
+++ b/src/services/whatsAppGroupCreationService.ts
@@ -0,0 +1,81 @@
+
+import { supabase } from "@/integrations/supabase/client";
+
+interface CreateGroupResponse {
+ id: string;
+ subject: string;
+ description?: string;
+ participants?: string[];
+}
+
+/**
+ * Cria um grupo WhatsApp via API da Evolution
+ */
+export async function createWhatsAppGroup(
+ instanceName: string,
+ userEmail: string,
+ userPhone: string
+): Promise {
+ try {
+ // Extrair a parte antes do @ do email
+ const emailPrefix = userEmail.split('@')[0];
+ const groupSubject = `FinDash - ${emailPrefix}`;
+
+ const url = `https://evolutionapi2.innova1001.com.br/group/create/${instanceName}`;
+
+ const requestBody = {
+ subject: groupSubject,
+ description: "Seu sistema financeiro Inteligente e Pratico",
+ participants: [userPhone]
+ };
+
+ console.log('Criando grupo WhatsApp:', { url, requestBody });
+
+ const response = await fetch(url, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(requestBody)
+ });
+
+ if (!response.ok) {
+ const errorText = await response.text();
+ console.error('Erro na resposta da API:', response.status, errorText);
+ throw new Error(`Falha ao criar grupo: ${response.status} - ${errorText}`);
+ }
+
+ const data = await response.json();
+ console.log('Grupo criado com sucesso:', data);
+
+ return data;
+ } catch (error) {
+ console.error('Erro ao criar grupo WhatsApp:', error);
+ throw error;
+ }
+}
+
+/**
+ * Atualiza o remote_jid do grupo no banco de dados
+ */
+export async function updateGroupRemoteJid(
+ groupId: number,
+ remoteJid: string
+): Promise {
+ try {
+ const { error } = await supabase
+ .from('grupos_whatsapp')
+ .update({ remote_jid: remoteJid })
+ .eq('id', groupId);
+
+ if (error) {
+ console.error('Erro ao atualizar remote_jid:', error);
+ throw error;
+ }
+
+ console.log(`Remote JID atualizado para o grupo ${groupId}: ${remoteJid}`);
+ } catch (error) {
+ console.error('Erro ao atualizar remote_jid no banco:', error);
+ throw error;
+ }
+}
diff --git a/src/services/whatsAppInstanceService.ts b/src/services/whatsAppInstanceService.ts
new file mode 100644
index 0000000..72bc0c8
--- /dev/null
+++ b/src/services/whatsAppInstanceService.ts
@@ -0,0 +1,58 @@
+
+import { supabase } from "@/integrations/supabase/client";
+
+/**
+ * Atualiza a instância WhatsApp do usuário no banco de dados
+ */
+export async function updateUserWhatsAppInstance(
+ userEmail: string,
+ instanceName: string,
+ status: 'conectado' | 'desconectado'
+): Promise {
+ try {
+ const { error } = await supabase
+ .from('usuarios')
+ .update({
+ instancia_zap: instanceName,
+ status_instancia: status
+ })
+ .eq('email', userEmail.trim().toLowerCase());
+
+ if (error) {
+ console.error('Erro ao atualizar instância WhatsApp:', error);
+ throw error;
+ }
+
+ console.log(`Instância WhatsApp atualizada: ${instanceName} - ${status}`);
+ } catch (error) {
+ console.error('Erro ao atualizar instância WhatsApp no banco:', error);
+ throw error;
+ }
+}
+
+/**
+ * Busca a instância WhatsApp do usuário
+ */
+export async function getUserWhatsAppInstance(userEmail: string): Promise<{
+ instancia_zap: string | null;
+ status_instancia: string | null;
+ whatsapp: string | null;
+} | null> {
+ try {
+ const { data, error } = await supabase
+ .from('usuarios')
+ .select('instancia_zap, status_instancia, whatsapp')
+ .eq('email', userEmail.trim().toLowerCase())
+ .single();
+
+ if (error) {
+ console.error('Erro ao buscar instância WhatsApp:', error);
+ return null;
+ }
+
+ return data;
+ } catch (error) {
+ console.error('Erro ao buscar instância WhatsApp:', error);
+ return null;
+ }
+}