Skip to content
Open
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 .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ MAX_RETRIES=-1
# Maximun time to connect to whatsapp
RECONNECT_INTERVAL=5000

# How long to expose the last session issue (ms) after a rejected link
SESSION_ISSUE_TTL_MS=900000

# Authentication
AUTHENTICATION_GLOBAL_AUTH_TOKEN=A4gx18YGxKAvR01ClcHpcR7TjZUNtwvE

Expand Down
17 changes: 8 additions & 9 deletions controllers/chatsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import {
getChatList,
isExists,
sendMessage,
formatPhone,
formatGroup,
formatChatJid,
readMessage,
getMessageMedia,
getStoreMessage,
Expand All @@ -20,13 +19,13 @@ const send = async (req, res) => {
const session = getSession(res.locals.sessionId)
const { message } = req.body
const isGroup = req.body.isGroup ?? false
const receiver = isGroup ? formatGroup(req.body.receiver) : formatPhone(req.body.receiver)
const receiver = formatChatJid(req.body.receiver, isGroup)

const typesMessage = ['image', 'video', 'audio', 'document', 'sticker']

const filterTypeMessaje = compareAndFilter(Object.keys(message), typesMessage)
try {
const exists = await isExists(session, receiver, isGroup)
const exists = receiver.endsWith('@lid') ? true : await isExists(session, receiver, isGroup)

if (!exists) {
return response(res, 400, false, 'The receiver number is not exists.')
Expand Down Expand Up @@ -70,10 +69,10 @@ const sendBulk = async (req, res) => {
delay = 1000
}

receiver = formatPhone(receiver)
receiver = formatChatJid(receiver)

try {
const exists = await isExists(session, receiver)
const exists = receiver.endsWith('@lid') ? true : await isExists(session, receiver)

if (!exists) {
errors.push({ key, message: 'number not exists on whatsapp' })
Expand Down Expand Up @@ -106,7 +105,7 @@ const deleteChat = async (req, res) => {
const { receiver, isGroup, message } = req.body

try {
const jidFormat = isGroup ? formatGroup(receiver) : formatPhone(receiver)
const jidFormat = formatChatJid(receiver, isGroup)

await sendMessage(session, jidFormat, { delete: message })
response(res, 200, true, 'Message has been successfully deleted.')
Expand All @@ -120,7 +119,7 @@ const forward = async (req, res) => {
const { forward, receiver, isGroup } = req.body

const { id, remoteJid } = forward
const jidFormat = isGroup ? formatGroup(receiver) : formatPhone(receiver)
const jidFormat = formatChatJid(receiver, isGroup)

try {
const messages = await session.store.loadMessages(remoteJid, 25, null)
Expand Down Expand Up @@ -164,7 +163,7 @@ const sendPresence = async (req, res) => {
const { receiver, isGroup, presence } = req.body

try {
const jidFormat = isGroup ? formatGroup(receiver) : formatPhone(receiver)
const jidFormat = formatChatJid(receiver, isGroup)

await session.sendPresenceUpdate(presence, jidFormat)

Expand Down
4 changes: 2 additions & 2 deletions controllers/getMessages.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getSession, formatGroup, formatPhone } from '../whatsapp.js'
import { getSession, formatChatJid } from '../whatsapp.js'
import response from './../response.js'

const getMessages = async (req, res) => {
Expand All @@ -8,7 +8,7 @@ const getMessages = async (req, res) => {
const { limit = 25, cursorId = null, cursorFromMe = null, isGroup = false } = req.query

const isGroupBool = isGroup === 'true'
const jidFormat = isGroupBool ? formatGroup(jid) : formatPhone(jid)
const jidFormat = formatChatJid(jid, isGroupBool)

const cursor = {}

Expand Down
6 changes: 3 additions & 3 deletions controllers/miscControlls.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
getSession,
getProfilePicture,
formatPhone,
formatGroup,
formatChatJid,
profilePicture,
blockAndUnblockUser,
sendMessage,
Expand Down Expand Up @@ -63,7 +63,7 @@ const getProfilePictureUser = async (req, res) => {
try {
const session = getSession(res.locals.sessionId)
const isGroup = req.body.isGroup ?? false
const jid = isGroup ? formatGroup(req.body.jid) : formatPhone(req.body.jid)
const jid = formatChatJid(req.body.jid, isGroup)

const imagen = await getProfilePicture(session, jid, 'image')

Expand All @@ -81,7 +81,7 @@ const blockAndUnblockContact = async (req, res) => {
try {
const session = getSession(res.locals.sessionId)
const { jid, isBlock } = req.body
const jidFormat = formatPhone(jid)
const jidFormat = formatChatJid(jid)
const blockFormat = isBlock === true ? 'block' : 'unblock'
await blockAndUnblockUser(session, jidFormat, blockFormat)
response(res, 200, true, 'The contact has been blocked or unblocked successfully')
Expand Down
8 changes: 7 additions & 1 deletion middlewares/sessionValidator.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { isSessionExists, isSessionConnected } from '../whatsapp.js'
import { isSessionExists, isSessionConnected, getSessionIssue } from '../whatsapp.js'
import response from './../response.js'

const validate = (req, res, next) => {
const sessionId = req.query.id ?? req.params.id

if (!isSessionExists(sessionId)) {
const issue = getSessionIssue(sessionId)
// Fork guard: surface the last mismatch briefly so clients do not see an ambiguous 404.
if (issue && req.baseUrl === '/sessions' && (req.path.startsWith('/status/') || req.path.startsWith('/find/'))) {
return response(res, 409, false, issue.message, issue)
}

return response(res, 404, false, 'Session not found.')
}

Expand Down
17 changes: 13 additions & 4 deletions useDBAuthState/mysql-auth-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ import { decryptText, encryptText } from '../persistence/crypto.js';

// --- Mutex en memoria por session_id (serializa escrituras dentro del proceso) ---
const _memQueues = new Map();
const getEnv = (key, fallback = '') => {
const raw = process.env[key];
if (typeof raw !== 'string') return fallback;
const value = raw.trim();
return value === '' ? fallback : value;
};

function withSessionMutex(sessionId, task) {
const prev = _memQueues.get(sessionId) || Promise.resolve();
const next = prev.then(() => task());
Expand All @@ -17,11 +24,13 @@ export default class MySQLAuthStore {
constructor() {
if (!MySQLAuthStore.pool) {
const dbPoolLimit = Number.parseInt(process.env.DB_POOL_LIMIT ?? '30', 10);
const dbPort = Number.parseInt(getEnv('DB_PORT', '3306'), 10);
MySQLAuthStore.pool = mysql.createPool({
host: 'localhost',
user: process.env.DB_USER,
password: process.env.DB_PASWD,
database: process.env.DB_NAME,
host: getEnv('DB_HOST', '127.0.0.1'),
port: Number.isNaN(dbPort) ? 3306 : dbPort,
user: getEnv('DB_USER', 'root'),
password: getEnv('DB_PASWD', ''),
database: getEnv('DB_NAME', 'baileys_api'),
waitForConnections: true,
connectionLimit: Number.isNaN(dbPoolLimit) ? 30 : dbPoolLimit,
queueLimit: 0,
Expand Down
Loading