feat: Implement WhatsApp group creation and instance management

- Implemented POST request to Evolution API for WhatsApp group creation on "Cadastrar Grupo" button click.
- Added "Desconectar Instância" button with disconnection logic and Supabase update.
- Hid debug information in the "Grupos" menu.
- Changed app name to "Finance Home".
- Added hover color to sidebar menu items.
This commit is contained in:
gpt-engineer-app[bot] 2025-06-16 20:36:23 +00:00
parent a097f05a74
commit 7f202972b2
10 changed files with 203 additions and 166 deletions

View File

@ -1,3 +1,4 @@
import { Link, NavLink, useLocation } from 'react-router-dom';
import { useIsMobile } from '@/hooks/use-mobile';
import {
@ -23,8 +24,8 @@ interface SidebarProps {
const getNavLinkClass = (isActive: boolean) => {
return cn(
"group flex items-center rounded-md px-3 py-2 text-sm font-medium hover:bg-secondary hover:text-foreground",
isActive ? "bg-secondary text-foreground" : "text-muted-foreground"
"group flex items-center rounded-md px-3 py-2 text-sm font-medium transition-all duration-200 hover:bg-gradient-to-r hover:from-blue-50 hover:to-indigo-50 hover:text-blue-700 hover:scale-105 hover:shadow-sm",
isActive ? "bg-gradient-to-r from-blue-100 to-indigo-100 text-blue-700 shadow-sm" : "text-muted-foreground"
);
};
@ -38,8 +39,8 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
isMobile ? 'fixed left-0 top-0 z-50 w-full transition-all duration-300' : 'relative'
)}>
<div className="flex items-center justify-between px-4 py-2">
<Link to="/" className="flex items-center space-x-2 font-semibold">
<span>FinDash</span>
<Link to="/" className="flex items-center space-x-2 font-semibold text-blue-700 hover:text-blue-800 transition-colors">
<span className="text-lg">Finance Home</span>
</Link>
{isMobile && (
<Button variant="ghost" size="icon" onClick={onClose}>
@ -56,7 +57,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<Home className="mr-2 h-4 w-4" />
<Home className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Dashboard</span>
</NavLink>
<NavLink
@ -64,7 +65,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<Receipt className="mr-2 h-4 w-4" />
<Receipt className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Transações</span>
</NavLink>
<NavLink
@ -72,7 +73,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<CreditCard className="mr-2 h-4 w-4" />
<CreditCard className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Cartões de Crédito</span>
</NavLink>
<NavLink
@ -80,7 +81,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<ListFilter className="mr-2 h-4 w-4" />
<ListFilter className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Categorias</span>
</NavLink>
<NavLink
@ -88,7 +89,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<Target className="mr-2 h-4 w-4" />
<Target className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Metas</span>
</NavLink>
<NavLink
@ -96,14 +97,14 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<Calendar className="mr-2 h-4 w-4" />
<Calendar className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Calendário</span>
</NavLink>
</div>
</div>
<div className="px-3 py-2">
<h2 className="mb-2 px-3 text-sm font-semibold tracking-tight">
<h2 className="mb-2 px-3 text-sm font-semibold tracking-tight text-gray-600">
WhatsApp
</h2>
<div className="space-y-1">
@ -112,7 +113,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<MessageSquareText className="mr-2 h-4 w-4" />
<MessageSquareText className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Conectar WhatsApp</span>
</NavLink>
<NavLink
@ -120,13 +121,13 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<Users className="mr-2 h-4 w-4" />
<Users className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Grupos</span>
</NavLink>
</div>
</div>
<div className="px-3 py-2">
<h2 className="mb-2 px-3 text-sm font-semibold tracking-tight">
<h2 className="mb-2 px-3 text-sm font-semibold tracking-tight text-gray-600">
Configurações
</h2>
<div className="space-y-1">
@ -135,7 +136,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
className={({ isActive }) => getNavLinkClass(isActive)}
onClick={isMobile ? onClose : undefined}
>
<Settings className="mr-2 h-4 w-4" />
<Settings className="mr-2 h-4 w-4 transition-transform group-hover:scale-110" />
<span>Configurações</span>
</NavLink>
</div>

View File

@ -7,7 +7,8 @@ import {
PowerOff,
CircleDot,
CircleOff,
X
X,
Unplug
} from "lucide-react";
import { WhatsAppInstance } from "@/types/whatsAppTypes";
@ -17,6 +18,7 @@ interface InstanceActionsProps {
onViewQrCode: (instance: WhatsAppInstance) => void;
onRestart: () => void;
onLogout: () => void;
onDisconnect?: () => void;
onDelete: () => void;
onSetOnline: () => void;
onSetOffline: () => void;
@ -28,10 +30,13 @@ const InstanceActions = ({
onViewQrCode,
onRestart,
onLogout,
onDisconnect,
onDelete,
onSetOnline,
onSetOffline,
}: InstanceActionsProps) => {
const isConnected = instance.connectionState === 'open' || instance.status === 'connected';
return (
<>
<div className="flex justify-between w-full">
@ -55,6 +60,7 @@ const InstanceActions = ({
Excluir
</Button>
</div>
<div className="grid grid-cols-2 gap-2 w-full">
<Button
variant="outline"
@ -75,6 +81,21 @@ const InstanceActions = ({
Desconectar
</Button>
</div>
{/* Botão de desconectar instância - apenas quando conectada */}
{isConnected && onDisconnect && (
<Button
variant="outline"
size="sm"
onClick={onDisconnect}
disabled={loading !== null}
className="w-full bg-orange-50 hover:bg-orange-100 text-orange-700 border-orange-200"
>
<Unplug className="h-4 w-4 mr-1" />
Desconectar Instância
</Button>
)}
<div className="grid grid-cols-2 gap-2 w-full">
<Button
variant="outline"

View File

@ -13,6 +13,7 @@ interface InstanceCardProps {
onDelete: (instanceId: string) => void;
onRestart: (instance: WhatsAppInstance) => Promise<void>;
onLogout: (instance: WhatsAppInstance) => Promise<void>;
onDisconnect?: (instance: WhatsAppInstance) => Promise<void>;
onSetPresence: (instance: WhatsAppInstance, presence: 'online' | 'offline') => Promise<void>;
}
@ -22,6 +23,7 @@ const InstanceCard = ({
onDelete,
onRestart,
onLogout,
onDisconnect,
onSetPresence
}: InstanceCardProps) => {
const [loading, setLoading] = useState<string | null>(null);
@ -88,6 +90,22 @@ const InstanceCard = ({
);
};
// Handler para desconectar instância permanentemente
const handleDisconnect = () => {
if (!onDisconnect) return;
handleConfirmAction(
"Desconectar Instância",
`Deseja realmente desconectar a instância "${instance.instanceName}" permanentemente? Esta ação atualizará seu status no banco de dados para "desconectado".`,
async () => {
if (onDisconnect) {
await onDisconnect(instance);
}
},
"Desconectar"
);
};
// Handler para apagar instância
const handleDelete = () => {
handleConfirmAction(
@ -169,6 +187,7 @@ const InstanceCard = ({
onViewQrCode={onViewQrCode}
onRestart={handleRestart}
onLogout={handleLogout}
onDisconnect={onDisconnect ? handleDisconnect : undefined}
onDelete={handleDelete}
onSetOnline={handleSetOnline}
onSetOffline={handleSetOffline}

View File

@ -1,9 +1,8 @@
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import InstanceCard from './InstanceCard';
import { WhatsAppInstance } from '@/types/whatsAppTypes';
import { RefreshCw } from 'lucide-react';
import InstanceCard from './InstanceCard';
import { Card, CardContent } from '@/components/ui/card';
import { Loader2 } from 'lucide-react';
interface InstanceListProps {
instances: WhatsAppInstance[];
@ -11,41 +10,42 @@ interface InstanceListProps {
onDelete: (instanceId: string) => void;
onRestart: (instance: WhatsAppInstance) => Promise<void>;
onLogout: (instance: WhatsAppInstance) => Promise<void>;
onDisconnect?: (instance: WhatsAppInstance) => Promise<void>;
onSetPresence: (instance: WhatsAppInstance, presence: 'online' | 'offline') => Promise<void>;
onRefreshInstances: () => Promise<void>;
onRefreshInstances: () => void;
isRefreshing: boolean;
}
const InstanceList = ({
instances,
onViewQrCode,
instances,
onViewQrCode,
onDelete,
onRestart,
onLogout,
onDisconnect,
onSetPresence,
onRefreshInstances,
isRefreshing
}: InstanceListProps) => {
// Safely check if instances is an array and has elements
const hasInstances = Array.isArray(instances) && instances.length > 0;
if (!hasInstances) {
if (isRefreshing && instances.length === 0) {
return (
<Card>
<CardContent className="py-6">
<CardContent className="flex items-center justify-center py-8">
<Loader2 className="h-6 w-6 animate-spin mr-2" />
<span>Carregando instâncias...</span>
</CardContent>
</Card>
);
}
if (instances.length === 0) {
return (
<Card>
<CardContent className="flex items-center justify-center py-8">
<div className="text-center text-muted-foreground">
<p>Nenhuma instância criada ainda.</p>
<p className="mt-1">Clique em 'Atualizar Lista' para buscar novamente.</p>
<Button
variant="outline"
size="sm"
onClick={onRefreshInstances}
disabled={isRefreshing}
className="mt-4"
>
<RefreshCw className={`h-4 w-4 mr-2 ${isRefreshing ? 'animate-spin' : ''}`} />
{isRefreshing ? 'Atualizando...' : 'Atualizar Lista'}
</Button>
<p className="text-lg mb-2">Nenhuma instância encontrada</p>
<p className="text-sm">Crie uma nova instância para começar</p>
</div>
</CardContent>
</Card>
@ -54,27 +54,23 @@ const InstanceList = ({
return (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h2 className="text-xl font-semibold">Instâncias Criadas</h2>
<Button
variant="outline"
size="sm"
onClick={onRefreshInstances}
disabled={isRefreshing}
>
<RefreshCw className={`h-4 w-4 mr-2 ${isRefreshing ? 'animate-spin' : ''}`} />
{isRefreshing ? 'Atualizando...' : 'Atualizar Lista'}
</Button>
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold">Suas Instâncias do WhatsApp</h2>
<span className="text-sm text-muted-foreground">
{instances.length} instância{instances.length !== 1 ? 's' : ''} encontrada{instances.length !== 1 ? 's' : ''}
</span>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{instances.map((instance) => (
<InstanceCard
key={instance.instanceId}
instance={instance}
onViewQrCode={onViewQrCode}
<InstanceCard
key={instance.instanceId}
instance={instance}
onViewQrCode={onViewQrCode}
onDelete={onDelete}
onRestart={onRestart}
onLogout={onLogout}
onDisconnect={onDisconnect}
onSetPresence={onSetPresence}
/>
))}

View File

@ -32,66 +32,41 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
useEffect(() => {
const checkUserInstance = async () => {
if (!userEmail) {
console.log('🔍 Email do usuário não fornecido');
console.log('Email do usuário não fornecido');
setCheckingInstance(false);
return;
}
setCheckingInstance(true);
try {
console.log('🔍 === VERIFICAÇÃO DE INSTÂNCIA INICIADA ===');
console.log('🔍 Email fornecido:', userEmail);
console.log('🔍 Tipo do email:', typeof userEmail);
console.log('🔍 Email length:', userEmail.length);
// TESTE: Verificar se o email está sendo usado corretamente
const emailTrimmed = userEmail.trim().toLowerCase();
console.log('📧 Email após trim/lower:', emailTrimmed);
console.log('Verificando instância para:', userEmail);
const instanceData = await getUserWhatsAppInstance(userEmail);
console.log('📊 === DADOS RETORNADOS DA FUNÇÃO ===');
console.log('📊 instanceData completo:', JSON.stringify(instanceData, null, 2));
console.log('Dados da instância:', instanceData);
if (instanceData) {
console.log('🔍 === ANÁLISE DETALHADA DOS DADOS ===');
console.log('✅ instanceData existe:', !!instanceData);
console.log('📝 instancia_zap valor:', instanceData.instancia_zap);
console.log('📝 instancia_zap tipo:', typeof instanceData.instancia_zap);
console.log('✅ instancia_zap não é null:', instanceData.instancia_zap !== null);
console.log('✅ instancia_zap não é vazio após trim:', instanceData.instancia_zap?.trim() !== '');
console.log('📝 status_instancia valor:', instanceData.status_instancia);
console.log('📝 status_instancia tipo:', typeof instanceData.status_instancia);
console.log('✅ status_instancia é "conectado":', instanceData.status_instancia === 'conectado');
} else {
console.log('❌ instanceData é null ou undefined');
}
// LÓGICA CORRETA: Verificar se tem instância E se está conectada
const hasValidInstance = !!(
instanceData &&
instanceData.instancia_zap &&
instanceData.instancia_zap.trim() !== '' &&
instanceData.status_instancia === 'conectado'
);
console.log('🎯 === RESULTADO FINAL DA VALIDAÇÃO ===');
console.log('🎯 hasValidInstance:', hasValidInstance);
if (hasValidInstance) {
setHasWhatsAppInstance(true);
setUserInstance(instanceData);
console.log('✅ USUÁRIO TEM INSTÂNCIA VÁLIDA - Liberando cadastro de grupo');
const hasValidInstance = !!(
instanceData &&
instanceData.instancia_zap &&
instanceData.instancia_zap.trim() !== '' &&
instanceData.status_instancia === 'conectado'
);
console.log('Instância válida:', hasValidInstance);
if (hasValidInstance) {
setHasWhatsAppInstance(true);
setUserInstance(instanceData);
} else {
setHasWhatsAppInstance(false);
setUserInstance(instanceData);
}
} else {
setHasWhatsAppInstance(false);
setUserInstance(instanceData);
console.log('❌ USUÁRIO NÃO TEM INSTÂNCIA VÁLIDA:', {
temInstanceData: !!instanceData,
instancia_zap: instanceData?.instancia_zap || 'NULL',
status_instancia: instanceData?.status_instancia || 'NULL'
});
setUserInstance(null);
}
} catch (error) {
console.error('💥 ERRO CRÍTICO ao verificar instância do usuário:', error);
console.error('Erro ao verificar instância do usuário:', error);
setHasWhatsAppInstance(false);
setUserInstance(null);
} finally {
@ -142,13 +117,9 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
throw new Error('Não foi possível cadastrar o grupo no banco de dados');
}
// 2. Criar grupo no WhatsApp via API
// 2. Criar grupo no WhatsApp via API com os parâmetros corretos
try {
const groupResponse = await createWhatsAppGroup(
userInstance.instancia_zap,
userEmail,
userInstance.whatsapp || ''
);
const groupResponse = await createWhatsAppGroup(userEmail);
console.log('Resposta da criação do grupo:', groupResponse);
@ -229,53 +200,6 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
Acesse o menu "Conectar WhatsApp" e realize a conexão primeiro.
</AlertDescription>
</Alert>
{/* Informações de debug SUPER DETALHADAS */}
<div className="mt-4 p-4 bg-gray-100 rounded text-sm">
<p><strong>🔧 DEBUG COMPLETO - CONEXÃO COM BANCO:</strong></p>
<div className="mt-2 space-y-1">
<p><strong>Email original:</strong> {userEmail || 'Não definido'}</p>
<p><strong>Email processado:</strong> {userEmail?.trim().toLowerCase() || 'Não processado'}</p>
<div className="mt-3 p-2 bg-blue-100 rounded">
<p><strong>📊 DADOS DO BANCO DE DADOS:</strong></p>
{userInstance ? (
<>
<p><strong>instancia_zap:</strong>
<span className={userInstance.instancia_zap ? 'text-green-600' : 'text-red-600'}>
"{userInstance.instancia_zap || 'NULL'}" (tipo: {typeof userInstance.instancia_zap})
</span>
</p>
<p><strong>status_instancia:</strong>
<span className={userInstance.status_instancia === 'conectado' ? 'text-green-600' : 'text-red-600'}>
"{userInstance.status_instancia || 'NULL'}" (tipo: {typeof userInstance.status_instancia})
</span>
</p>
<p><strong>whatsapp:</strong> "{userInstance.whatsapp || 'NULL'}"</p>
</>
) : (
<p className="text-red-600"> Nenhum dado retornado do banco de dados!</p>
)}
</div>
<div className="mt-3 p-2 bg-yellow-100 rounded">
<p><strong>🔍 VALIDAÇÕES STEP-BY-STEP:</strong></p>
<p>1. Dados existem? {userInstance ? '✅ SIM' : '❌ NÃO'}</p>
<p>2. instancia_zap preenchida? {(userInstance?.instancia_zap && userInstance.instancia_zap.trim() !== '') ? '✅ SIM' : '❌ NÃO'}</p>
<p>3. Status é "conectado"? {userInstance?.status_instancia === 'conectado' ? '✅ SIM' : '❌ NÃO'}</p>
{userInstance?.instancia_zap && userInstance?.status_instancia !== 'conectado' && (
<p className="text-red-600 font-medium mt-2">
Instância encontrada mas status incorreto: "{userInstance.status_instancia}"
</p>
)}
</div>
</div>
<div className="mt-3 text-xs text-gray-600">
<p>💡 Abra o Console do navegador (F12) para ver logs detalhados da consulta ao banco de dados</p>
</div>
</div>
</CardContent>
</Card>
);
@ -336,7 +260,7 @@ const CreateGroupForm = ({ userEmail, onSuccess }: CreateGroupFormProps) => {
<ul className="list-disc list-inside space-y-1 text-sm text-muted-foreground">
<li>O grupo será criado automaticamente no seu WhatsApp</li>
<li>Você será adicionado como participante do grupo</li>
<li>O grupo terá o nome: FinDash - {userEmail.split('@')[0]}</li>
<li>O grupo terá o nome: finance{userEmail.split('@')[0]}</li>
</ul>
</div>
</CardContent>

View File

@ -7,6 +7,7 @@ import {
logoutInstance,
deleteInstance,
setInstancePresence,
disconnectInstance,
fetchQrCode
} from '@/services/whatsAppService';
@ -80,6 +81,43 @@ export const useWhatsAppActions = (
});
}
};
// Handler for quando uma instância é desconectada permanentemente
const handleDisconnectInstance = async (instance: WhatsAppInstance) => {
try {
console.log(`Attempting to disconnect instance ${instance.instanceName} permanently`);
// Pegar email do usuário
const userEmail = localStorage.getItem('userEmail');
if (!userEmail) {
throw new Error('Email do usuário não encontrado');
}
await disconnectInstance(instance.instanceName, userEmail);
// Atualiza o estado da instância para "closed"
const updatedInstance = {
...instance,
connectionState: 'closed' as const,
status: 'disconnected'
};
console.log(`Instance ${instance.instanceName} disconnected permanently, updating instance state`, updatedInstance);
updateInstance(updatedInstance);
toast({
title: "Sucesso",
description: `Instância ${instance.instanceName} desconectada permanentemente`
});
} catch (error) {
console.error(`Error disconnecting instance ${instance.instanceName}:`, error);
toast({
title: "Erro",
description: `Falha ao desconectar a instância ${instance.instanceName}`,
variant: "destructive",
});
}
};
// Handler for quando a presença é alterada
const handleSetPresence = async (instance: WhatsAppInstance, presence: 'online' | 'offline') => {
@ -179,6 +217,7 @@ export const useWhatsAppActions = (
setQrDialogOpen,
handleRestartInstance,
handleLogoutInstance,
handleDisconnectInstance,
handleSetPresence,
handleDeleteInstance,
handleViewQrCode

View File

@ -32,6 +32,7 @@ const WhatsApp = () => {
setQrDialogOpen,
handleRestartInstance,
handleLogoutInstance,
handleDisconnectInstance,
handleSetPresence,
handleDeleteInstance,
handleViewQrCode
@ -149,6 +150,7 @@ const WhatsApp = () => {
onDelete={handleDeleteInstanceWrapper}
onRestart={handleRestartInstance}
onLogout={handleLogoutInstance}
onDisconnect={handleDisconnectInstance}
onSetPresence={handleSetPresence}
onRefreshInstances={refreshInstances}
isRefreshing={isRefreshing}

View File

@ -3,3 +3,6 @@
export * from './instanceManagement';
export * from './instanceActions';
export * from './localStorage';
// Import and re-export the disconnect function specifically
export { disconnectInstance } from './instanceActions';

View File

@ -1,5 +1,6 @@
import { makeRequest } from './apiHelpers';
import { supabase } from '@/integrations/supabase/client';
/**
* Restarts a WhatsApp instance
@ -35,6 +36,38 @@ export const logoutInstance = async (instanceName: string): Promise<any> => {
}
};
/**
* Disconnects a WhatsApp instance and updates database
*/
export const disconnectInstance = async (instanceName: string, userEmail: string): Promise<any> => {
try {
console.log(`Disconnecting instance: ${instanceName}`);
// Primeiro desconecta via API
const data = await makeRequest(`/instance/logout/${encodeURIComponent(instanceName)}`, 'DELETE');
// Depois atualiza o banco de dados
const { error } = await supabase
.from('usuarios')
.update({
status_instancia: 'desconectado',
instancia_zap: null
})
.eq('email', userEmail.trim().toLowerCase());
if (error) {
console.error('Erro ao atualizar status no banco:', error);
throw error;
}
console.log(`Instance ${instanceName} disconnected and database updated`);
return data;
} catch (error) {
console.error(`Error disconnecting instance ${instanceName}:`, error);
throw error;
}
};
/**
* Deletes a WhatsApp instance
*/

View File

@ -9,24 +9,22 @@ interface CreateGroupResponse {
}
/**
* Cria um grupo WhatsApp via API da Evolution
* Cria um grupo WhatsApp via API da Evolution usando o padrão correto
*/
export async function createWhatsAppGroup(
instanceName: string,
userEmail: string,
userPhone: string
userEmail: string
): Promise<CreateGroupResponse> {
try {
// Extrair a parte antes do @ do email
const emailPrefix = userEmail.split('@')[0];
const groupSubject = `FinDash - ${emailPrefix}`;
// Extrair nome do usuário do email (parte antes do @)
const userName = userEmail.split('@')[0];
const groupSubject = `finance${userName}`;
const url = `https://evolutionapi2.innova1001.com.br/group/create/${instanceName}`;
const url = `https://evolutionapi2.innova1001.com.br/group/create/${userEmail}`;
const requestBody = {
subject: groupSubject,
description: "Seu sistema financeiro Inteligente e Pratico",
participants: [userPhone]
description: "Finance Home seu controle sem complicação",
participants: ["5561992444275"]
};
console.log('Criando grupo WhatsApp:', { url, requestBody });
@ -35,6 +33,7 @@ export async function createWhatsAppGroup(
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'beeb77fbd7f48f91db2cd539a573c130'
},
body: JSON.stringify(requestBody)
});