|
|
@@ -5,10 +5,32 @@
|
|
|
|
export function normalizeUrl(url) {
|
|
|
|
export function normalizeUrl(url) {
|
|
|
|
if (!url) return '';
|
|
|
|
if (!url) return '';
|
|
|
|
let u = url.trim().replace(/\/+$/, '');
|
|
|
|
let u = url.trim().replace(/\/+$/, '');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Se a página estiver rodando em HTTPS (ex: Netlify, Vercel ou servidor com SSL)
|
|
|
|
|
|
|
|
// e a URL apontar para o servidor WPP HTTP padrão (porta 22700), o navegador bloqueia por "Mixed Content".
|
|
|
|
|
|
|
|
// Redirecionamos automaticamente para o proxy reverso relativo /api-wpp provido pelo Netlify/Vercel/Nginx.
|
|
|
|
|
|
|
|
if (typeof window !== 'undefined' && window.location.protocol === 'https:') {
|
|
|
|
|
|
|
|
if (u.includes('c2wpp.c2sistemas.com.br:22700') || u.startsWith('/api-wpp')) {
|
|
|
|
|
|
|
|
return `${window.location.origin}/api-wpp`;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!/^https?:\/\//i.test(u)) u = 'http://' + u;
|
|
|
|
if (!/^https?:\/\//i.test(u)) u = 'http://' + u;
|
|
|
|
return u;
|
|
|
|
return u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function formatFetchError(err, baseUrl = '') {
|
|
|
|
|
|
|
|
if (!err) return 'Erro desconhecido de conexão.';
|
|
|
|
|
|
|
|
const msg = err.message || '';
|
|
|
|
|
|
|
|
if (msg.includes('Failed to fetch') || msg.includes('NetworkError') || err.name === 'TypeError') {
|
|
|
|
|
|
|
|
if (typeof window !== 'undefined' && window.location.protocol === 'https:' && !baseUrl.includes('/api-wpp')) {
|
|
|
|
|
|
|
|
return 'Bloqueio de Conteúdo Misto (Mixed Content): O site está em HTTPS, mas o servidor WPP está em HTTP. O proxy reverso /api-wpp intermediará as requisições.';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'Falha na conexão com o servidor WPP. Verifique se o servidor está online e acessível.';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function ensureQRPrefix(qrCode) {
|
|
|
|
export function ensureQRPrefix(qrCode) {
|
|
|
|
if (!qrCode) return '';
|
|
|
|
if (!qrCode) return '';
|
|
|
|
return qrCode.startsWith('data:') ? qrCode : `data:image/png;base64,${qrCode}`;
|
|
|
|
return qrCode.startsWith('data:') ? qrCode : `data:image/png;base64,${qrCode}`;
|
|
|
@@ -24,19 +46,23 @@ export function getSessionAuth(server, session) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function testServerConnection(baseUrl, secretKey) {
|
|
|
|
export async function testServerConnection(baseUrl, secretKey) {
|
|
|
|
const normUrl = normalizeUrl(baseUrl);
|
|
|
|
const normUrl = normalizeUrl(baseUrl);
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${normUrl}/api/${secretKey}/show-all-sessions`, {
|
|
|
|
const res = await fetch(`${normUrl}/api/${secretKey}/show-all-sessions`, {
|
|
|
|
headers: { 'Authorization': `Bearer ${secretKey}` },
|
|
|
|
headers: { 'Authorization': `Bearer ${secretKey}` },
|
|
|
|
signal: AbortSignal.timeout(8000),
|
|
|
|
signal: AbortSignal.timeout(10000),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (res.ok) {
|
|
|
|
if (res.ok) {
|
|
|
|
return { ok: true, message: 'Conexão OK! Servidor respondeu com sucesso.' };
|
|
|
|
return { ok: true, message: 'Conexão OK! Servidor WPPConnect respondeu com sucesso.' };
|
|
|
|
} else if (res.status === 401) {
|
|
|
|
} else if (res.status === 401) {
|
|
|
|
return { ok: false, error: 'Token incorreto. Verifique a Secret Key.' };
|
|
|
|
return { ok: false, error: 'Token incorreto. Verifique a Secret Key.' };
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
const text = await res.text().catch(() => '');
|
|
|
|
const text = await res.text().catch(() => '');
|
|
|
|
return { ok: false, error: `Erro ${res.status}: ${text || 'Resposta inesperada'}` };
|
|
|
|
return { ok: false, error: `Erro ${res.status}: ${text || 'Resposta inesperada'}` };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
return { ok: false, error: formatFetchError(err, normUrl) };
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -52,6 +78,7 @@ export async function startSession(server, sessionName, options = {}) {
|
|
|
|
if (session?.webhook) body.webhook = session.webhook;
|
|
|
|
if (session?.webhook) body.webhook = session.webhook;
|
|
|
|
if (session?.proxy) body.proxy = session.proxy;
|
|
|
|
if (session?.proxy) body.proxy = session.proxy;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(url, {
|
|
|
|
const res = await fetch(url, {
|
|
|
|
method: 'POST',
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
headers: {
|
|
|
@@ -62,11 +89,14 @@ export async function startSession(server, sessionName, options = {}) {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!res.ok) {
|
|
|
|
if (!res.ok) {
|
|
|
|
const errText = await res.text();
|
|
|
|
const errText = await res.text().catch(() => '');
|
|
|
|
throw new Error(errText || `HTTP ${res.status}`);
|
|
|
|
throw new Error(errText || `HTTP ${res.status}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return await res.json();
|
|
|
|
return await res.json();
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
throw new Error(formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -74,6 +104,7 @@ export async function startSession(server, sessionName, options = {}) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function generateToken(server, sessionName) {
|
|
|
|
export async function generateToken(server, sessionName) {
|
|
|
|
const baseUrl = normalizeUrl(server.baseUrl);
|
|
|
|
const baseUrl = normalizeUrl(server.baseUrl);
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/${server.secretKey}/generate-token`, {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/${server.secretKey}/generate-token`, {
|
|
|
|
method: 'POST',
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
headers: {
|
|
|
@@ -88,6 +119,10 @@ export async function generateToken(server, sessionName) {
|
|
|
|
return data.token || null;
|
|
|
|
return data.token || null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
console.warn('Erro ao gerar token:', formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -98,9 +133,10 @@ export async function checkSessionStatus(server, sessionName) {
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
const authToken = getSessionAuth(server, session);
|
|
|
|
const authToken = getSessionAuth(server, session);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/check-connection-session`, {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/check-connection-session`, {
|
|
|
|
headers: { 'Authorization': `Bearer ${authToken}` },
|
|
|
|
headers: { 'Authorization': `Bearer ${authToken}` },
|
|
|
|
signal: AbortSignal.timeout(6000),
|
|
|
|
signal: AbortSignal.timeout(8000),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (res.ok) {
|
|
|
|
if (res.ok) {
|
|
|
@@ -108,6 +144,10 @@ export async function checkSessionStatus(server, sessionName) {
|
|
|
|
return data.status || 'unknown';
|
|
|
|
return data.status || 'unknown';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 'error';
|
|
|
|
return 'error';
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
console.warn('Erro ao verificar status:', formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
return 'error';
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -118,9 +158,10 @@ export async function fetchQRCode(server, sessionName) {
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
const authToken = getSessionAuth(server, session);
|
|
|
|
const authToken = getSessionAuth(server, session);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
const qrRes = await fetch(`${baseUrl}/api/${sessionName}/qrcode-session`, {
|
|
|
|
const qrRes = await fetch(`${baseUrl}/api/${sessionName}/qrcode-session`, {
|
|
|
|
headers: { 'Authorization': `Bearer ${authToken}` },
|
|
|
|
headers: { 'Authorization': `Bearer ${authToken}` },
|
|
|
|
signal: AbortSignal.timeout(10000),
|
|
|
|
signal: AbortSignal.timeout(12000),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!qrRes.ok) return null;
|
|
|
|
if (!qrRes.ok) return null;
|
|
|
@@ -137,6 +178,10 @@ export async function fetchQRCode(server, sessionName) {
|
|
|
|
return `data:${ct};base64,${btoa(binary)}`;
|
|
|
|
return `data:${ct};base64,${btoa(binary)}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
console.warn('Erro ao buscar QR code:', formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -147,6 +192,7 @@ export async function closeSession(server, sessionName) {
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
let authToken = getSessionAuth(server, session);
|
|
|
|
let authToken = getSessionAuth(server, session);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/close-session`, {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/close-session`, {
|
|
|
|
method: 'POST',
|
|
|
|
method: 'POST',
|
|
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${authToken}` },
|
|
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${authToken}` },
|
|
|
@@ -158,6 +204,9 @@ export async function closeSession(server, sessionName) {
|
|
|
|
throw new Error(errBody || `HTTP ${res.status}`);
|
|
|
|
throw new Error(errBody || `HTTP ${res.status}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
throw new Error(formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -168,6 +217,7 @@ export async function logoutSession(server, sessionName) {
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
const session = server.sessions?.find(s => s.name === sessionName);
|
|
|
|
let authToken = getSessionAuth(server, session);
|
|
|
|
let authToken = getSessionAuth(server, session);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/logout-session`, {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/logout-session`, {
|
|
|
|
method: 'POST',
|
|
|
|
method: 'POST',
|
|
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${authToken}` },
|
|
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${authToken}` },
|
|
|
@@ -179,6 +229,9 @@ export async function logoutSession(server, sessionName) {
|
|
|
|
throw new Error(errBody || `HTTP ${res.status}`);
|
|
|
|
throw new Error(errBody || `HTTP ${res.status}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
throw new Error(formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -186,6 +239,7 @@ export async function logoutSession(server, sessionName) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function clearSessionData(server, sessionName) {
|
|
|
|
export async function clearSessionData(server, sessionName) {
|
|
|
|
const baseUrl = normalizeUrl(server.baseUrl);
|
|
|
|
const baseUrl = normalizeUrl(server.baseUrl);
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/${server.secretKey}/clear-session-data`, {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${sessionName}/${server.secretKey}/clear-session-data`, {
|
|
|
|
method: 'POST',
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
headers: {
|
|
|
@@ -199,6 +253,9 @@ export async function clearSessionData(server, sessionName) {
|
|
|
|
throw new Error(errBody || `HTTP ${res.status}`);
|
|
|
|
throw new Error(errBody || `HTTP ${res.status}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
throw new Error(formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@@ -206,12 +263,16 @@ export async function clearSessionData(server, sessionName) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function listAllServerSessions(server) {
|
|
|
|
export async function listAllServerSessions(server) {
|
|
|
|
const baseUrl = normalizeUrl(server.baseUrl);
|
|
|
|
const baseUrl = normalizeUrl(server.baseUrl);
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${server.secretKey}/show-all-sessions`, {
|
|
|
|
const res = await fetch(`${baseUrl}/api/${server.secretKey}/show-all-sessions`, {
|
|
|
|
headers: { 'Authorization': `Bearer ${server.secretKey}` },
|
|
|
|
headers: { 'Authorization': `Bearer ${server.secretKey}` },
|
|
|
|
signal: AbortSignal.timeout(10000),
|
|
|
|
signal: AbortSignal.timeout(12000),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
|
|
const data = await res.json();
|
|
|
|
const data = await res.json();
|
|
|
|
return data.response || [];
|
|
|
|
return data.response || [];
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
throw new Error(formatFetchError(err, baseUrl));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|