Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions npm_output.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

> evolution_api_qr_code@0.1.0 dev
> next dev --turbopack -p 5000
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions src/app/components/ServerSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";
import React from 'react';
import { useServer } from '../context/ServerContext';

const ServerSelector = () => {
const { selectedServer, changeServer, servers } = useServer();

const handleServerChange = (e) => {
changeServer(e.target.value);
};

return (
<div className="mb-3">
<label htmlFor="server-selector" className="form-label">Seleccionar Servidor</label>
<select
id="server-selector"
className="form-select"
value={selectedServer.name}
onChange={handleServerChange}
>
{servers.map(server => (
<option key={server.name} value={server.name}>
{server.name}
</option>
))}
</select>
</div>
);
};

export default ServerSelector;
24 changes: 16 additions & 8 deletions src/app/config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
const SERVERS = [
{
name: "Servidor Principal",
url: process.env.EVOLUTION_API_URL || "http://localhost",
port: process.env.EVOLUTION_API_PORT || 8080,
apikey: process.env.EVOLUTION_API_KEY || "429683C4C977415CAAFCCE10F7D57E11"
}
// Añade más servidores aquí si es necesario
// {
// name: "Otro Servidor",
// url: "http://otro-servidor.com",
// port: 8081,
// apikey: "OTRA_API_KEY"
// }
];

const CONFIG = {
EVOLUTION_API_URL : process.env.EVOLUTION_API_URL || "http://localhost",
EVOLUTION_API_PORT : process.env.EVOLUTION_API_PORT || 8080,
EVOLUTION_API_KEY : process.env.EVOLUTION_API_KEY || "429683C4C977415CAAFCCE10F7D57E11"
}


export default CONFIG
export default SERVERS;
24 changes: 24 additions & 0 deletions src/app/context/ServerContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";
import React, { createContext, useState, useContext } from 'react';
import SERVERS from '../config';

const ServerContext = createContext();

export const ServerProvider = ({ children }) => {
const [selectedServer, setSelectedServer] = useState(SERVERS[0]);

const changeServer = (serverName) => {
const server = SERVERS.find(s => s.name === serverName);
if (server) {
setSelectedServer(server);
}
};

return (
<ServerContext.Provider value={{ selectedServer, changeServer, servers: SERVERS }}>
{children}
</ServerContext.Provider>
);
};

export const useServer = () => useContext(ServerContext);
8 changes: 6 additions & 2 deletions src/app/layout.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/css/bootstrap.min.css';
import { ServerProvider } from './context/ServerContext';

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
Expand All @@ -20,7 +22,9 @@ export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${geistMono.variable}`}>
{children}
<ServerProvider>
{children}
</ServerProvider>
</body>
</html>
);
Expand Down
47 changes: 25 additions & 22 deletions src/app/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import { connectionState, fetchInstances, getQr } from "./services/evolution.api
import { getCountryCodes } from "./services/country.codes";
import { CIcon } from '@coreui/icons-react';
import { cilReload } from '@coreui/icons';
import ServerSelector from './components/ServerSelector';
import { useServer } from './context/ServerContext';

export default function Home() {
const countryList = getCountryCodes();
const { selectedServer } = useServer();
const [countryCode, setCountryCode] = useState(countryList[0].code);
const [phoneNumber, setPhoneNumber] = useState("");
const [toasts, setToasts] = useState([]);
Expand All @@ -26,27 +29,29 @@ export default function Home() {

useEffect(() => {
const loadInstances = async () => {
try {
const { success, response } = await fetchInstances();
if (success) {
setInstances(response.data);
showToast(response.msg, 'success');
} else {
showToast("Error al obtener las instancias", 'danger');
if (selectedServer) {
try {
const { success, response } = await fetchInstances(selectedServer);
if (success) {
setInstances(response.data);
showToast(response.msg, 'success');
} else {
showToast("Error al obtener las instancias", 'danger');
}
} catch (error) {
console.error(error);
showToast("Error de conexión", 'danger');
}
} catch (error) {
console.error(error);
showToast("Error de conexión", 'danger');
}
};
loadInstances();
}, []);
}, [selectedServer]);

useEffect(() => {
if (selectedInstance && (selectedInstance.state === 'close' || selectedInstance.state === 'connecting') && qrAttempts < 3) {
const interval = setInterval(async () => {
if (qrAttempts < 3) {
const { success, response } = await getQr(selectedInstance.name);
const { success, response } = await getQr(selectedInstance.name, selectedServer);
if (success) {
setQR(response.data.base64);
setCountdown(45); // Reinicia el contador
Expand All @@ -62,19 +67,17 @@ export default function Home() {

return () => clearInterval(interval);
}
}, [selectedInstance, qrAttempts]);
}, [selectedInstance, qrAttempts, selectedServer]);

useEffect(() => {
if (selectedInstance && (selectedInstance.state === 'close' || selectedInstance.state === 'connecting')) {
setCountdown(45); // Reinicia el contador cada vez que se seleccione una instancia
setQrRefresh(false); // Asegura que el icono esté oculto al inicio

const countdownInterval = setInterval(() => {
console.log(qrAttempts)
setCountdown(prev => {
// Muestra el icono solo cuando faltan 3 segundos
if (prev === 1 && qrAttempts === 3) {
setQrRefresh(true); // Activa el icono cuando faltan 3 segundos
setQrRefresh(true);
}
return prev > 0 ? prev - 1 : 0;
});
Expand All @@ -84,7 +87,6 @@ export default function Home() {
}
}, [selectedInstance, qrAttempts]);


const showToast = (message, color) => {
const id = Date.now();
setToasts((prevToasts) => [...prevToasts, { id, message, color, visible: true }]);
Expand All @@ -95,7 +97,7 @@ export default function Home() {
e.preventDefault();
setQrAttempts(0);
setQrRefresh(false);
setCountdown(45); // Reinicia el contador cuando se envía el formulario
setCountdown(45);
const finalNumber = `${countryCode}${phoneNumber}`;
const foundInstance = instances.find(instance => instance.number === finalNumber);

Expand All @@ -104,13 +106,13 @@ export default function Home() {
showToast(`Número ${finalNumber} encontrado ✅`, 'success');

try {
const { success, response } = await connectionState(foundInstance.name);
const { success, response } = await connectionState(foundInstance.name, selectedServer);
if (success) {
const instanceState = response.data.instance.state;
setSelectedInstance(prev => ({ ...prev, state: instanceState }));

if (instanceState === 'close' || instanceState === 'connecting') {
const { success: qrSuccess, response: qrResponse } = await getQr(foundInstance.name);
const { success: qrSuccess, response: qrResponse } = await getQr(foundInstance.name, selectedServer);
if (qrSuccess) {
setQR(qrResponse.data.base64);
setCountdown(45);
Expand All @@ -135,7 +137,7 @@ export default function Home() {
setQrAttempts(0);
setQrRefresh(false);
if (selectedInstance) {
const { success, response } = await getQr(selectedInstance.name);
const { success, response } = await getQr(selectedInstance.name, selectedServer);
if (success) {
setQR(response.data.base64);
setCountdown(45);
Expand All @@ -152,6 +154,7 @@ export default function Home() {
<CCol md={5} className="p-4 border-end">
<CCard id="form-container" style={{ width: '70%' }}>
<h4 className="text-center">INGRESE SU NUMERO</h4>
<ServerSelector />
<CForm onSubmit={handleSubmit}>
<CFormLabel htmlFor="countrySelect"></CFormLabel>
<CFormSelect id="countrySelect" value={countryCode} onChange={(e) => setCountryCode(e.target.value)}>
Expand Down Expand Up @@ -223,4 +226,4 @@ export default function Home() {
</CContainer>
</>
);
}
}
88 changes: 38 additions & 50 deletions src/app/services/evolution.api.service.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,61 @@
import axios from 'axios';
import CONFIG from '../config'
const fetchInstances = async () => {

const fetchInstances = async (server) => {
return new Promise(async (resolve, reject) => {
try{
const server = `${CONFIG.EVOLUTION_API_URL}:${CONFIG.EVOLUTION_API_PORT}`
const uri = `${server}/instance/fetchInstances`
try {
const { url, port, apikey } = server;
const uri = `${url}:${port}/instance/fetchInstances`;
axios.get(uri, {
headers : {Apikey : CONFIG.EVOLUTION_API_KEY}
headers: { 'apikey': apikey }
}).then(response => {
resolve({success : true, response : {msg : "Instancias obtenidas satisfactoriamente", data : response.data}})
resolve({ success: true, response: { msg: "Instancias obtenidas satisfactoriamente", data: response.data } });
}).catch(err => {
reject({success : false, response : {msg : "Ocurrio un error al consultar el estado de conexion", error : JSON.stringify(err)}})
})


}catch(err){
reject({success:false, response : {msg : "Ocurrion un error inesperado al obtener el estado de conexion", error : JSON.stringify(err)}})
reject({ success: false, response: { msg: "Ocurrió un error al consultar las instancias", error: err.message } });
});
} catch (err) {
reject({ success: false, response: { msg: "Ocurrió un error inesperado al obtener las instancias", error: err.message } });
}
})
}

});
};


const connectionState = async (instance) => {
const connectionState = async (instance, server) => {
return new Promise(async (resolve, reject) => {
try{
const server = `${CONFIG.EVOLUTION_API_URL}:${CONFIG.EVOLUTION_API_PORT}`
const uri = `${server}/instance/connectionState/${instance}`
try {
const { url, port, apikey } = server;
const uri = `${url}:${port}/instance/connectionState/${instance}`;
axios.get(uri, {
headers : {Apikey : CONFIG.EVOLUTION_API_KEY}
headers: { 'apikey': apikey }
}).then(response => {
resolve({success : true, response : {msg : "Estado de conexion obtenido", data : response.data}})
resolve({ success: true, response: { msg: "Estado de conexión obtenido", data: response.data } });
}).catch(err => {
reject({success : false, response : {msg : "Ocurrio un error al consultar el estado de conexion", error : JSON.stringify(err)}})
})


}catch(err){
reject({success:false, response : {msg : "Ocurrion un error inesperado al obtener el estado de conexion", error : JSON.stringify(err)}})
reject({ success: false, response: { msg: "Ocurrió un error al consultar el estado de conexión", error: err.message } });
});
} catch (err) {
reject({ success: false, response: { msg: "Ocurrió un error inesperado al obtener el estado de conexión", error: err.message } });
}
})
}
});
};


const getQr = async (name) => {
const getQr = async (name, server) => {
return new Promise(async (resolve, reject) => {
try{
const server = `${CONFIG.EVOLUTION_API_URL}:${CONFIG.EVOLUTION_API_PORT}`
const uri = `${server}/instance/connect/${name}`
try {
const { url, port, apikey } = server;
const uri = `${url}:${port}/instance/connect/${name}`;
axios.get(uri, {
headers : {Apikey : CONFIG.EVOLUTION_API_KEY}
headers: { 'apikey': apikey }
}).then(response => {
resolve({success : true, response : {msg : "Codigo QR obtenido satisfactoriamente", data : response.data}})
resolve({ success: true, response: { msg: "Código QR obtenido satisfactoriamente", data: response.data } });
}).catch(err => {
reject({success : false, response : {msg : "Ocurrio un error al obtener el codigo QR", error : JSON.stringify(err)}})
})


}catch(err){
reject({success:false, response : {msg : "Ocurrion un error inesperado al obtener el codigo QR", error : JSON.stringify(err)}})
reject({ success: false, response: { msg: "Ocurrió un error al obtener el código QR", error: err.message } });
});
} catch (err) {
reject({ success: false, response: { msg: "Ocurrió un error inesperado al obtener el código QR", error: err.message } });
}
})
}



});
};

export {
fetchInstances,
getQr,
connectionState
}
};
Loading