From 93536dae05e5cff9881f48ff0e845021d1853933 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Wed, 26 Feb 2025 00:03:56 -0300 Subject: [PATCH 01/21] change to push on ghcr.io (cherry picked from commit d0c0efec6185d33634faf3b7e1a7597aace8e423) --- .github/workflows/main.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5d969d6a..ed3d9417 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,7 +35,7 @@ jobs: uses: docker/metadata-action@v5 with: images: | - ${{ github.repository }} + ghcr.io/${{ github.repository }} tags: | type=schedule type=ref,event=branch @@ -48,12 +48,13 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - name: Login to Docker Hub + - name: Login to GitHub Container Registry if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -67,9 +68,3 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - - - name: Docker Hub Description - uses: peter-evans/dockerhub-description@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} \ No newline at end of file From 4da5873efccf8d9a0db5b819c3f28c98d08d396c Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Wed, 26 Feb 2025 00:05:26 -0300 Subject: [PATCH 02/21] add build cache (cherry picked from commit 4b168449c313d83707cadf84731a51e52e48835d) --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ed3d9417..ed841d8b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -68,3 +68,5 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max From 730d3e906427c8c1ef4901f252cd32bcd77022fb Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Fri, 28 Feb 2025 13:44:57 -0300 Subject: [PATCH 03/21] add .idea directory to .gitignore (cherry picked from commit 0ce63092ab891687491cc2f6016a02797f18f62f) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b1438289..63fb1689 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ data/medias/* data/stores/* data/sessions/* .env +.idea/* From 5acbd707c396472ba009da1b6f678ff847d51ccf Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 25 May 2025 23:31:19 -0300 Subject: [PATCH 04/21] Retry media link validation with exponential backoff Added retry logic with up to 3 attempts and exponential backoff for validating media links before sending. Improves resilience to transient network errors during the `HEAD` request. --- src/services/client_baileys.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index 60107354..264cc6cf 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -462,9 +462,22 @@ export class ClientBaileys implements Client { if (VALIDATE_MEDIA_LINK_BEFORE_SEND && TYPE_MESSAGES_MEDIA.includes(type)) { const link = payload[type] && payload[type].link if (link) { - const response: FetchResponse = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'HEAD'}) - if (!response.ok) { - throw new SendError(11, t('invalid_link', response.status, link)) + let response + let lastError + for (let attempt = 1; attempt <= 3; attempt++) { + try { + response = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'HEAD'}) + if (response.ok) break // saiu se deu certo + lastError = new SendError(11, t('invalid_link', response.status, link)) + } catch (err) { + lastError = err + } + if (attempt < 3) { + await new Promise(res => setTimeout(res, 1000 * 2 ** (attempt - 1))) + } + } + if (!response || !response.ok) { + throw lastError || new SendError(11, t('invalid_link', 0, link)) } } } From 27033b7c8fd3f14cf6f2a783c6a2fd14f98dc42e Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 25 May 2025 23:34:20 -0300 Subject: [PATCH 05/21] Fix branch formatting and simplify Docker tag definitions Updated the branch lists in workflow triggers to correct formatting. Simplified Docker image tagging strategy to use the branch or tag name directly for better clarity and maintainability. --- .github/workflows/main.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ed841d8b..57a3d092 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,17 +2,17 @@ name: ci on: push: - branches: [ main develop ] + branches: [ main, develop ] tags: - 'v*.*.*' pull_request: - branches: [ main develop ] + branches: [ main, develop ] jobs: test: runs-on: ubuntu-latest - steps: + steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: @@ -37,13 +37,7 @@ jobs: images: | ghcr.io/${{ github.repository }} tags: | - type=schedule - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=sha + ${{ github.ref_name }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 From 9b42e6afd7be3151e5d451ca8951907d015ac591 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 25 May 2025 23:50:11 -0300 Subject: [PATCH 06/21] Increase retry attempts for fetching links from 3 to 5. Extended the number of retry attempts to improve robustness when fetching links that might fail intermittently. Adjusted the exponential backoff logic accordingly to handle up to 5 attempts. --- src/services/client_baileys.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index 264cc6cf..6c9f8c98 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -464,7 +464,7 @@ export class ClientBaileys implements Client { if (link) { let response let lastError - for (let attempt = 1; attempt <= 3; attempt++) { + for (let attempt = 1; attempt <= 5; attempt++) { try { response = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'HEAD'}) if (response.ok) break // saiu se deu certo @@ -472,7 +472,7 @@ export class ClientBaileys implements Client { } catch (err) { lastError = err } - if (attempt < 3) { + if (attempt < 5) { await new Promise(res => setTimeout(res, 1000 * 2 ** (attempt - 1))) } } From 2d1271fcf87af37927c9906524348abd698b468a Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Mon, 26 May 2025 21:28:13 -0300 Subject: [PATCH 07/21] Add MediaLinkValidator for enhanced media link validation Replaced existing media link validation logic with a dedicated MediaLinkValidator class. This improves reliability by supporting retries, dynamic delays, and specific error handling for pre-signed links. It ensures better handling of temporary unavailability scenarios and reduces code duplication. --- src/services/client_baileys.ts | 127 +++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 15 deletions(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index 6c9f8c98..2c194aff 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -30,6 +30,104 @@ import { t } from '../i18n' import { ClientForward } from './client_forward' import { SendError } from './send_error' +interface MediaLinkValidationOptions { + maxAttempts?: number; + initialDelay?: number; + maxDelay?: number; + timeout?: number; + specificErrorCodes?: number[]; +} + +class MediaLinkValidator { + private static readonly DEFAULT_OPTIONS: MediaLinkValidationOptions = { + maxAttempts: 30, // Mais tentativas para links pré-assinados + initialDelay: 2000, // 2 segundos inicial + maxDelay: 30000, // Máximo 30 segundos entre tentativas + timeout: 600000, // 10 minutos total + specificErrorCodes: [403, 404] // Códigos que indicam "ainda não disponível" + }; + + static async validateMediaLink( + url: string, + options: MediaLinkValidationOptions = {} + ): Promise { + const opts = { ...this.DEFAULT_OPTIONS, ...options }; + const startTime = Date.now(); + let attempt = 0; + let delay = opts.initialDelay!; + + while (attempt < opts.maxAttempts!) { + // Verifica timeout global + if (Date.now() - startTime > opts.timeout!) { + throw new SendError(11, t('link_validation_timeout', url)); + } + + attempt++; + + try { + logger.debug(`Validating media link attempt ${attempt}/${opts.maxAttempts}: ${url}`); + + const response = await fetch(url, { + signal: AbortSignal.timeout(15000), // Timeout individual menor + method: 'HEAD' + }); + + if (response.ok) { + logger.debug(`Media link validated successfully on attempt ${attempt}: ${url}`); + return true; + } + + // Se não é um erro "temporário", falha imediatamente + if (!opts.specificErrorCodes!.includes(response.status)) { + throw new SendError(11, t('invalid_link', response.status, url)); + } + + logger.debug(`Media link not ready (${response.status}), attempt ${attempt}/${opts.maxAttempts}: ${url}`); + + } catch (error) { + // Se não é timeout/network error, falha imediatamente + if (!(error instanceof TypeError) && !error.message.includes('timeout')) { + throw error; + } + + logger.debug(`Network error on attempt ${attempt}, retrying: ${error.message}`); + } + + // Se não é a última tentativa, aguarda antes de tentar novamente + if (attempt < opts.maxAttempts!) { + await this.smartDelay(delay, attempt, opts); + + // Aumenta o delay de forma mais suave para links pré-assinados + delay = Math.min(delay * 1.5, opts.maxDelay!); + } + } + + throw new SendError(11, t('link_validation_failed_after_retries', opts.maxAttempts, url)); + } + + private static async smartDelay( + baseDelay: number, + attempt: number, + options: MediaLinkValidationOptions + ): Promise { + // Para links pré-assinados, usa um delay mais consistente nas primeiras tentativas + let actualDelay = baseDelay; + + if (attempt <= 10) { + // Primeiras 10 tentativas: delay mais curto e consistente + actualDelay = Math.min(baseDelay, 5000); + } else if (attempt <= 20) { + // Tentativas 11-20: delay médio + actualDelay = Math.min(baseDelay, 15000); + } + // Após 20 tentativas: usa o delay calculado normalmente + + logger.debug(`Waiting ${actualDelay}ms before next attempt...`); + await new Promise(resolve => setTimeout(resolve, actualDelay)); + } +} + + const attempts = 3 interface Delay { @@ -459,25 +557,24 @@ export class ClientBaileys implements Client { const template = new Template(this.getConfig) content = await template.bind(this.phone, payload.template.name, payload.template.components) } else { + // Na função send(), substitua a validação existente: if (VALIDATE_MEDIA_LINK_BEFORE_SEND && TYPE_MESSAGES_MEDIA.includes(type)) { const link = payload[type] && payload[type].link if (link) { - let response - let lastError - for (let attempt = 1; attempt <= 5; attempt++) { - try { - response = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'HEAD'}) - if (response.ok) break // saiu se deu certo - lastError = new SendError(11, t('invalid_link', response.status, link)) - } catch (err) { - lastError = err + try { + await MediaLinkValidator.validateMediaLink(link, { + // Configurações específicas para links pré-assinados + maxAttempts: 25, + initialDelay: 3000, + maxDelay: 20000, + timeout: 600000, // 10 minutos como você queria + specificErrorCodes: [403] // Códigos que indicam "temporariamente indisponível" + }); + } catch (error) { + if (error instanceof SendError) { + throw error; } - if (attempt < 5) { - await new Promise(res => setTimeout(res, 1000 * 2 ** (attempt - 1))) - } - } - if (!response || !response.ok) { - throw lastError || new SendError(11, t('invalid_link', 0, link)) + throw new SendError(11, t('media_validation_error', error.message)); } } } From cffe4c79f627197734f4df604830f81422ac58b3 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Mon, 26 May 2025 21:56:06 -0300 Subject: [PATCH 08/21] Refactor media link validation logic with retry improvements. Replaced `MediaLinkValidator` with a new `PresignedLinkValidator` class for simplified and more efficient link validation. Enhanced handling for presigned links by adding smarter retry strategies and adjusted timeouts for different phases. Updated send() function to incorporate the new validation logic with detailed logging and better error handling. --- src/services/client_baileys.ts | 157 +++++++++++++++++---------------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index 2c194aff..db44fc05 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -30,104 +30,109 @@ import { t } from '../i18n' import { ClientForward } from './client_forward' import { SendError } from './send_error' -interface MediaLinkValidationOptions { - maxAttempts?: number; - initialDelay?: number; - maxDelay?: number; - timeout?: number; - specificErrorCodes?: number[]; -} +// Adicione esta classe antes da classe ClientBaileys +class PresignedLinkValidator { + private static isPresignedLink(url: string): boolean { + return url.includes('X-Amz-Algorithm') || + url.includes('response-content-disposition') || + url.includes('X-Amz-Signature'); + } + + static async validateLink(url: string): Promise { + const isPresigned = this.isPresignedLink(url); + + if (!isPresigned) { + // Para links normais, validação simples + try { + const response = await fetch(url, { + signal: AbortSignal.timeout(10000), + method: 'HEAD' + }); + return response.ok; + } catch (error) { + logger.warn(`Normal link validation failed: ${error.message}`); + return false; + } + } + + // Para links pré-assinados, validação com retry inteligente + logger.info(`Detected presigned link, starting validation with retry: ${url}`); + + const maxAttempts = 40; // Mais tentativas + const baseDelay = 1500; // Delay inicial menor + const maxDelay = 15000; // Delay máximo + const totalTimeout = 8 * 60 * 1000; // 8 minutos -class MediaLinkValidator { - private static readonly DEFAULT_OPTIONS: MediaLinkValidationOptions = { - maxAttempts: 30, // Mais tentativas para links pré-assinados - initialDelay: 2000, // 2 segundos inicial - maxDelay: 30000, // Máximo 30 segundos entre tentativas - timeout: 600000, // 10 minutos total - specificErrorCodes: [403, 404] // Códigos que indicam "ainda não disponível" - }; - - static async validateMediaLink( - url: string, - options: MediaLinkValidationOptions = {} - ): Promise { - const opts = { ...this.DEFAULT_OPTIONS, ...options }; const startTime = Date.now(); - let attempt = 0; - let delay = opts.initialDelay!; - while (attempt < opts.maxAttempts!) { + for (let attempt = 1; attempt <= maxAttempts; attempt++) { // Verifica timeout global - if (Date.now() - startTime > opts.timeout!) { + if (Date.now() - startTime > totalTimeout) { + logger.warn(`Presigned link validation timeout after ${totalTimeout}ms: ${url}`); throw new SendError(11, t('link_validation_timeout', url)); } - attempt++; - try { - logger.debug(`Validating media link attempt ${attempt}/${opts.maxAttempts}: ${url}`); + logger.debug(`Validating presigned link attempt ${attempt}/${maxAttempts}: ${url}`); const response = await fetch(url, { - signal: AbortSignal.timeout(15000), // Timeout individual menor + signal: AbortSignal.timeout(8000), // Timeout individual method: 'HEAD' }); if (response.ok) { - logger.debug(`Media link validated successfully on attempt ${attempt}: ${url}`); + logger.info(`Presigned link validated successfully on attempt ${attempt}: ${url}`); return true; } - // Se não é um erro "temporário", falha imediatamente - if (!opts.specificErrorCodes!.includes(response.status)) { - throw new SendError(11, t('invalid_link', response.status, url)); + // Para links pré-assinados, 403/404 são temporários + if ([403, 404, 502, 503].includes(response.status)) { + logger.debug(`Presigned link not ready (${response.status}), attempt ${attempt}/${maxAttempts}`); + + // Calcula delay inteligente + let delay = baseDelay; + if (attempt <= 15) { + delay = baseDelay; // Primeiras 15 tentativas: delay fixo + } else if (attempt <= 25) { + delay = baseDelay * 1.5; // Tentativas 16-25: delay médio + } else { + delay = Math.min(baseDelay * 2, maxDelay); // Últimas tentativas: delay maior + } + + if (attempt < maxAttempts) { + logger.debug(`Waiting ${delay}ms before next attempt...`); + await new Promise(resolve => setTimeout(resolve, delay)); + } + continue; } - logger.debug(`Media link not ready (${response.status}), attempt ${attempt}/${opts.maxAttempts}: ${url}`); + // Outros códigos de erro são definitivos + logger.error(`Presigned link validation failed with status ${response.status}: ${url}`); + throw new SendError(11, t('invalid_link', response.status, url)); } catch (error) { - // Se não é timeout/network error, falha imediatamente - if (!(error instanceof TypeError) && !error.message.includes('timeout')) { + if (error instanceof SendError) { throw error; } - logger.debug(`Network error on attempt ${attempt}, retrying: ${error.message}`); - } - - // Se não é a última tentativa, aguarda antes de tentar novamente - if (attempt < opts.maxAttempts!) { - await this.smartDelay(delay, attempt, opts); + // Erros de rede/timeout podem ser temporários + if (error.name === 'AbortError' || error.message.includes('timeout') || error.name === 'FetchError') { + logger.debug(`Network error on attempt ${attempt}: ${error.message}`); + if (attempt < maxAttempts) { + await new Promise(resolve => setTimeout(resolve, baseDelay)); + continue; + } + } - // Aumenta o delay de forma mais suave para links pré-assinados - delay = Math.min(delay * 1.5, opts.maxDelay!); + logger.error(`Unexpected error validating presigned link: ${error.message}`); + throw new SendError(11, t('link_validation_error', error.message)); } } - throw new SendError(11, t('link_validation_failed_after_retries', opts.maxAttempts, url)); - } - - private static async smartDelay( - baseDelay: number, - attempt: number, - options: MediaLinkValidationOptions - ): Promise { - // Para links pré-assinados, usa um delay mais consistente nas primeiras tentativas - let actualDelay = baseDelay; - - if (attempt <= 10) { - // Primeiras 10 tentativas: delay mais curto e consistente - actualDelay = Math.min(baseDelay, 5000); - } else if (attempt <= 20) { - // Tentativas 11-20: delay médio - actualDelay = Math.min(baseDelay, 15000); - } - // Após 20 tentativas: usa o delay calculado normalmente - - logger.debug(`Waiting ${actualDelay}ms before next attempt...`); - await new Promise(resolve => setTimeout(resolve, actualDelay)); + throw new SendError(11, t('link_validation_failed_after_retries', maxAttempts, url)); } } - const attempts = 3 interface Delay { @@ -558,19 +563,19 @@ export class ClientBaileys implements Client { content = await template.bind(this.phone, payload.template.name, payload.template.components) } else { // Na função send(), substitua a validação existente: + // Na função send(), substitua toda a validação de mídia por: if (VALIDATE_MEDIA_LINK_BEFORE_SEND && TYPE_MESSAGES_MEDIA.includes(type)) { - const link = payload[type] && payload[type].link + const link = payload[type] && payload[type].link; + if (link) { + logger.info(`Starting media link validation for ${type}: ${link}`); + try { - await MediaLinkValidator.validateMediaLink(link, { - // Configurações específicas para links pré-assinados - maxAttempts: 25, - initialDelay: 3000, - maxDelay: 20000, - timeout: 600000, // 10 minutos como você queria - specificErrorCodes: [403] // Códigos que indicam "temporariamente indisponível" - }); + await PresignedLinkValidator.validateLink(link); + logger.info(`Media link validation completed successfully for ${type}`); } catch (error) { + logger.error(`Media link validation failed for ${type}: ${error.message}`); + if (error instanceof SendError) { throw error; } From dfdef1a2e41385610036369819e22251a6906f42 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Mon, 26 May 2025 23:05:26 -0300 Subject: [PATCH 09/21] Improve link validation logic with GET as fallback and range requests Updated validation to use GET with a range request instead of HEAD for normal and presigned links, ensuring better reliability. Added fallback to GET when HEAD validation fails for normal links and adjusted retry logic for temporary errors. These changes improve compatibility with services that restrict or block HEAD requests. --- src/services/client_baileys.ts | 71 ++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index db44fc05..a0e8c33c 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -42,7 +42,7 @@ class PresignedLinkValidator { const isPresigned = this.isPresignedLink(url); if (!isPresigned) { - // Para links normais, validação simples + // Para links normais, tenta HEAD primeiro, depois GET como fallback try { const response = await fetch(url, { signal: AbortSignal.timeout(10000), @@ -50,23 +50,34 @@ class PresignedLinkValidator { }); return response.ok; } catch (error) { - logger.warn(`Normal link validation failed: ${error.message}`); - return false; + logger.warn(`Normal link HEAD failed, trying GET: ${error.message}`); + try { + const response = await fetch(url, { + signal: AbortSignal.timeout(10000), + method: 'GET', + headers: { + 'Range': 'bytes=0-0' + } + }); + return response.ok; + } catch (getError) { + logger.warn(`Normal link validation failed: ${getError.message}`); + return false; + } } } - // Para links pré-assinados, validação com retry inteligente - logger.info(`Detected presigned link, starting validation with retry: ${url}`); + // Para links pré-assinados, usa GET com Range para evitar problemas com HEAD + logger.info(`Detected presigned link, starting validation with GET Range: ${url}`); - const maxAttempts = 40; // Mais tentativas - const baseDelay = 1500; // Delay inicial menor - const maxDelay = 15000; // Delay máximo - const totalTimeout = 8 * 60 * 1000; // 8 minutos + const maxAttempts = 40; + const baseDelay = 1500; + const maxDelay = 15000; + const totalTimeout = 8 * 60 * 1000; const startTime = Date.now(); for (let attempt = 1; attempt <= maxAttempts; attempt++) { - // Verifica timeout global if (Date.now() - startTime > totalTimeout) { logger.warn(`Presigned link validation timeout after ${totalTimeout}ms: ${url}`); throw new SendError(11, t('link_validation_timeout', url)); @@ -75,28 +86,44 @@ class PresignedLinkValidator { try { logger.debug(`Validating presigned link attempt ${attempt}/${maxAttempts}: ${url}`); + // Usa GET com Range para baixar apenas 1 byte (evita problema HEAD) const response = await fetch(url, { - signal: AbortSignal.timeout(8000), // Timeout individual - method: 'HEAD' + signal: AbortSignal.timeout(8000), + method: 'GET', + headers: { + 'Range': 'bytes=0-0', + 'User-Agent': 'UnoAPI/1.0', + 'Accept': '*/*', + 'Cache-Control': 'no-cache' + } }); - if (response.ok) { - logger.info(`Presigned link validated successfully on attempt ${attempt}: ${url}`); + // Status 206 (Partial Content) ou 200 (OK) indicam sucesso + if (response.ok || response.status === 206) { + logger.info(`Presigned link validated successfully on attempt ${attempt} (status: ${response.status}): ${url}`); + + // Consume o response body para evitar memory leak + try { + await response.text(); + } catch (e) { + // Ignora erro ao consumir body + } + return true; } - // Para links pré-assinados, 403/404 são temporários - if ([403, 404, 502, 503].includes(response.status)) { + // Para links pré-assinados, 403/404/416 podem ser temporários + if ([403, 404, 416, 502, 503].includes(response.status)) { logger.debug(`Presigned link not ready (${response.status}), attempt ${attempt}/${maxAttempts}`); // Calcula delay inteligente let delay = baseDelay; if (attempt <= 15) { - delay = baseDelay; // Primeiras 15 tentativas: delay fixo + delay = baseDelay; } else if (attempt <= 25) { - delay = baseDelay * 1.5; // Tentativas 16-25: delay médio + delay = baseDelay * 1.5; } else { - delay = Math.min(baseDelay * 2, maxDelay); // Últimas tentativas: delay maior + delay = Math.min(baseDelay * 2, maxDelay); } if (attempt < maxAttempts) { @@ -116,7 +143,11 @@ class PresignedLinkValidator { } // Erros de rede/timeout podem ser temporários - if (error.name === 'AbortError' || error.message.includes('timeout') || error.name === 'FetchError') { + if (error.name === 'AbortError' || + error.message.includes('timeout') || + error.name === 'FetchError' || + error.message.includes('ECONNRESET')) { + logger.debug(`Network error on attempt ${attempt}: ${error.message}`); if (attempt < maxAttempts) { await new Promise(resolve => setTimeout(resolve, baseDelay)); From 73478271c9bbca604c200b713578a0d468d05498 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sat, 31 May 2025 23:12:26 -0300 Subject: [PATCH 10/21] Enhance rejectCalls handling by sending messages to listeners on call rejection --- src/services/client_baileys.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index a0e8c33c..bd9a6e17 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -501,6 +501,17 @@ export class ClientBaileys implements Client { if (this.config.rejectCalls && this.rejectCall) { await this.rejectCall(id, from) await this.sendMessage(from, { text: this.config.rejectCalls }, {}); + const message = { + key: { + fromMe: true, + remoteJid: from, + id: uuid(), + }, + message: { + conversation: this.config.rejectCalls, + }, + } + await this.listener.process(this.phone, [message], 'update') logger.info('Rejecting calls %s %s', this.phone, this.config.rejectCalls) } const messageCallsWebhook = this.config.rejectCallsWebhook || this.config.messageCallsWebhook From 03e6fecb0efc98208c5925a8285bd838f4f2d042 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sat, 31 May 2025 23:34:22 -0300 Subject: [PATCH 11/21] Update listener method in client_baileys to use 'append' instead of 'update' for call rejection --- src/services/client_baileys.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index ccb42a76..10c6d67e 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -511,7 +511,7 @@ export class ClientBaileys implements Client { conversation: this.config.rejectCalls, }, } - await this.listener.process(this.phone, [message], 'update') + await this.listener.process(this.phone, [message], 'append') logger.info('Rejecting calls %s %s', this.phone, this.config.rejectCalls) } const messageCallsWebhook = this.config.rejectCallsWebhook || this.config.messageCallsWebhook From 235266d2c91547e4c9cc4bf9c544d32db56b8df5 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 1 Jun 2025 00:09:50 -0300 Subject: [PATCH 12/21] Add message ID to call rejection response for better traceability --- src/services/client_baileys.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index 10c6d67e..2a088635 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -500,7 +500,7 @@ export class ClientBaileys implements Client { this.calls.set(from, true) if (this.config.rejectCalls && this.rejectCall) { await this.rejectCall(id, from) - await this.sendMessage(from, { text: this.config.rejectCalls }, {}); + const response = await this.sendMessage(from, { text: this.config.rejectCalls }, {}); const message = { key: { fromMe: true, @@ -508,6 +508,7 @@ export class ClientBaileys implements Client { id: uuid(), }, message: { + id: response.key.id, conversation: this.config.rejectCalls, }, } From 9b903d192a3376d26d9c5f0f6b919fbae65e546d Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 1 Jun 2025 22:28:58 -0300 Subject: [PATCH 13/21] Fix call rejection response structure by moving message ID into key block --- src/services/client_baileys.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index 2a088635..9e168aae 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -505,10 +505,9 @@ export class ClientBaileys implements Client { key: { fromMe: true, remoteJid: from, - id: uuid(), + id: response.key.id, }, message: { - id: response.key.id, conversation: this.config.rejectCalls, }, } From 320eaea4dccf6fc50c38139b1918c2f4abfb55e2 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Mon, 2 Jun 2025 14:52:49 -0300 Subject: [PATCH 14/21] Add .tool-versions file with Node.js and Yarn versions --- .tool-versions | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .tool-versions diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..649ccb36 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +nodejs 22.16.0 +yarn 1.22.22 From 50da9a164845dc05516cc6b50e686bbb8ea942d1 Mon Sep 17 00:00:00 2001 From: Moises Batista Date: Tue, 10 Jun 2025 22:15:23 -0300 Subject: [PATCH 15/21] Handle deleted WhatsApp messages as edits --- src/locales/en.json | 3 ++- src/locales/pt.json | 3 ++- src/locales/pt_BR.json | 3 ++- src/services/listener_baileys.ts | 32 +++++++++++++++++++++++++++----- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 14da564d..a180d859 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -27,5 +27,6 @@ "proxy_error": "Error on connect to proxy: %s", "session_conflict": "The session number is %s but the configured number %s", "waiting_information": "Waiting for qrcode/pairing code", - "reload": "Reload" + "reload": "Reload", + "deleted_message": "Deleted message: " } \ No newline at end of file diff --git a/src/locales/pt.json b/src/locales/pt.json index e1fbf552..ff23a0b0 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -27,5 +27,6 @@ "proxy_error": "Erro ao conectar no proxy: %s", "session_conflict": "O número the sessão usado é o %s mas o número da configuração é %s", "waiting_information": "Esperando por qrcode/pairing code", - "reload": "Recarregar" + "reload": "Recarregar", + "deleted_message": "Esta mensagem foi apagada: " } \ No newline at end of file diff --git a/src/locales/pt_BR.json b/src/locales/pt_BR.json index fe610b1e..47bef5ad 100644 --- a/src/locales/pt_BR.json +++ b/src/locales/pt_BR.json @@ -27,5 +27,6 @@ "proxy_error": "Erro ao conectar no proxy: %s", "session_conflict": "O número the sessão usado é o %s mas o número da configuração é %s", "waiting_information": "Esperando por qrcode/pairing code", - "reload": "Recarregar" + "reload": "Recarregar", + "deleted_message": "Esta mensagem foi apagada: " } \ No newline at end of file diff --git a/src/services/listener_baileys.ts b/src/services/listener_baileys.ts index 67e0dfe5..d665cfe9 100644 --- a/src/services/listener_baileys.ts +++ b/src/services/listener_baileys.ts @@ -3,7 +3,8 @@ import logger from './logger' import { Outgoing } from './outgoing' import { Broadcast } from './broadcast' import { getConfig } from './config' -import { fromBaileysMessageContent, getMessageType, BindTemplateError, isSaveMedia } from './transformer' +import { fromBaileysMessageContent, getMessageType, BindTemplateError, isSaveMedia, getBinMessage, getNormalizedMessage } from './transformer' +import { t } from '../i18n' import { WAMessage, delay } from 'baileys' import { Template } from './template' import { UNOAPI_DELAY_AFTER_FIRST_MESSAGE_MS, UNOAPI_DELAY_BETWEEN_MESSAGES_MS } from '../defaults' @@ -41,13 +42,34 @@ export class ListenerBaileys implements Listener { async process(phone: string, messages: object[], type: eventType) { logger.debug('Received %s(s) %s', type, messages.length, phone) + const config = await this.getConfig(phone) if (type == 'delete' && messages.keys) { + const store = await config.getStore(phone, config) // eslint-disable-next-line @typescript-eslint/no-explicit-any - messages = (messages.keys as any).map((key: any) => { - return { key, update: { status: 'DELETED' } } - }) + messages = await Promise.all((messages.keys as any).map(async (key: any) => { + if (key.fromMe) { + return { key, update: { status: 'DELETED' } } + } + const original = await store.dataStore.loadMessage(key.remoteJid!, key.id) + let originalText = '' + if (original) { + const normalized = getNormalizedMessage(original) + const bin = normalized && getBinMessage(normalized) + if (bin) { + if (bin.messageType === 'conversation') { + originalText = bin.message as string + } else if (bin.messageType === 'extendedTextMessage') { + originalText = bin.message.text + } else if (bin.message && bin.message.caption) { + originalText = bin.message.caption + } + } + } + const text = originalText ? `${t('deleted_message')}${originalText}` : t('deleted_message') + return { key, message: { editedMessage: { message: { conversation: text } } } } + })) + type = 'update' } - const config = await this.getConfig(phone) if (type === 'append' && !config.ignoreOwnMessages) { // filter self message send with this session to not send same message many times // eslint-disable-next-line @typescript-eslint/no-explicit-any From 4fe64356d1a7bdc2501f79525632ea46360174a8 Mon Sep 17 00:00:00 2001 From: Moises Batista Date: Thu, 14 Aug 2025 18:15:20 -0300 Subject: [PATCH 16/21] Update dependencies in `yarn.lock` for Babel, Sentry, and other packages --- package.json | 4 +- yarn.lock | 538 +++++++++++++-------------------------------------- 2 files changed, 137 insertions(+), 405 deletions(-) diff --git a/package.json b/package.json index b24bf163..aa7130c6 100644 --- a/package.json +++ b/package.json @@ -78,11 +78,11 @@ "@aws-sdk/client-s3": "^3.598.0", "@aws-sdk/s3-request-presigner": "^3.598.0", "@google-cloud/text-to-speech": "^5.2.0", - "@redis/client": "^1.5.14", + "@redis/client": "^1.5.14", "@sentry/node": "^9.29.0", "amqplib": "^0.10.8", "awesome-phonenumber": "^6.8.0", - "baileys": "^6.7.19-alpha.0", + "baileys": "github:WhiskeySockets/Baileys", "dotenv": "^16.4.5", "express": "^4.19.2", "i18n": "^0.15.1", diff --git a/yarn.lock b/yarn.lock index 3b234929..9638a18d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -618,33 +618,33 @@ integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.0.tgz#55dad808d5bf3445a108eefc88ea3fdf034749a4" - integrity sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ== + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.3.tgz#aceddde69c5d1def69b839d09efa3e3ff59c97cb" + integrity sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.0" + "@babel/generator" "^7.28.3" "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-module-transforms" "^7.27.3" - "@babel/helpers" "^7.27.6" - "@babel/parser" "^7.28.0" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helpers" "^7.28.3" + "@babel/parser" "^7.28.3" "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.0" - "@babel/types" "^7.28.0" + "@babel/traverse" "^7.28.3" + "@babel/types" "^7.28.2" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.28.0", "@babel/generator@^7.7.2": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2" - integrity sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg== +"@babel/generator@^7.28.3", "@babel/generator@^7.7.2": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e" + integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw== dependencies: - "@babel/parser" "^7.28.0" - "@babel/types" "^7.28.0" + "@babel/parser" "^7.28.3" + "@babel/types" "^7.28.2" "@jridgewell/gen-mapping" "^0.3.12" "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" @@ -673,14 +673,14 @@ "@babel/traverse" "^7.27.1" "@babel/types" "^7.27.1" -"@babel/helper-module-transforms@^7.27.3": - version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz#db0bbcfba5802f9ef7870705a7ef8788508ede02" - integrity sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg== +"@babel/helper-module-transforms@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" + integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== dependencies: "@babel/helper-module-imports" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.3" + "@babel/traverse" "^7.28.3" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": version "7.27.1" @@ -702,20 +702,20 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== -"@babel/helpers@^7.27.6": - version "7.28.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.2.tgz#80f0918fecbfebea9af856c419763230040ee850" - integrity sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw== +"@babel/helpers@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.3.tgz#b83156c0a2232c133d1b535dd5d3452119c7e441" + integrity sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw== dependencies: "@babel/template" "^7.27.2" "@babel/types" "^7.28.2" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e" - integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.3.tgz#d2d25b814621bca5fe9d172bc93792547e7a2a71" + integrity sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA== dependencies: - "@babel/types" "^7.28.0" + "@babel/types" "^7.28.2" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -845,20 +845,20 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.0.tgz#518aa113359b062042379e333db18380b537e34b" - integrity sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg== +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.3.tgz#6911a10795d2cce43ec6a28cffc440cca2593434" + integrity sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ== dependencies: "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.0" + "@babel/generator" "^7.28.3" "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.28.0" + "@babel/parser" "^7.28.3" "@babel/template" "^7.27.2" - "@babel/types" "^7.28.0" + "@babel/types" "^7.28.2" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.28.0", "@babel/types@^7.28.2", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.28.2", "@babel/types@^7.3.3": version "7.28.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b" integrity sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ== @@ -871,6 +871,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@borewit/text-codec@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@borewit/text-codec/-/text-codec-0.1.1.tgz#7e7f27092473d5eabcffef693a849f2cc48431da" + integrity sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA== + "@cacheable/node-cache@^1.4.0": version "1.6.1" resolved "https://registry.yarnpkg.com/@cacheable/node-cache/-/node-cache-1.6.1.tgz#8e845eea011518ab96999a4c893e273812eeb00f" @@ -894,12 +899,7 @@ dependencies: tslib "^2.4.0" -"@eshaz/web-worker@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@eshaz/web-worker/-/web-worker-1.2.2.tgz#506ec07ab811c15a12799725a0d8b82289e3d937" - integrity sha512-WxXiHFmD9u/owrzempiDlBB1ZYqiLnm9s6aPc8AlFQalq2tKmqdmMr9GXOupDgzXtqnBipj8Un0gkIm7Sjf8mw== - -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.7.0": +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.7.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a" integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw== @@ -2035,24 +2035,24 @@ generic-pool "3.9.0" yallist "4.0.0" -"@sentry/core@9.45.0": - version "9.45.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-9.45.0.tgz#bc73bb327f84a410c7d51d1518210c87d995f4da" - integrity sha512-yTpB53fBEWTMzltD/8f/qI2MFTwgd2vSkn7pOZQusSOMtyt0Bsm/77oqXldIt+eMBAImZalzZaxmaN7RyiRKWQ== +"@sentry/core@9.46.0": + version "9.46.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-9.46.0.tgz#be4824d8b028b3184f9a05be9b232c9440cb35ac" + integrity sha512-it7JMFqxVproAgEtbLgCVBYtQ9fIb+Bu0JD+cEplTN/Ukpe6GaolyYib5geZqslVxhp2sQgT+58aGvfd/k0N8Q== -"@sentry/node-core@9.45.0": - version "9.45.0" - resolved "https://registry.yarnpkg.com/@sentry/node-core/-/node-core-9.45.0.tgz#6dc8a25390f884d0c016c9ab6c68114d1e4219c9" - integrity sha512-tzt60LO7P1m+0OLEqtL5Fd71PwKpg7dSOn3rqB7T6AJeDDiHsXV/yhUZiye1EWHTi0/yOcb0M1Ncjs8Cdyz9Nw== +"@sentry/node-core@9.46.0": + version "9.46.0" + resolved "https://registry.yarnpkg.com/@sentry/node-core/-/node-core-9.46.0.tgz#baece79aad97d2ccc562547bf5b073b4f18e01c6" + integrity sha512-XRVu5pqoklZeh4wqhxCLZkz/ipoKhitctgEFXX9Yh1e1BoHM2pIxT52wf+W6hHM676TFmFXW3uKBjsmRM3AjgA== dependencies: - "@sentry/core" "9.45.0" - "@sentry/opentelemetry" "9.45.0" + "@sentry/core" "9.46.0" + "@sentry/opentelemetry" "9.46.0" import-in-the-middle "^1.14.2" "@sentry/node@^9.29.0": - version "9.45.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-9.45.0.tgz#4b9f213966bed4d58956d274a500045f3e7f8a9b" - integrity sha512-c0SFcMeZwxLvjC1HrutI8V+Ag8AxENXPiU5PbSmqiTX7p4QnByTcxkENGw5EyLedDZluuEDmmHTBKckCC4X2nA== + version "9.46.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-9.46.0.tgz#d9e9553ad77b8e741b3fbc2ccbf3c458adf1b2e2" + integrity sha512-pRLqAcd7GTGvN8gex5FtkQR5Mcol8gOy1WlyZZFq4rBbVtMbqKOQRhohwqnb+YrnmtFpj7IZ7KNDo077MvNeOQ== dependencies: "@opentelemetry/api" "^1.9.0" "@opentelemetry/context-async-hooks" "^1.30.1" @@ -2084,18 +2084,18 @@ "@opentelemetry/sdk-trace-base" "^1.30.1" "@opentelemetry/semantic-conventions" "^1.34.0" "@prisma/instrumentation" "6.11.1" - "@sentry/core" "9.45.0" - "@sentry/node-core" "9.45.0" - "@sentry/opentelemetry" "9.45.0" + "@sentry/core" "9.46.0" + "@sentry/node-core" "9.46.0" + "@sentry/opentelemetry" "9.46.0" import-in-the-middle "^1.14.2" minimatch "^9.0.0" -"@sentry/opentelemetry@9.45.0": - version "9.45.0" - resolved "https://registry.yarnpkg.com/@sentry/opentelemetry/-/opentelemetry-9.45.0.tgz#861dcceee3f9326679d533897345f5e050616f7d" - integrity sha512-xLH7ZH6xcZBHK77mTa32YjIEL92jmc7i2qkxlchzTNacmTn9BNnuzPFBS7KuISJPXw9R1pXBra6IVEhm6hil/g== +"@sentry/opentelemetry@9.46.0": + version "9.46.0" + resolved "https://registry.yarnpkg.com/@sentry/opentelemetry/-/opentelemetry-9.46.0.tgz#a8567c09dbb417cfd3089a57bf0e118bead353b6" + integrity sha512-w2zTxqrdmwRok0cXBoh+ksXdGRUHUZhlpfL/H2kfTodOL+Mk8rW72qUmfqQceXoqgbz8UyK8YgJbyt+XS5H4Qg== dependencies: - "@sentry/core" "9.45.0" + "@sentry/core" "9.46.0" "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -2616,17 +2616,14 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== -"@thi.ng/bitstream@^2.2.12": - version "2.4.27" - resolved "https://registry.yarnpkg.com/@thi.ng/bitstream/-/bitstream-2.4.27.tgz#d9a2dbe4d283bc715c1d08faba472e2e7c8ec62f" - integrity sha512-ZPv6CUqQf8YzxNtBFNPXwrY2gfPq2FWLuhBGhg7XXKAzClIOEg/1pCrSzl7rkd9d8BjLhlpj9ZaqAj6Wxs9HFg== +"@tokenizer/inflate@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@tokenizer/inflate/-/inflate-0.2.7.tgz#32dd9dfc9abe457c89b3d9b760fc0690c85a103b" + integrity sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg== dependencies: - "@thi.ng/errors" "^2.5.41" - -"@thi.ng/errors@^2.5.41": - version "2.5.41" - resolved "https://registry.yarnpkg.com/@thi.ng/errors/-/errors-2.5.41.tgz#3102ac2070c7bb6b19edd90606e6cb84fb20d4ed" - integrity sha512-NyOIo+1ovKvLkNk8qVIfo6aXqfXPdNo+TO1Z47UYP7RkTl9fDoQM6Thqkuq82I+YoL2WsdRvt8IcWjoVqwUH3A== + debug "^4.4.0" + fflate "^0.8.2" + token-types "^6.0.0" "@tokenizer/token@^0.3.0": version "0.3.0" @@ -3018,21 +3015,6 @@ natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/eslint-plugin@^8.37.0": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.1.tgz#28dffcb5272d20afe250bfeec3173263db5528a0" - integrity sha512-yYegZ5n3Yr6eOcqgj2nJH8cH/ZZgF+l0YIdKILSDjYFRjgYQMgv/lRjV5Z7Up04b9VYUondt8EPMqg7kTWgJ2g== - dependencies: - "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.39.1" - "@typescript-eslint/type-utils" "8.39.1" - "@typescript-eslint/utils" "8.39.1" - "@typescript-eslint/visitor-keys" "8.39.1" - graphemer "^1.4.0" - ignore "^7.0.0" - natural-compare "^1.4.0" - ts-api-utils "^2.1.0" - "@typescript-eslint/parser@7.18.0", "@typescript-eslint/parser@^7.13.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.18.0.tgz#83928d0f1b7f4afa974098c64b5ce6f9051f96a0" @@ -3044,26 +3026,6 @@ "@typescript-eslint/visitor-keys" "7.18.0" debug "^4.3.4" -"@typescript-eslint/parser@^8.37.0": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.39.1.tgz#7f8f9ecfc7e172d67e42c366fa198e42324e5d50" - integrity sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg== - dependencies: - "@typescript-eslint/scope-manager" "8.39.1" - "@typescript-eslint/types" "8.39.1" - "@typescript-eslint/typescript-estree" "8.39.1" - "@typescript-eslint/visitor-keys" "8.39.1" - debug "^4.3.4" - -"@typescript-eslint/project-service@8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.39.1.tgz#63525878d488ebf27c485f295e83434a1398f52d" - integrity sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw== - dependencies: - "@typescript-eslint/tsconfig-utils" "^8.39.1" - "@typescript-eslint/types" "^8.39.1" - debug "^4.3.4" - "@typescript-eslint/scope-manager@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" @@ -3072,19 +3034,6 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/visitor-keys" "7.18.0" -"@typescript-eslint/scope-manager@8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.39.1.tgz#1253fe3e1f2f33f08a3e438a05b5dd7faf9fbca6" - integrity sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw== - dependencies: - "@typescript-eslint/types" "8.39.1" - "@typescript-eslint/visitor-keys" "8.39.1" - -"@typescript-eslint/tsconfig-utils@8.39.1", "@typescript-eslint/tsconfig-utils@^8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.1.tgz#17f13b4ad481e7bec7c249ee1854078645b34b12" - integrity sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA== - "@typescript-eslint/type-utils@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" @@ -3095,27 +3044,11 @@ debug "^4.3.4" ts-api-utils "^1.3.0" -"@typescript-eslint/type-utils@8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.39.1.tgz#642f9fb96173649e2928fea0375b1d74d31906c2" - integrity sha512-gu9/ahyatyAdQbKeHnhT4R+y3YLtqqHyvkfDxaBYk97EcbfChSJXyaJnIL3ygUv7OuZatePHmQvuH5ru0lnVeA== - dependencies: - "@typescript-eslint/types" "8.39.1" - "@typescript-eslint/typescript-estree" "8.39.1" - "@typescript-eslint/utils" "8.39.1" - debug "^4.3.4" - ts-api-utils "^2.1.0" - "@typescript-eslint/types@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== -"@typescript-eslint/types@8.39.1", "@typescript-eslint/types@^8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.39.1.tgz#f0ab996c8ab2c3b046bbf86bb1990b03529869a1" - integrity sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw== - "@typescript-eslint/typescript-estree@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" @@ -3130,22 +3063,6 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/typescript-estree@8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.1.tgz#8825d3ea7ea2144c577859ae489eec24ef7318a5" - integrity sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw== - dependencies: - "@typescript-eslint/project-service" "8.39.1" - "@typescript-eslint/tsconfig-utils" "8.39.1" - "@typescript-eslint/types" "8.39.1" - "@typescript-eslint/visitor-keys" "8.39.1" - debug "^4.3.4" - fast-glob "^3.3.2" - is-glob "^4.0.3" - minimatch "^9.0.4" - semver "^7.6.0" - ts-api-utils "^2.1.0" - "@typescript-eslint/utils@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" @@ -3156,16 +3073,6 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/typescript-estree" "7.18.0" -"@typescript-eslint/utils@8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.39.1.tgz#58a834f89f93b786ada2cd14d77fa63c3c8f408b" - integrity sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg== - dependencies: - "@eslint-community/eslint-utils" "^4.7.0" - "@typescript-eslint/scope-manager" "8.39.1" - "@typescript-eslint/types" "8.39.1" - "@typescript-eslint/typescript-estree" "8.39.1" - "@typescript-eslint/visitor-keys@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" @@ -3174,58 +3081,11 @@ "@typescript-eslint/types" "7.18.0" eslint-visitor-keys "^3.4.3" -"@typescript-eslint/visitor-keys@8.39.1": - version "8.39.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.1.tgz#a467742a98f2fa3c03d7bed4979dc0db3850a77a" - integrity sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A== - dependencies: - "@typescript-eslint/types" "8.39.1" - eslint-visitor-keys "^4.2.1" - "@ungap/structured-clone@^1.2.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== -"@wasm-audio-decoders/common@9.0.7": - version "9.0.7" - resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/common/-/common-9.0.7.tgz#3210cdd77893a51fbb205f15dc0e56293e2074b5" - integrity sha512-WRaUuWSKV7pkttBygml/a6dIEpatq2nnZGFIoPTc5yPLkxL6Wk4YaslPM98OPQvWacvNZ+Py9xROGDtrFBDzag== - dependencies: - "@eshaz/web-worker" "1.2.2" - simple-yenc "^1.0.4" - -"@wasm-audio-decoders/flac@^0.2.4": - version "0.2.8" - resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/flac/-/flac-0.2.8.tgz#fe8ac627d6132437a15467d3840d128b7466b3bf" - integrity sha512-CxvylHiUmtCrf0hUSzYQlD9RtoY/LsPuKR8M6ZjtQrXHzSLir0whWjPs1yb+hDZdK8R1NbESHcz2ZV88eMcKUg== - dependencies: - "@wasm-audio-decoders/common" "9.0.7" - codec-parser "2.5.0" - -"@wasm-audio-decoders/ogg-vorbis@^0.1.15": - version "0.1.18" - resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/ogg-vorbis/-/ogg-vorbis-0.1.18.tgz#c380cf1025f5b45b123d84f389215a6f9ca8c187" - integrity sha512-kEg6b5vW4wAXfGAqe5wzvSuAs2FEhPY/rniYF/Gx3rgxQcPiRI86SBAyIRWFJ7O4CY/JJHX57B1OCDueMlBSLQ== - dependencies: - "@wasm-audio-decoders/common" "9.0.7" - codec-parser "2.5.0" - -"@wasm-audio-decoders/opus-ml@0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/opus-ml/-/opus-ml-0.0.1.tgz#5966904b1d0428de8ee9ef144ef2182dc1ad145b" - integrity sha512-FALuUCz10HS2h8KB4L7wmfXncOuBDFvlKRk6Ga2rw8sr/zNIpwCjhhomxH4JKPhVLOnBjZfrPa8aTFIQq74vzQ== - dependencies: - "@wasm-audio-decoders/common" "9.0.7" - -"@whiskeysockets/eslint-config@github:whiskeysockets/eslint-config": - version "1.0.0" - resolved "https://codeload.github.com/whiskeysockets/eslint-config/tar.gz/299e8389baf62f9aa3034de18ff0d62cc0a5e838" - dependencies: - "@typescript-eslint/eslint-plugin" "^8.37.0" - "@typescript-eslint/parser" "^8.37.0" - eslint-plugin-simple-import-sort "^12.1.1" - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -3384,11 +3244,6 @@ asap@^2.0.0: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== -async-lock@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.4.1.tgz#56b8718915a9b68b10fce2f2a9a3dddf765ef53f" - integrity sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ== - async-mutex@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.5.0.tgz#353c69a0b9e75250971a64ac203b0ebfddd75482" @@ -3406,30 +3261,6 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== -audio-buffer@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/audio-buffer/-/audio-buffer-5.0.0.tgz#92129984ebdbb8ad1c4ec6fd81525a0e0a29e99e" - integrity sha512-gsDyj1wwUp8u7NBB+eW6yhLb9ICf+0eBmDX8NGaAS00w8/fLqFdxUlL5Ge/U8kB64DlQhdonxYC59dXy1J7H/w== - -audio-decode@^2.1.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/audio-decode/-/audio-decode-2.2.3.tgz#147ae56fe3e758f0f63ea9a124af42bdee6fd6dc" - integrity sha512-Z0lHvMayR/Pad9+O9ddzaBJE0DrhZkQlStrC1RwcAHF3AhQAsdwKHeLGK8fYKyp2DDU6xHxzGb4CLMui12yVrg== - dependencies: - "@wasm-audio-decoders/flac" "^0.2.4" - "@wasm-audio-decoders/ogg-vorbis" "^0.1.15" - audio-buffer "^5.0.0" - audio-type "^2.2.1" - mpg123-decoder "^1.0.0" - node-wav "^0.0.2" - ogg-opus-decoder "^1.6.12" - qoa-format "^1.0.1" - -audio-type@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/audio-type/-/audio-type-2.2.1.tgz#5ceae0b0b3cf3b1e117edabb9e5332eaf3bd4f25" - integrity sha512-En9AY6EG1qYqEy5L/quryzbA4akBpJrnBZNxeKTqGHC2xT9Qc4aZ8b7CcbOMFTTc/MGdoNyp+SN4zInZNKxMYA== - awesome-phonenumber@^6.8.0: version "6.12.0" resolved "https://registry.yarnpkg.com/awesome-phonenumber/-/awesome-phonenumber-6.12.0.tgz#333cc3b393490dfa2b2c3b4461b442dad52d5af3" @@ -3507,41 +3338,16 @@ babel-preset-jest@^29.6.3: babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" -baileys@^6.7.19-alpha.0: - version "6.17.16" - resolved "https://registry.yarnpkg.com/baileys/-/baileys-6.17.16.tgz#6299a7a06867d7acafe49e19f6e88e8d2c8afbff" - integrity sha512-5dLjZ6+yRR4K7u56xKGCOsLPu5o7PrfLpAW0wV3WELpQQ6m33xwFK+Jd6hu+xDSVfMr7SqP2Dn0jqj+zH8ymdw== - dependencies: - "@adiwajshing/keyed-db" "^0.2.4" - "@cacheable/node-cache" "^1.4.0" - "@hapi/boom" "^9.1.3" - "@whiskeysockets/eslint-config" "github:whiskeysockets/eslint-config" - async-lock "^1.4.1" - audio-decode "^2.1.3" - axios "^1.6.0" - cache-manager "^5.7.6" - libphonenumber-js "^1.10.20" - libsignal "github:WhiskeySockets/libsignal-node" - lodash "^4.17.21" - music-metadata "^7.12.3" - pino "^9.6" - protobufjs "^7.2.4" - uuid "^10.0.0" - ws "^8.13.0" - -baileys@^6.7.8: +baileys@^6.7.8, "baileys@github:WhiskeySockets/Baileys": version "6.7.18" - resolved "https://registry.yarnpkg.com/baileys/-/baileys-6.7.18.tgz#4169791f44666b27b9507f7fe46afb830f0b1c99" - integrity sha512-o90lVPkzAKCw10Ui1mhFxAUJn/Yn/RkB4jgHlFFtIXwB3L3oxOK58jbJdLvVIf3jxpDmGOQqtqu/JEnZc3mrTg== + resolved "https://codeload.github.com/WhiskeySockets/Baileys/tar.gz/be3d869cae5866ccf512de0364db01e188b34fac" dependencies: "@cacheable/node-cache" "^1.4.0" "@hapi/boom" "^9.1.3" - "@whiskeysockets/eslint-config" "github:whiskeysockets/eslint-config" async-mutex "^0.5.0" axios "^1.6.0" - libsignal "github:WhiskeySockets/libsignal-node" - lodash "^4.17.21" - music-metadata "^7.12.3" + libsignal "git+https://github.com/whiskeysockets/libsignal-node" + music-metadata "^11.7.0" pino "^9.6" protobufjs "^7.2.4" ws "^8.13.0" @@ -3691,16 +3497,6 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cache-manager@^5.7.6: - version "5.7.6" - resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-5.7.6.tgz#bdd8a154c73e5233824aa09ceb359ed225d37b7e" - integrity sha512-wBxnBHjDxF1RXpHCBD6HGvKER003Ts7IIm0CHpggliHzN1RZditb7rXoduE1rplc2DEFYKxhLKgFuchXMJje9w== - dependencies: - eventemitter3 "^5.0.1" - lodash.clonedeep "^4.5.0" - lru-cache "^10.2.2" - promise-coalesce "^1.1.2" - cacheable@^1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/cacheable/-/cacheable-1.10.3.tgz#8dcb02081a10c4819a8d70e1251bcce0ee5afdd4" @@ -3746,9 +3542,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001733: - version "1.0.30001734" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001734.tgz#f97e08599e2d75664543ae4b6ef25dc2183c5cc6" - integrity sha512-uhE1Ye5vgqju6OI71HTQqcBCZrvHugk0MjLak7Q+HfoBgoq5Bi+5YnwjP4fjDgrtYr/l8MVRBvzz9dPD4KyK0A== + version "1.0.30001735" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz#ba658fd3fd24a4106fd68d5ce472a2c251494dbe" + integrity sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w== centra@^2.7.0: version "2.7.0" @@ -3871,11 +3667,6 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== -codec-parser@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/codec-parser/-/codec-parser-2.5.0.tgz#213f224dcf029854682a532a41d2d433ddda4d3e" - integrity sha512-Ru9t80fV8B0ZiixQl8xhMTLru+dzuis/KQld32/x5T/+3LwZb0/YvQdSKytX9JqCnRdiupvAvyYJINKrXieziQ== - codepage@~1.15.0: version "1.15.0" resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab" @@ -4065,7 +3856,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7: +debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7, debug@^4.4.0, debug@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== @@ -4240,9 +4031,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.5.199: - version "1.5.200" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.200.tgz#adffa5db97390ce9d48987f528117a608ed0d7c9" - integrity sha512-rFCxROw7aOe4uPTfIAx+rXv9cEcGx+buAF4npnhtTqCJk5KDFRnh3+KYj7rdVh6lsFt5/aPs+Irj9rZ33WMA7w== + version "1.5.201" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.201.tgz#bdc8f13e828e2f65d2c925ab2e8b02604928632f" + integrity sha512-ZG65vsrLClodGqywuigc+7m0gr4ISoTQttfVh7nfpLv0M7SIwF4WbFNEOywcqTiujs12AUeeXbFyQieDICAIxg== emittery@^0.13.1: version "0.13.1" @@ -4383,11 +4174,6 @@ eslint-plugin-prettier@^4.2.1: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-simple-import-sort@^12.1.1: - version "12.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz#e64bfdaf91c5b98a298619aa634a9f7aa43b709e" - integrity sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA== - eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" @@ -4401,11 +4187,6 @@ eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint-visitor-keys@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" - integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== - eslint@^8.56.0: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" @@ -4498,11 +4279,6 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" - integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== - events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -4596,7 +4372,7 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.9, fast-glob@^3.3.2: +fast-glob@^3.2.9: version "3.3.3" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== @@ -4653,6 +4429,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fflate@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" + integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4669,6 +4450,16 @@ file-type@^16.5.4: strtok3 "^6.2.4" token-types "^4.1.1" +file-type@^21.0.0: + version "21.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-21.0.0.tgz#b6c5990064bc4b704f8e5c9b6010c59064d268bc" + integrity sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg== + dependencies: + "@tokenizer/inflate" "^0.2.7" + strtok3 "^10.2.2" + token-types "^6.0.0" + uint8array-extras "^1.4.0" + fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -5120,11 +4911,6 @@ ignore@^5.2.0, ignore@^5.3.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== -ignore@^7.0.0: - version "7.0.5" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" - integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== - image-q@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/image-q/-/image-q-4.0.0.tgz#31e075be7bae3c1f42a85c469b4732c358981776" @@ -5827,14 +5613,9 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -libphonenumber-js@^1.10.20: - version "1.12.10" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.10.tgz#525f7c9ffaea40c21463d3906f52ec3209ea5945" - integrity sha512-E91vHJD61jekHHR/RF/E83T/CMoaLXT7cwYA75T4gim4FZjnM6hbJjVIGg7chqlSqRsSvQ3izGmOjHy1SQzcGQ== - -"libsignal@github:WhiskeySockets/libsignal-node": +"libsignal@git+https://github.com/whiskeysockets/libsignal-node": version "2.0.1" - resolved "https://codeload.github.com/WhiskeySockets/libsignal-node/tar.gz/4d08331a833727c338c1a90041d17b870210dfae" + resolved "git+https://github.com/whiskeysockets/libsignal-node#4d08331a833727c338c1a90041d17b870210dfae" dependencies: curve25519-js "^0.0.4" protobufjs "6.8.8" @@ -5885,11 +5666,6 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -5900,11 +5676,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" @@ -5915,11 +5686,6 @@ long@^5.0.0: resolved "https://registry.yarnpkg.com/long/-/long-5.3.2.tgz#1d84463095999262d7d7b7f8bfd4a8cc55167f83" integrity sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA== -lru-cache@^10.2.2: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -6067,13 +5833,6 @@ moo@^0.5.1: resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.2.tgz#f9fe82473bc7c184b0d32e2215d3f6e67278733c" integrity sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q== -mpg123-decoder@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/mpg123-decoder/-/mpg123-decoder-1.0.2.tgz#4f6879ea46c2af489834f1c799e1a34cb42b0c3e" - integrity sha512-cw0Laz57gumQsfCqnNeGtgq64EcyrK/z4qx+kq4iba7iSSXfI7uO3jiHjdHxNp4PB2v08VZYZ2Fr68VM1JkaPQ== - dependencies: - "@wasm-audio-decoders/common" "9.0.7" - mri@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" @@ -6089,18 +5848,19 @@ ms@2.1.3, ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -music-metadata@^7.12.3: - version "7.14.0" - resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-7.14.0.tgz#74e3e5fc8e09b86d1a3e791fb5ce9ccdc4347ad9" - integrity sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA== +music-metadata@^11.7.0: + version "11.8.2" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-11.8.2.tgz#61053b956d31eae479f6c045210d559ed8fc583d" + integrity sha512-k7fxn9GCl27b+P+suLwMuEuS1Kft32P1jBZ/MXLh5iRTll60qbWWc/hh+Xvv70khyykcGwsVzddURzLdKymZ0g== dependencies: + "@borewit/text-codec" "^0.1.0" "@tokenizer/token" "^0.3.0" content-type "^1.0.5" - debug "^4.3.4" - file-type "^16.5.4" + debug "^4.4.1" + file-type "^21.0.0" media-typer "^1.1.0" - strtok3 "^6.3.0" - token-types "^4.2.1" + strtok3 "^10.3.4" + token-types "^6.1.1" mustache@^4.2.0: version "4.2.0" @@ -6146,11 +5906,6 @@ node-releases@^2.0.19: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== -node-wav@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/node-wav/-/node-wav-0.0.2.tgz#89cb63cf8cd66ec8ab455f5ba4864e5fcb4605e8" - integrity sha512-M6Rm/bbG6De/gKGxOpeOobx/dnGuP0dz40adqx38boqHhlWssBJZgLCPBNtb9NkrmnKYiV04xELq+R6PFOnoLA== - node-xlsx@^0.24.0: version "0.24.0" resolved "https://registry.yarnpkg.com/node-xlsx/-/node-xlsx-0.24.0.tgz#a6a365acb18ad37c66c2b254b6ebe0c22dc9dc6f" @@ -6208,16 +5963,6 @@ object-inspect@^1.13.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== -ogg-opus-decoder@^1.6.12: - version "1.7.0" - resolved "https://registry.yarnpkg.com/ogg-opus-decoder/-/ogg-opus-decoder-1.7.0.tgz#bf4db9918c6a003382ed2aedbbf1e1dd4e2ca7a4" - integrity sha512-/lrj4+ZGjxZCCNiDSlNEckLrCL+UU9N9XtqES7sXq/Lm6PMi8Pwn/D6TTsbvG45krt21ohAh2FqdEsMuI7ZN4w== - dependencies: - "@wasm-audio-decoders/common" "9.0.7" - "@wasm-audio-decoders/opus-ml" "0.0.1" - codec-parser "2.5.0" - opus-decoder "0.7.10" - omggif@^1.0.10, omggif@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -6266,13 +6011,6 @@ optionator@^0.9.3: type-check "^0.4.0" word-wrap "^1.2.5" -opus-decoder@0.7.10: - version "0.7.10" - resolved "https://registry.yarnpkg.com/opus-decoder/-/opus-decoder-0.7.10.tgz#a075cb4e6f0d4692fd918615321de6147a5c022e" - integrity sha512-qUZdyAK+kKy/wUSd/oZ0ULE9U/yskp332n2oBvSP/Jz/wHsHiVRg33f/tRUR8TRiw+ka7AQUclxcr5TbUJo+VA== - dependencies: - "@wasm-audio-decoders/common" "9.0.7" - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -6506,9 +6244,9 @@ pino@^7.0.0: thread-stream "^0.15.1" pino@^9.6: - version "9.8.0" - resolved "https://registry.yarnpkg.com/pino/-/pino-9.8.0.tgz#8730b8ff2e1b94ef3691666ee067f7352fef1de8" - integrity sha512-L5+rV1wL7vGAcxXP7sPpN5lrJ07Piruka6ArXr7EWBXxdVWjJshGVX8suFsiusJVcGKDGUFfbgbnKdg+VAC+0g== + version "9.9.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-9.9.0.tgz#0d2667ab4a54b561a4434a321ec595f305ab9cd1" + integrity sha512-zxsRIQG9HzG+jEljmvmZupOMDUQ0Jpj0yAgE28jQvvrdYTlEaiGwelJpdndMl/MBuRr70heIj83QyqJUWaU8mQ== dependencies: atomic-sleep "^1.0.0" fast-redact "^3.1.1" @@ -6619,11 +6357,6 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -promise-coalesce@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/promise-coalesce/-/promise-coalesce-1.1.2.tgz#5d3bc4d0b2cf2e41e9df7cbeb6519b2a09459e3d" - integrity sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg== - promise-polyfill@^8.1.3: version "8.3.0" resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.3.0.tgz#9284810268138d103807b11f4e23d5e945a4db63" @@ -6722,13 +6455,6 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== -qoa-format@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/qoa-format/-/qoa-format-1.0.1.tgz#fb438b4757173e68b6e6baab316835e134ce0bca" - integrity sha512-dMB0Z6XQjdpz/Cw4Rf6RiBpQvUSPCfYlQMWvmuWlWkAT7nDQD29cVZ1SwDUB6DYJSitHENwbt90lqfI+7bvMcw== - dependencies: - "@thi.ng/bitstream" "^2.2.12" - qrcode-terminal@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" @@ -7128,11 +6854,6 @@ simple-update-notifier@^2.0.0: dependencies: semver "^7.5.3" -simple-yenc@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/simple-yenc/-/simple-yenc-1.0.4.tgz#52805f504ec03c0aafe3766eee901e4e6f352ead" - integrity sha512-5gvxpSd79e9a3V4QDYUqnqxeD4HGlhCakVpb6gMnDD7lexJggSBJRBO5h52y/iJrdXRilX9UCuDaIJhSWm5OWw== - sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -7341,7 +7062,14 @@ strnum@^2.1.0: resolved "https://registry.yarnpkg.com/strnum/-/strnum-2.1.1.tgz#cf2a6e0cf903728b8b2c4b971b7e36b4e82d46ab" integrity sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw== -strtok3@^6.2.4, strtok3@^6.3.0: +strtok3@^10.2.2, strtok3@^10.3.4: + version "10.3.4" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.3.4.tgz#793ebd0d59df276a085586134b73a406e60be9c1" + integrity sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg== + dependencies: + "@tokenizer/token" "^0.3.0" + +strtok3@^6.2.4: version "6.3.0" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== @@ -7469,7 +7197,7 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -token-types@^4.1.1, token-types@^4.2.1: +token-types@^4.1.1: version "4.2.1" resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== @@ -7477,6 +7205,15 @@ token-types@^4.1.1, token-types@^4.2.1: "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" +token-types@^6.0.0, token-types@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.1.1.tgz#85bd0ada82939b9178ecd5285881a538c4c00fdd" + integrity sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ== + dependencies: + "@borewit/text-codec" "^0.1.0" + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + touch@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694" @@ -7497,11 +7234,6 @@ ts-api-utils@^1.3.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== -ts-api-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" - integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== - ts-essentials@^10.0.0: version "10.1.1" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-10.1.1.tgz#4e1d29b7c9b33c1a2744482376634c4fafba5210" @@ -7626,6 +7358,11 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== +uint8array-extras@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.4.1.tgz#6d6e88363a414577c133aca1e63b2a6c5524be21" + integrity sha512-+NWHrac9dvilNgme+gP4YrBSumsaMZP0fNBtXXFIf33RLLKEcBUKaQZ7ULUbS0sBfcjxIZ4V96OTRkCbM7hxpw== + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" @@ -7694,11 +7431,6 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" - integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== - uuid@^9.0.0, uuid@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" From 0d22c3249dfe0ef06bdf7a223276cae7c905b583 Mon Sep 17 00:00:00 2001 From: Moises Batista Date: Thu, 14 Aug 2025 18:44:02 -0300 Subject: [PATCH 17/21] Revert "Update dependencies in `yarn.lock` for Babel, Sentry, and other packages" This reverts commit 4fe64356d1a7bdc2501f79525632ea46360174a8. --- package.json | 4 +- yarn.lock | 538 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 405 insertions(+), 137 deletions(-) diff --git a/package.json b/package.json index aa7130c6..b24bf163 100644 --- a/package.json +++ b/package.json @@ -78,11 +78,11 @@ "@aws-sdk/client-s3": "^3.598.0", "@aws-sdk/s3-request-presigner": "^3.598.0", "@google-cloud/text-to-speech": "^5.2.0", - "@redis/client": "^1.5.14", + "@redis/client": "^1.5.14", "@sentry/node": "^9.29.0", "amqplib": "^0.10.8", "awesome-phonenumber": "^6.8.0", - "baileys": "github:WhiskeySockets/Baileys", + "baileys": "^6.7.19-alpha.0", "dotenv": "^16.4.5", "express": "^4.19.2", "i18n": "^0.15.1", diff --git a/yarn.lock b/yarn.lock index 9638a18d..3b234929 100644 --- a/yarn.lock +++ b/yarn.lock @@ -618,33 +618,33 @@ integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.3.tgz#aceddde69c5d1def69b839d09efa3e3ff59c97cb" - integrity sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ== + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.0.tgz#55dad808d5bf3445a108eefc88ea3fdf034749a4" + integrity sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.3" + "@babel/generator" "^7.28.0" "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-module-transforms" "^7.28.3" - "@babel/helpers" "^7.28.3" - "@babel/parser" "^7.28.3" + "@babel/helper-module-transforms" "^7.27.3" + "@babel/helpers" "^7.27.6" + "@babel/parser" "^7.28.0" "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.3" - "@babel/types" "^7.28.2" + "@babel/traverse" "^7.28.0" + "@babel/types" "^7.28.0" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.28.3", "@babel/generator@^7.7.2": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e" - integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw== +"@babel/generator@^7.28.0", "@babel/generator@^7.7.2": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2" + integrity sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg== dependencies: - "@babel/parser" "^7.28.3" - "@babel/types" "^7.28.2" + "@babel/parser" "^7.28.0" + "@babel/types" "^7.28.0" "@jridgewell/gen-mapping" "^0.3.12" "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" @@ -673,14 +673,14 @@ "@babel/traverse" "^7.27.1" "@babel/types" "^7.27.1" -"@babel/helper-module-transforms@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" - integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== +"@babel/helper-module-transforms@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz#db0bbcfba5802f9ef7870705a7ef8788508ede02" + integrity sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg== dependencies: "@babel/helper-module-imports" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.28.3" + "@babel/traverse" "^7.27.3" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": version "7.27.1" @@ -702,20 +702,20 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== -"@babel/helpers@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.3.tgz#b83156c0a2232c133d1b535dd5d3452119c7e441" - integrity sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw== +"@babel/helpers@^7.27.6": + version "7.28.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.2.tgz#80f0918fecbfebea9af856c419763230040ee850" + integrity sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw== dependencies: "@babel/template" "^7.27.2" "@babel/types" "^7.28.2" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.3.tgz#d2d25b814621bca5fe9d172bc93792547e7a2a71" - integrity sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e" + integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== dependencies: - "@babel/types" "^7.28.2" + "@babel/types" "^7.28.0" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -845,20 +845,20 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.3.tgz#6911a10795d2cce43ec6a28cffc440cca2593434" - integrity sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ== +"@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.0.tgz#518aa113359b062042379e333db18380b537e34b" + integrity sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg== dependencies: "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.3" + "@babel/generator" "^7.28.0" "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.28.3" + "@babel/parser" "^7.28.0" "@babel/template" "^7.27.2" - "@babel/types" "^7.28.2" + "@babel/types" "^7.28.0" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.28.2", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.28.0", "@babel/types@^7.28.2", "@babel/types@^7.3.3": version "7.28.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b" integrity sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ== @@ -871,11 +871,6 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@borewit/text-codec@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@borewit/text-codec/-/text-codec-0.1.1.tgz#7e7f27092473d5eabcffef693a849f2cc48431da" - integrity sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA== - "@cacheable/node-cache@^1.4.0": version "1.6.1" resolved "https://registry.yarnpkg.com/@cacheable/node-cache/-/node-cache-1.6.1.tgz#8e845eea011518ab96999a4c893e273812eeb00f" @@ -899,7 +894,12 @@ dependencies: tslib "^2.4.0" -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": +"@eshaz/web-worker@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@eshaz/web-worker/-/web-worker-1.2.2.tgz#506ec07ab811c15a12799725a0d8b82289e3d937" + integrity sha512-WxXiHFmD9u/owrzempiDlBB1ZYqiLnm9s6aPc8AlFQalq2tKmqdmMr9GXOupDgzXtqnBipj8Un0gkIm7Sjf8mw== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.7.0": version "4.7.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a" integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw== @@ -2035,24 +2035,24 @@ generic-pool "3.9.0" yallist "4.0.0" -"@sentry/core@9.46.0": - version "9.46.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-9.46.0.tgz#be4824d8b028b3184f9a05be9b232c9440cb35ac" - integrity sha512-it7JMFqxVproAgEtbLgCVBYtQ9fIb+Bu0JD+cEplTN/Ukpe6GaolyYib5geZqslVxhp2sQgT+58aGvfd/k0N8Q== +"@sentry/core@9.45.0": + version "9.45.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-9.45.0.tgz#bc73bb327f84a410c7d51d1518210c87d995f4da" + integrity sha512-yTpB53fBEWTMzltD/8f/qI2MFTwgd2vSkn7pOZQusSOMtyt0Bsm/77oqXldIt+eMBAImZalzZaxmaN7RyiRKWQ== -"@sentry/node-core@9.46.0": - version "9.46.0" - resolved "https://registry.yarnpkg.com/@sentry/node-core/-/node-core-9.46.0.tgz#baece79aad97d2ccc562547bf5b073b4f18e01c6" - integrity sha512-XRVu5pqoklZeh4wqhxCLZkz/ipoKhitctgEFXX9Yh1e1BoHM2pIxT52wf+W6hHM676TFmFXW3uKBjsmRM3AjgA== +"@sentry/node-core@9.45.0": + version "9.45.0" + resolved "https://registry.yarnpkg.com/@sentry/node-core/-/node-core-9.45.0.tgz#6dc8a25390f884d0c016c9ab6c68114d1e4219c9" + integrity sha512-tzt60LO7P1m+0OLEqtL5Fd71PwKpg7dSOn3rqB7T6AJeDDiHsXV/yhUZiye1EWHTi0/yOcb0M1Ncjs8Cdyz9Nw== dependencies: - "@sentry/core" "9.46.0" - "@sentry/opentelemetry" "9.46.0" + "@sentry/core" "9.45.0" + "@sentry/opentelemetry" "9.45.0" import-in-the-middle "^1.14.2" "@sentry/node@^9.29.0": - version "9.46.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-9.46.0.tgz#d9e9553ad77b8e741b3fbc2ccbf3c458adf1b2e2" - integrity sha512-pRLqAcd7GTGvN8gex5FtkQR5Mcol8gOy1WlyZZFq4rBbVtMbqKOQRhohwqnb+YrnmtFpj7IZ7KNDo077MvNeOQ== + version "9.45.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-9.45.0.tgz#4b9f213966bed4d58956d274a500045f3e7f8a9b" + integrity sha512-c0SFcMeZwxLvjC1HrutI8V+Ag8AxENXPiU5PbSmqiTX7p4QnByTcxkENGw5EyLedDZluuEDmmHTBKckCC4X2nA== dependencies: "@opentelemetry/api" "^1.9.0" "@opentelemetry/context-async-hooks" "^1.30.1" @@ -2084,18 +2084,18 @@ "@opentelemetry/sdk-trace-base" "^1.30.1" "@opentelemetry/semantic-conventions" "^1.34.0" "@prisma/instrumentation" "6.11.1" - "@sentry/core" "9.46.0" - "@sentry/node-core" "9.46.0" - "@sentry/opentelemetry" "9.46.0" + "@sentry/core" "9.45.0" + "@sentry/node-core" "9.45.0" + "@sentry/opentelemetry" "9.45.0" import-in-the-middle "^1.14.2" minimatch "^9.0.0" -"@sentry/opentelemetry@9.46.0": - version "9.46.0" - resolved "https://registry.yarnpkg.com/@sentry/opentelemetry/-/opentelemetry-9.46.0.tgz#a8567c09dbb417cfd3089a57bf0e118bead353b6" - integrity sha512-w2zTxqrdmwRok0cXBoh+ksXdGRUHUZhlpfL/H2kfTodOL+Mk8rW72qUmfqQceXoqgbz8UyK8YgJbyt+XS5H4Qg== +"@sentry/opentelemetry@9.45.0": + version "9.45.0" + resolved "https://registry.yarnpkg.com/@sentry/opentelemetry/-/opentelemetry-9.45.0.tgz#861dcceee3f9326679d533897345f5e050616f7d" + integrity sha512-xLH7ZH6xcZBHK77mTa32YjIEL92jmc7i2qkxlchzTNacmTn9BNnuzPFBS7KuISJPXw9R1pXBra6IVEhm6hil/g== dependencies: - "@sentry/core" "9.46.0" + "@sentry/core" "9.45.0" "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -2616,14 +2616,17 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== -"@tokenizer/inflate@^0.2.7": - version "0.2.7" - resolved "https://registry.yarnpkg.com/@tokenizer/inflate/-/inflate-0.2.7.tgz#32dd9dfc9abe457c89b3d9b760fc0690c85a103b" - integrity sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg== +"@thi.ng/bitstream@^2.2.12": + version "2.4.27" + resolved "https://registry.yarnpkg.com/@thi.ng/bitstream/-/bitstream-2.4.27.tgz#d9a2dbe4d283bc715c1d08faba472e2e7c8ec62f" + integrity sha512-ZPv6CUqQf8YzxNtBFNPXwrY2gfPq2FWLuhBGhg7XXKAzClIOEg/1pCrSzl7rkd9d8BjLhlpj9ZaqAj6Wxs9HFg== dependencies: - debug "^4.4.0" - fflate "^0.8.2" - token-types "^6.0.0" + "@thi.ng/errors" "^2.5.41" + +"@thi.ng/errors@^2.5.41": + version "2.5.41" + resolved "https://registry.yarnpkg.com/@thi.ng/errors/-/errors-2.5.41.tgz#3102ac2070c7bb6b19edd90606e6cb84fb20d4ed" + integrity sha512-NyOIo+1ovKvLkNk8qVIfo6aXqfXPdNo+TO1Z47UYP7RkTl9fDoQM6Thqkuq82I+YoL2WsdRvt8IcWjoVqwUH3A== "@tokenizer/token@^0.3.0": version "0.3.0" @@ -3015,6 +3018,21 @@ natural-compare "^1.4.0" ts-api-utils "^1.3.0" +"@typescript-eslint/eslint-plugin@^8.37.0": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.1.tgz#28dffcb5272d20afe250bfeec3173263db5528a0" + integrity sha512-yYegZ5n3Yr6eOcqgj2nJH8cH/ZZgF+l0YIdKILSDjYFRjgYQMgv/lRjV5Z7Up04b9VYUondt8EPMqg7kTWgJ2g== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.39.1" + "@typescript-eslint/type-utils" "8.39.1" + "@typescript-eslint/utils" "8.39.1" + "@typescript-eslint/visitor-keys" "8.39.1" + graphemer "^1.4.0" + ignore "^7.0.0" + natural-compare "^1.4.0" + ts-api-utils "^2.1.0" + "@typescript-eslint/parser@7.18.0", "@typescript-eslint/parser@^7.13.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.18.0.tgz#83928d0f1b7f4afa974098c64b5ce6f9051f96a0" @@ -3026,6 +3044,26 @@ "@typescript-eslint/visitor-keys" "7.18.0" debug "^4.3.4" +"@typescript-eslint/parser@^8.37.0": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.39.1.tgz#7f8f9ecfc7e172d67e42c366fa198e42324e5d50" + integrity sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg== + dependencies: + "@typescript-eslint/scope-manager" "8.39.1" + "@typescript-eslint/types" "8.39.1" + "@typescript-eslint/typescript-estree" "8.39.1" + "@typescript-eslint/visitor-keys" "8.39.1" + debug "^4.3.4" + +"@typescript-eslint/project-service@8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.39.1.tgz#63525878d488ebf27c485f295e83434a1398f52d" + integrity sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw== + dependencies: + "@typescript-eslint/tsconfig-utils" "^8.39.1" + "@typescript-eslint/types" "^8.39.1" + debug "^4.3.4" + "@typescript-eslint/scope-manager@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" @@ -3034,6 +3072,19 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/visitor-keys" "7.18.0" +"@typescript-eslint/scope-manager@8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.39.1.tgz#1253fe3e1f2f33f08a3e438a05b5dd7faf9fbca6" + integrity sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw== + dependencies: + "@typescript-eslint/types" "8.39.1" + "@typescript-eslint/visitor-keys" "8.39.1" + +"@typescript-eslint/tsconfig-utils@8.39.1", "@typescript-eslint/tsconfig-utils@^8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.1.tgz#17f13b4ad481e7bec7c249ee1854078645b34b12" + integrity sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA== + "@typescript-eslint/type-utils@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" @@ -3044,11 +3095,27 @@ debug "^4.3.4" ts-api-utils "^1.3.0" +"@typescript-eslint/type-utils@8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.39.1.tgz#642f9fb96173649e2928fea0375b1d74d31906c2" + integrity sha512-gu9/ahyatyAdQbKeHnhT4R+y3YLtqqHyvkfDxaBYk97EcbfChSJXyaJnIL3ygUv7OuZatePHmQvuH5ru0lnVeA== + dependencies: + "@typescript-eslint/types" "8.39.1" + "@typescript-eslint/typescript-estree" "8.39.1" + "@typescript-eslint/utils" "8.39.1" + debug "^4.3.4" + ts-api-utils "^2.1.0" + "@typescript-eslint/types@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== +"@typescript-eslint/types@8.39.1", "@typescript-eslint/types@^8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.39.1.tgz#f0ab996c8ab2c3b046bbf86bb1990b03529869a1" + integrity sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw== + "@typescript-eslint/typescript-estree@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" @@ -3063,6 +3130,22 @@ semver "^7.6.0" ts-api-utils "^1.3.0" +"@typescript-eslint/typescript-estree@8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.1.tgz#8825d3ea7ea2144c577859ae489eec24ef7318a5" + integrity sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw== + dependencies: + "@typescript-eslint/project-service" "8.39.1" + "@typescript-eslint/tsconfig-utils" "8.39.1" + "@typescript-eslint/types" "8.39.1" + "@typescript-eslint/visitor-keys" "8.39.1" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^2.1.0" + "@typescript-eslint/utils@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" @@ -3073,6 +3156,16 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/typescript-estree" "7.18.0" +"@typescript-eslint/utils@8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.39.1.tgz#58a834f89f93b786ada2cd14d77fa63c3c8f408b" + integrity sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg== + dependencies: + "@eslint-community/eslint-utils" "^4.7.0" + "@typescript-eslint/scope-manager" "8.39.1" + "@typescript-eslint/types" "8.39.1" + "@typescript-eslint/typescript-estree" "8.39.1" + "@typescript-eslint/visitor-keys@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" @@ -3081,11 +3174,58 @@ "@typescript-eslint/types" "7.18.0" eslint-visitor-keys "^3.4.3" +"@typescript-eslint/visitor-keys@8.39.1": + version "8.39.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.1.tgz#a467742a98f2fa3c03d7bed4979dc0db3850a77a" + integrity sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A== + dependencies: + "@typescript-eslint/types" "8.39.1" + eslint-visitor-keys "^4.2.1" + "@ungap/structured-clone@^1.2.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== +"@wasm-audio-decoders/common@9.0.7": + version "9.0.7" + resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/common/-/common-9.0.7.tgz#3210cdd77893a51fbb205f15dc0e56293e2074b5" + integrity sha512-WRaUuWSKV7pkttBygml/a6dIEpatq2nnZGFIoPTc5yPLkxL6Wk4YaslPM98OPQvWacvNZ+Py9xROGDtrFBDzag== + dependencies: + "@eshaz/web-worker" "1.2.2" + simple-yenc "^1.0.4" + +"@wasm-audio-decoders/flac@^0.2.4": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/flac/-/flac-0.2.8.tgz#fe8ac627d6132437a15467d3840d128b7466b3bf" + integrity sha512-CxvylHiUmtCrf0hUSzYQlD9RtoY/LsPuKR8M6ZjtQrXHzSLir0whWjPs1yb+hDZdK8R1NbESHcz2ZV88eMcKUg== + dependencies: + "@wasm-audio-decoders/common" "9.0.7" + codec-parser "2.5.0" + +"@wasm-audio-decoders/ogg-vorbis@^0.1.15": + version "0.1.18" + resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/ogg-vorbis/-/ogg-vorbis-0.1.18.tgz#c380cf1025f5b45b123d84f389215a6f9ca8c187" + integrity sha512-kEg6b5vW4wAXfGAqe5wzvSuAs2FEhPY/rniYF/Gx3rgxQcPiRI86SBAyIRWFJ7O4CY/JJHX57B1OCDueMlBSLQ== + dependencies: + "@wasm-audio-decoders/common" "9.0.7" + codec-parser "2.5.0" + +"@wasm-audio-decoders/opus-ml@0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@wasm-audio-decoders/opus-ml/-/opus-ml-0.0.1.tgz#5966904b1d0428de8ee9ef144ef2182dc1ad145b" + integrity sha512-FALuUCz10HS2h8KB4L7wmfXncOuBDFvlKRk6Ga2rw8sr/zNIpwCjhhomxH4JKPhVLOnBjZfrPa8aTFIQq74vzQ== + dependencies: + "@wasm-audio-decoders/common" "9.0.7" + +"@whiskeysockets/eslint-config@github:whiskeysockets/eslint-config": + version "1.0.0" + resolved "https://codeload.github.com/whiskeysockets/eslint-config/tar.gz/299e8389baf62f9aa3034de18ff0d62cc0a5e838" + dependencies: + "@typescript-eslint/eslint-plugin" "^8.37.0" + "@typescript-eslint/parser" "^8.37.0" + eslint-plugin-simple-import-sort "^12.1.1" + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -3244,6 +3384,11 @@ asap@^2.0.0: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +async-lock@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.4.1.tgz#56b8718915a9b68b10fce2f2a9a3dddf765ef53f" + integrity sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ== + async-mutex@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.5.0.tgz#353c69a0b9e75250971a64ac203b0ebfddd75482" @@ -3261,6 +3406,30 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== +audio-buffer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/audio-buffer/-/audio-buffer-5.0.0.tgz#92129984ebdbb8ad1c4ec6fd81525a0e0a29e99e" + integrity sha512-gsDyj1wwUp8u7NBB+eW6yhLb9ICf+0eBmDX8NGaAS00w8/fLqFdxUlL5Ge/U8kB64DlQhdonxYC59dXy1J7H/w== + +audio-decode@^2.1.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/audio-decode/-/audio-decode-2.2.3.tgz#147ae56fe3e758f0f63ea9a124af42bdee6fd6dc" + integrity sha512-Z0lHvMayR/Pad9+O9ddzaBJE0DrhZkQlStrC1RwcAHF3AhQAsdwKHeLGK8fYKyp2DDU6xHxzGb4CLMui12yVrg== + dependencies: + "@wasm-audio-decoders/flac" "^0.2.4" + "@wasm-audio-decoders/ogg-vorbis" "^0.1.15" + audio-buffer "^5.0.0" + audio-type "^2.2.1" + mpg123-decoder "^1.0.0" + node-wav "^0.0.2" + ogg-opus-decoder "^1.6.12" + qoa-format "^1.0.1" + +audio-type@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/audio-type/-/audio-type-2.2.1.tgz#5ceae0b0b3cf3b1e117edabb9e5332eaf3bd4f25" + integrity sha512-En9AY6EG1qYqEy5L/quryzbA4akBpJrnBZNxeKTqGHC2xT9Qc4aZ8b7CcbOMFTTc/MGdoNyp+SN4zInZNKxMYA== + awesome-phonenumber@^6.8.0: version "6.12.0" resolved "https://registry.yarnpkg.com/awesome-phonenumber/-/awesome-phonenumber-6.12.0.tgz#333cc3b393490dfa2b2c3b4461b442dad52d5af3" @@ -3338,16 +3507,41 @@ babel-preset-jest@^29.6.3: babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" -baileys@^6.7.8, "baileys@github:WhiskeySockets/Baileys": +baileys@^6.7.19-alpha.0: + version "6.17.16" + resolved "https://registry.yarnpkg.com/baileys/-/baileys-6.17.16.tgz#6299a7a06867d7acafe49e19f6e88e8d2c8afbff" + integrity sha512-5dLjZ6+yRR4K7u56xKGCOsLPu5o7PrfLpAW0wV3WELpQQ6m33xwFK+Jd6hu+xDSVfMr7SqP2Dn0jqj+zH8ymdw== + dependencies: + "@adiwajshing/keyed-db" "^0.2.4" + "@cacheable/node-cache" "^1.4.0" + "@hapi/boom" "^9.1.3" + "@whiskeysockets/eslint-config" "github:whiskeysockets/eslint-config" + async-lock "^1.4.1" + audio-decode "^2.1.3" + axios "^1.6.0" + cache-manager "^5.7.6" + libphonenumber-js "^1.10.20" + libsignal "github:WhiskeySockets/libsignal-node" + lodash "^4.17.21" + music-metadata "^7.12.3" + pino "^9.6" + protobufjs "^7.2.4" + uuid "^10.0.0" + ws "^8.13.0" + +baileys@^6.7.8: version "6.7.18" - resolved "https://codeload.github.com/WhiskeySockets/Baileys/tar.gz/be3d869cae5866ccf512de0364db01e188b34fac" + resolved "https://registry.yarnpkg.com/baileys/-/baileys-6.7.18.tgz#4169791f44666b27b9507f7fe46afb830f0b1c99" + integrity sha512-o90lVPkzAKCw10Ui1mhFxAUJn/Yn/RkB4jgHlFFtIXwB3L3oxOK58jbJdLvVIf3jxpDmGOQqtqu/JEnZc3mrTg== dependencies: "@cacheable/node-cache" "^1.4.0" "@hapi/boom" "^9.1.3" + "@whiskeysockets/eslint-config" "github:whiskeysockets/eslint-config" async-mutex "^0.5.0" axios "^1.6.0" - libsignal "git+https://github.com/whiskeysockets/libsignal-node" - music-metadata "^11.7.0" + libsignal "github:WhiskeySockets/libsignal-node" + lodash "^4.17.21" + music-metadata "^7.12.3" pino "^9.6" protobufjs "^7.2.4" ws "^8.13.0" @@ -3497,6 +3691,16 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cache-manager@^5.7.6: + version "5.7.6" + resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-5.7.6.tgz#bdd8a154c73e5233824aa09ceb359ed225d37b7e" + integrity sha512-wBxnBHjDxF1RXpHCBD6HGvKER003Ts7IIm0CHpggliHzN1RZditb7rXoduE1rplc2DEFYKxhLKgFuchXMJje9w== + dependencies: + eventemitter3 "^5.0.1" + lodash.clonedeep "^4.5.0" + lru-cache "^10.2.2" + promise-coalesce "^1.1.2" + cacheable@^1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/cacheable/-/cacheable-1.10.3.tgz#8dcb02081a10c4819a8d70e1251bcce0ee5afdd4" @@ -3542,9 +3746,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001733: - version "1.0.30001735" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz#ba658fd3fd24a4106fd68d5ce472a2c251494dbe" - integrity sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w== + version "1.0.30001734" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001734.tgz#f97e08599e2d75664543ae4b6ef25dc2183c5cc6" + integrity sha512-uhE1Ye5vgqju6OI71HTQqcBCZrvHugk0MjLak7Q+HfoBgoq5Bi+5YnwjP4fjDgrtYr/l8MVRBvzz9dPD4KyK0A== centra@^2.7.0: version "2.7.0" @@ -3667,6 +3871,11 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== +codec-parser@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/codec-parser/-/codec-parser-2.5.0.tgz#213f224dcf029854682a532a41d2d433ddda4d3e" + integrity sha512-Ru9t80fV8B0ZiixQl8xhMTLru+dzuis/KQld32/x5T/+3LwZb0/YvQdSKytX9JqCnRdiupvAvyYJINKrXieziQ== + codepage@~1.15.0: version "1.15.0" resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab" @@ -3856,7 +4065,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7, debug@^4.4.0, debug@^4.4.1: +debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7: version "4.4.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== @@ -4031,9 +4240,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.5.199: - version "1.5.201" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.201.tgz#bdc8f13e828e2f65d2c925ab2e8b02604928632f" - integrity sha512-ZG65vsrLClodGqywuigc+7m0gr4ISoTQttfVh7nfpLv0M7SIwF4WbFNEOywcqTiujs12AUeeXbFyQieDICAIxg== + version "1.5.200" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.200.tgz#adffa5db97390ce9d48987f528117a608ed0d7c9" + integrity sha512-rFCxROw7aOe4uPTfIAx+rXv9cEcGx+buAF4npnhtTqCJk5KDFRnh3+KYj7rdVh6lsFt5/aPs+Irj9rZ33WMA7w== emittery@^0.13.1: version "0.13.1" @@ -4174,6 +4383,11 @@ eslint-plugin-prettier@^4.2.1: dependencies: prettier-linter-helpers "^1.0.0" +eslint-plugin-simple-import-sort@^12.1.1: + version "12.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz#e64bfdaf91c5b98a298619aa634a9f7aa43b709e" + integrity sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA== + eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" @@ -4187,6 +4401,11 @@ eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" + integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== + eslint@^8.56.0: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" @@ -4279,6 +4498,11 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -4372,7 +4596,7 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.9: +fast-glob@^3.2.9, fast-glob@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== @@ -4429,11 +4653,6 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -fflate@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" - integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4450,16 +4669,6 @@ file-type@^16.5.4: strtok3 "^6.2.4" token-types "^4.1.1" -file-type@^21.0.0: - version "21.0.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-21.0.0.tgz#b6c5990064bc4b704f8e5c9b6010c59064d268bc" - integrity sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg== - dependencies: - "@tokenizer/inflate" "^0.2.7" - strtok3 "^10.2.2" - token-types "^6.0.0" - uint8array-extras "^1.4.0" - fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -4911,6 +5120,11 @@ ignore@^5.2.0, ignore@^5.3.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== +ignore@^7.0.0: + version "7.0.5" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" + integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== + image-q@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/image-q/-/image-q-4.0.0.tgz#31e075be7bae3c1f42a85c469b4732c358981776" @@ -5613,9 +5827,14 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -"libsignal@git+https://github.com/whiskeysockets/libsignal-node": +libphonenumber-js@^1.10.20: + version "1.12.10" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.10.tgz#525f7c9ffaea40c21463d3906f52ec3209ea5945" + integrity sha512-E91vHJD61jekHHR/RF/E83T/CMoaLXT7cwYA75T4gim4FZjnM6hbJjVIGg7chqlSqRsSvQ3izGmOjHy1SQzcGQ== + +"libsignal@github:WhiskeySockets/libsignal-node": version "2.0.1" - resolved "git+https://github.com/whiskeysockets/libsignal-node#4d08331a833727c338c1a90041d17b870210dfae" + resolved "https://codeload.github.com/WhiskeySockets/libsignal-node/tar.gz/4d08331a833727c338c1a90041d17b870210dfae" dependencies: curve25519-js "^0.0.4" protobufjs "6.8.8" @@ -5666,6 +5885,11 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -5676,6 +5900,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" @@ -5686,6 +5915,11 @@ long@^5.0.0: resolved "https://registry.yarnpkg.com/long/-/long-5.3.2.tgz#1d84463095999262d7d7b7f8bfd4a8cc55167f83" integrity sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA== +lru-cache@^10.2.2: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5833,6 +6067,13 @@ moo@^0.5.1: resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.2.tgz#f9fe82473bc7c184b0d32e2215d3f6e67278733c" integrity sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q== +mpg123-decoder@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/mpg123-decoder/-/mpg123-decoder-1.0.2.tgz#4f6879ea46c2af489834f1c799e1a34cb42b0c3e" + integrity sha512-cw0Laz57gumQsfCqnNeGtgq64EcyrK/z4qx+kq4iba7iSSXfI7uO3jiHjdHxNp4PB2v08VZYZ2Fr68VM1JkaPQ== + dependencies: + "@wasm-audio-decoders/common" "9.0.7" + mri@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" @@ -5848,19 +6089,18 @@ ms@2.1.3, ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -music-metadata@^11.7.0: - version "11.8.2" - resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-11.8.2.tgz#61053b956d31eae479f6c045210d559ed8fc583d" - integrity sha512-k7fxn9GCl27b+P+suLwMuEuS1Kft32P1jBZ/MXLh5iRTll60qbWWc/hh+Xvv70khyykcGwsVzddURzLdKymZ0g== +music-metadata@^7.12.3: + version "7.14.0" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-7.14.0.tgz#74e3e5fc8e09b86d1a3e791fb5ce9ccdc4347ad9" + integrity sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA== dependencies: - "@borewit/text-codec" "^0.1.0" "@tokenizer/token" "^0.3.0" content-type "^1.0.5" - debug "^4.4.1" - file-type "^21.0.0" + debug "^4.3.4" + file-type "^16.5.4" media-typer "^1.1.0" - strtok3 "^10.3.4" - token-types "^6.1.1" + strtok3 "^6.3.0" + token-types "^4.2.1" mustache@^4.2.0: version "4.2.0" @@ -5906,6 +6146,11 @@ node-releases@^2.0.19: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-wav@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/node-wav/-/node-wav-0.0.2.tgz#89cb63cf8cd66ec8ab455f5ba4864e5fcb4605e8" + integrity sha512-M6Rm/bbG6De/gKGxOpeOobx/dnGuP0dz40adqx38boqHhlWssBJZgLCPBNtb9NkrmnKYiV04xELq+R6PFOnoLA== + node-xlsx@^0.24.0: version "0.24.0" resolved "https://registry.yarnpkg.com/node-xlsx/-/node-xlsx-0.24.0.tgz#a6a365acb18ad37c66c2b254b6ebe0c22dc9dc6f" @@ -5963,6 +6208,16 @@ object-inspect@^1.13.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== +ogg-opus-decoder@^1.6.12: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ogg-opus-decoder/-/ogg-opus-decoder-1.7.0.tgz#bf4db9918c6a003382ed2aedbbf1e1dd4e2ca7a4" + integrity sha512-/lrj4+ZGjxZCCNiDSlNEckLrCL+UU9N9XtqES7sXq/Lm6PMi8Pwn/D6TTsbvG45krt21ohAh2FqdEsMuI7ZN4w== + dependencies: + "@wasm-audio-decoders/common" "9.0.7" + "@wasm-audio-decoders/opus-ml" "0.0.1" + codec-parser "2.5.0" + opus-decoder "0.7.10" + omggif@^1.0.10, omggif@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -6011,6 +6266,13 @@ optionator@^0.9.3: type-check "^0.4.0" word-wrap "^1.2.5" +opus-decoder@0.7.10: + version "0.7.10" + resolved "https://registry.yarnpkg.com/opus-decoder/-/opus-decoder-0.7.10.tgz#a075cb4e6f0d4692fd918615321de6147a5c022e" + integrity sha512-qUZdyAK+kKy/wUSd/oZ0ULE9U/yskp332n2oBvSP/Jz/wHsHiVRg33f/tRUR8TRiw+ka7AQUclxcr5TbUJo+VA== + dependencies: + "@wasm-audio-decoders/common" "9.0.7" + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -6244,9 +6506,9 @@ pino@^7.0.0: thread-stream "^0.15.1" pino@^9.6: - version "9.9.0" - resolved "https://registry.yarnpkg.com/pino/-/pino-9.9.0.tgz#0d2667ab4a54b561a4434a321ec595f305ab9cd1" - integrity sha512-zxsRIQG9HzG+jEljmvmZupOMDUQ0Jpj0yAgE28jQvvrdYTlEaiGwelJpdndMl/MBuRr70heIj83QyqJUWaU8mQ== + version "9.8.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-9.8.0.tgz#8730b8ff2e1b94ef3691666ee067f7352fef1de8" + integrity sha512-L5+rV1wL7vGAcxXP7sPpN5lrJ07Piruka6ArXr7EWBXxdVWjJshGVX8suFsiusJVcGKDGUFfbgbnKdg+VAC+0g== dependencies: atomic-sleep "^1.0.0" fast-redact "^3.1.1" @@ -6357,6 +6619,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +promise-coalesce@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/promise-coalesce/-/promise-coalesce-1.1.2.tgz#5d3bc4d0b2cf2e41e9df7cbeb6519b2a09459e3d" + integrity sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg== + promise-polyfill@^8.1.3: version "8.3.0" resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.3.0.tgz#9284810268138d103807b11f4e23d5e945a4db63" @@ -6455,6 +6722,13 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== +qoa-format@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/qoa-format/-/qoa-format-1.0.1.tgz#fb438b4757173e68b6e6baab316835e134ce0bca" + integrity sha512-dMB0Z6XQjdpz/Cw4Rf6RiBpQvUSPCfYlQMWvmuWlWkAT7nDQD29cVZ1SwDUB6DYJSitHENwbt90lqfI+7bvMcw== + dependencies: + "@thi.ng/bitstream" "^2.2.12" + qrcode-terminal@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" @@ -6854,6 +7128,11 @@ simple-update-notifier@^2.0.0: dependencies: semver "^7.5.3" +simple-yenc@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/simple-yenc/-/simple-yenc-1.0.4.tgz#52805f504ec03c0aafe3766eee901e4e6f352ead" + integrity sha512-5gvxpSd79e9a3V4QDYUqnqxeD4HGlhCakVpb6gMnDD7lexJggSBJRBO5h52y/iJrdXRilX9UCuDaIJhSWm5OWw== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -7062,14 +7341,7 @@ strnum@^2.1.0: resolved "https://registry.yarnpkg.com/strnum/-/strnum-2.1.1.tgz#cf2a6e0cf903728b8b2c4b971b7e36b4e82d46ab" integrity sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw== -strtok3@^10.2.2, strtok3@^10.3.4: - version "10.3.4" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.3.4.tgz#793ebd0d59df276a085586134b73a406e60be9c1" - integrity sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg== - dependencies: - "@tokenizer/token" "^0.3.0" - -strtok3@^6.2.4: +strtok3@^6.2.4, strtok3@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== @@ -7197,7 +7469,7 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -token-types@^4.1.1: +token-types@^4.1.1, token-types@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== @@ -7205,15 +7477,6 @@ token-types@^4.1.1: "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" -token-types@^6.0.0, token-types@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.1.1.tgz#85bd0ada82939b9178ecd5285881a538c4c00fdd" - integrity sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ== - dependencies: - "@borewit/text-codec" "^0.1.0" - "@tokenizer/token" "^0.3.0" - ieee754 "^1.2.1" - touch@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694" @@ -7234,6 +7497,11 @@ ts-api-utils@^1.3.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== +ts-api-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" + integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== + ts-essentials@^10.0.0: version "10.1.1" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-10.1.1.tgz#4e1d29b7c9b33c1a2744482376634c4fafba5210" @@ -7358,11 +7626,6 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== -uint8array-extras@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.4.1.tgz#6d6e88363a414577c133aca1e63b2a6c5524be21" - integrity sha512-+NWHrac9dvilNgme+gP4YrBSumsaMZP0fNBtXXFIf33RLLKEcBUKaQZ7ULUbS0sBfcjxIZ4V96OTRkCbM7hxpw== - undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" @@ -7431,6 +7694,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" + integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== + uuid@^9.0.0, uuid@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" From ad03a8ce6c3deb48439575e6b86192b732d2a0cc Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 31 Aug 2025 17:03:06 -0300 Subject: [PATCH 18/21] update Node.js version to 24.7.0 in .tool-versions --- .tool-versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tool-versions b/.tool-versions index 649ccb36..c2580db2 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -nodejs 22.16.0 +nodejs 24.7.0 yarn 1.22.22 From d2c075ee02ca255bc0d765f9e317a6042e657d74 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 31 Aug 2025 17:03:17 -0300 Subject: [PATCH 19/21] update baileys dependency to version 6.7.19 --- package.json | 2 +- yarn.lock | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5dd25f96..7625aa0f 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "amqplib": "^0.10.8", "audio2textjs": "^1.0.5", "awesome-phonenumber": "^6.8.0", - "baileys": "git+https://github.com/WhiskeySockets/Baileys#19124426b2ded31f6d28ed60c53b75f101865bc3", + "baileys": "^6.7.19", "dotenv": "^16.4.5", "express": "^4.19.2", "i18n": "^0.15.1", diff --git a/yarn.lock b/yarn.lock index 667b4a8c..6ce61f78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3332,7 +3332,22 @@ babel-preset-jest@^29.6.3: babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" -baileys@^6.7.8, "baileys@git+https://github.com/WhiskeySockets/Baileys#19124426b2ded31f6d28ed60c53b75f101865bc3": +baileys@^6.7.19: + version "6.7.19" + resolved "https://registry.yarnpkg.com/baileys/-/baileys-6.7.19.tgz#7f278ed4c41b0c98e95766e7ebca5881cc539b16" + integrity sha512-15ZZVZoN5CQl6UeTT+3CogIZm40G+E5LO9meVi4NhqxmYYiIGoh7iuq5UlHjmTvZIpFtMPCnz+EDmyEABy8oig== + dependencies: + "@cacheable/node-cache" "^1.4.0" + "@hapi/boom" "^9.1.3" + async-mutex "^0.5.0" + axios "^1.6.0" + libsignal "git+https://github.com/whiskeysockets/libsignal-node" + music-metadata "^11.7.0" + pino "^9.6" + protobufjs "^7.2.4" + ws "^8.13.0" + +baileys@^6.7.8: version "6.7.18" resolved "git+https://github.com/WhiskeySockets/Baileys#19124426b2ded31f6d28ed60c53b75f101865bc3" dependencies: From df4456f2fdda14042b7b02b8aeedb130b0a69a68 Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Sun, 31 Aug 2025 18:06:30 -0300 Subject: [PATCH 20/21] refactor: clean up code formatting and remove unnecessary newlines --- __tests__/jobs/timer.ts | 15 +- __tests__/routes/blacklist.ts | 4 +- __tests__/services/blacklist.ts | 1 - __tests__/services/media_store_file.ts | 6 +- __tests__/services/outgoing_cloud_api.ts | 8 +- __tests__/services/session_store_file.ts | 6 +- __tests__/services/socket.ts | 4 +- __tests__/services/transformer.ts | 140 ++++++++------- jest.config.js | 8 + src/amqp.ts | 59 ++++--- src/app.ts | 38 ++--- src/bridge.ts | 50 ++---- src/broker.ts | 84 +++------ src/bulker.ts | 1 - src/controllers/index_controller.ts | 1 - .../marketing_messages_controller.ts | 1 - src/controllers/pairing_code_controller.ts | 4 +- src/controllers/registration_controller.ts | 2 +- src/controllers/templates_controller.ts | 1 - src/controllers/webhook_controller.ts | 2 +- src/controllers/webhook_fake_controller.ts | 1 - src/defaults.ts | 15 +- src/i18n.ts | 4 +- src/index.ts | 14 +- src/jobs/add_to_blacklist.ts | 2 +- src/jobs/bind_bridge.ts | 24 +-- src/jobs/bulk_parser.ts | 12 +- src/jobs/bulk_report.ts | 8 +- src/jobs/bulk_sender.ts | 16 +- src/jobs/commander.ts | 20 ++- src/jobs/incoming.ts | 14 +- src/jobs/listener.ts | 18 +- src/jobs/outgoing.ts | 82 +++++---- src/jobs/reload.ts | 2 +- src/jobs/timer.ts | 6 +- src/jobs/transcriber.ts | 43 ++--- src/jobs/webhook_status_failed.ts | 6 +- src/locales/en.json | 44 ++--- src/locales/pt.json | 34 ++-- src/locales/pt_BR.json | 34 ++-- src/router.ts | 2 - src/services/auto_connect.ts | 8 +- src/services/blacklist.ts | 6 +- src/services/broadcast.ts | 1 - src/services/client.ts | 16 +- src/services/client_baileys.ts | 148 ++++++++-------- src/services/client_forward.ts | 18 +- src/services/config.ts | 12 +- src/services/config_by_env.ts | 2 +- src/services/config_redis.ts | 12 +- src/services/contact_baileys.ts | 4 +- src/services/contact_dummy.ts | 4 +- src/services/data_store.ts | 27 +-- src/services/data_store_file.ts | 52 +++--- src/services/data_store_redis.ts | 3 +- src/services/incoming_amqp.ts | 18 +- src/services/listener_amqp.ts | 41 ++--- src/services/listener_baileys.ts | 99 ++++++----- src/services/logout_amqp.ts | 10 +- src/services/media_store_file.ts | 4 +- src/services/media_store_s3.ts | 17 +- src/services/outgoing_amqp.ts | 5 +- src/services/outgoing_cloud_api.ts | 2 +- src/services/redis.ts | 18 +- src/services/reload_amqp.ts | 16 +- src/services/reload_baileys.ts | 2 +- src/services/send_error.ts | 2 +- src/services/session_store.ts | 19 +-- src/services/session_store_redis.ts | 24 ++- src/services/socket.ts | 42 ++--- src/services/store.ts | 4 +- src/services/store_file.ts | 2 +- src/services/timer.ts | 16 +- src/services/transformer.ts | 159 ++++++++---------- src/standalone.ts | 68 +++----- src/utils/media_to_buffer.ts | 5 +- src/waker.ts | 22 +-- src/web.ts | 13 +- tsconfig.json | 4 +- yarn.lock | 79 ++++++++- 80 files changed, 887 insertions(+), 953 deletions(-) diff --git a/__tests__/jobs/timer.ts b/__tests__/jobs/timer.ts index 95910f38..3012c918 100644 --- a/__tests__/jobs/timer.ts +++ b/__tests__/jobs/timer.ts @@ -7,7 +7,7 @@ const delLastTimerMock = delLastTimer as jest.MockedFunction { let incoming, job, payload, phone, to, message, time, sendSpy, mockGetLastTimer, incomingPayload - + beforeEach(() => { incoming = mock() mockGetLastTimer = jest.fn() @@ -17,21 +17,24 @@ describe('timer', () => { message = `${new Date().getTime()}s sdfhosfo` time = '2011-10-05T14:48:00.000Z' payload = { - phone, to, message, time + phone, + to, + message, + time, } sendSpy = jest.spyOn(incoming, 'send') - incomingPayload =[ + incomingPayload = [ phone, { messaging_product: 'whatsapp', to, type: 'text', text: { - body: message - } + body: message, + }, }, - {} + {}, ] delLastTimerMock.mockResolvedValue(Promise.resolve()) }) diff --git a/__tests__/routes/blacklist.ts b/__tests__/routes/blacklist.ts index b7e1dae4..38ebae8d 100644 --- a/__tests__/routes/blacklist.ts +++ b/__tests__/routes/blacklist.ts @@ -24,8 +24,8 @@ describe('blacklist routes', () => { const reload = mock() const logout = mock() const app: App = new App(incoming, outgoing, '', getConfigTest, sessionStore, onNewLogin, addToBlacklist, reload, logout) - const res = await request(app.server).post('/2/blacklist/1').send({ttl: 1, to: '3'}) - expect(addToBlacklist).toHaveBeenCalledWith('2', '1', '3', 1); + const res = await request(app.server).post('/2/blacklist/1').send({ ttl: 1, to: '3' }) + expect(addToBlacklist).toHaveBeenCalledWith('2', '1', '3', 1) expect(res.status).toEqual(200) }) }) diff --git a/__tests__/services/blacklist.ts b/__tests__/services/blacklist.ts index a866218b..eb368f83 100644 --- a/__tests__/services/blacklist.ts +++ b/__tests__/services/blacklist.ts @@ -1,4 +1,3 @@ - jest.mock('../../src/services/redis') import { isInBlacklistInMemory, addToBlacklistInMemory, cleanBlackList, isInBlacklistInRedis } from '../../src/services/blacklist' import { redisGet, redisKeys, blacklist } from '../../src/services/redis' diff --git a/__tests__/services/media_store_file.ts b/__tests__/services/media_store_file.ts index e5d606d7..3dbef31a 100644 --- a/__tests__/services/media_store_file.ts +++ b/__tests__/services/media_store_file.ts @@ -8,12 +8,12 @@ const phone = `${new Date().getTime()}` const messageId = `wa.${new Date().getTime()}` const url = `http://somehost` const mimetype = 'text/plain' -const extension = 'txt' +const extension = 'txt' const message = { messaging_product: 'whatsapp', id: `${phone}/${messageId}`, - mime_type: mimetype + mime_type: mimetype, } const dataStore = mock() // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -32,7 +32,7 @@ describe('media routes', () => { test('getMedia', async () => { const response = { url: `${url}/v15.0/download/${phone}/${messageId}.${extension}`, - ...message + ...message, } expect(await mediaStore.getMedia(url, messageId)).toStrictEqual(response) }) diff --git a/__tests__/services/outgoing_cloud_api.ts b/__tests__/services/outgoing_cloud_api.ts index f1965364..79af9004 100644 --- a/__tests__/services/outgoing_cloud_api.ts +++ b/__tests__/services/outgoing_cloud_api.ts @@ -44,7 +44,7 @@ describe('service outgoing whatsapp cloud api', () => { service = new OutgoingCloudApi(getConfig, isInBlacklistInMemory) textPayload = { text: { - body: 'test' + body: 'test', }, type: 'text', to: 'abc', @@ -57,8 +57,8 @@ describe('service outgoing whatsapp cloud api', () => { { value: { metadata: { display_phone_number: 'abc' }, - messages: [ { from: 'abc' }, ] - } + messages: [{ from: 'abc' }], + }, }, ], }, @@ -71,7 +71,7 @@ describe('service outgoing whatsapp cloud api', () => { changes: [ { value: { - statuses: [ { status: 'deleted' } ] + statuses: [{ status: 'deleted' }], }, }, ], diff --git a/__tests__/services/session_store_file.ts b/__tests__/services/session_store_file.ts index ac5efdbe..0356dd84 100644 --- a/__tests__/services/session_store_file.ts +++ b/__tests__/services/session_store_file.ts @@ -38,7 +38,7 @@ describe('service session store file', () => { return MAX_CONNECT_RETRY + 1 } return getConnectCount(session) - } + } expect(await store.verifyStatusStandBy(session)).toBe(true) }) test('return a no standby on count and verify', async () => { @@ -50,7 +50,7 @@ describe('service session store file', () => { return MAX_CONNECT_RETRY - 2 } return getConnectCount(session) - } - expect(!!await store.verifyStatusStandBy(session)).toBe(false) + } + expect(!!(await store.verifyStatusStandBy(session))).toBe(false) }) }) diff --git a/__tests__/services/socket.ts b/__tests__/services/socket.ts index dd93984b..6d7c7b5d 100644 --- a/__tests__/services/socket.ts +++ b/__tests__/services/socket.ts @@ -49,7 +49,7 @@ describe('service socket', () => { onNewLogin, attempts: 1, time: 1, - config: { ...defaultConfig, whatsappVersion } + config: { ...defaultConfig, whatsappVersion }, }) expect(response && response.status.attempt).toBe(1) }) @@ -65,7 +65,7 @@ describe('service socket', () => { onNewLogin, attempts: 1, time: 1, - config: { ...defaultConfig, whatsappVersion } + config: { ...defaultConfig, whatsappVersion }, }) expect(mockOn).toHaveBeenCalled() }) diff --git a/__tests__/services/transformer.ts b/__tests__/services/transformer.ts index 12d0694c..c6046e3d 100644 --- a/__tests__/services/transformer.ts +++ b/__tests__/services/transformer.ts @@ -61,12 +61,12 @@ describe('service transformer', () => { changes: [ { value: { - statuses: [{ recipient_id: 'x' }] - } - } - ] - } - ] + statuses: [{ recipient_id: 'x' }], + }, + }, + ], + }, + ], } expect(extractDestinyPhone(payload)).toBe('x') }) @@ -78,12 +78,12 @@ describe('service transformer', () => { changes: [ { value: { - statuses: [{ recipient_id: 'x' }] - } - } - ] - } - ] + statuses: [{ recipient_id: 'x' }], + }, + }, + ], + }, + ], } expect(isGroupMessage(payload)).toBe(false) }) @@ -108,7 +108,7 @@ describe('service transformer', () => { test('getChatAndNumberAndId with lid and without group', async () => { const senderPn = '554988290955' const remoteJid = '24788516941@lid' - const payload = { key: { remoteJid, senderPn }} + const payload = { key: { remoteJid, senderPn } } const a = getChatAndNumberAndId(payload) expect(a[0]).toBe(remoteJid) expect(a[1]).toBe('5549988290955') @@ -119,7 +119,7 @@ describe('service transformer', () => { const participantPn = '554988290955' const remoteJid = '24788516941@g.us' const participant = '554988290955@s.whatsapp.net' - const payload = { key: { remoteJid, participant, participantPn }} + const payload = { key: { remoteJid, participant, participantPn } } const a = getChatAndNumberAndId(payload) expect(a[0]).toBe(remoteJid) expect(a[1]).toBe('5549988290955') @@ -130,7 +130,7 @@ describe('service transformer', () => { const participantPn = '554988290955' const remoteJid = '24788516941@g.us' const participantLid = '24788516941@lid' - const payload = { key: { remoteJid, participantLid, participantPn }} + const payload = { key: { remoteJid, participantLid, participantPn } } const a = getChatAndNumberAndId(payload) expect(a[0]).toBe(remoteJid) expect(a[1]).toBe('5549988290955') @@ -140,7 +140,7 @@ describe('service transformer', () => { test('getChatAndNumberAndId with senderLid and without group', async () => { const senderPn = '554988290955' const remoteJid = '24788516941@lid' - const payload = { key: { remoteJid, senderLid: remoteJid, senderPn }} + const payload = { key: { remoteJid, senderLid: remoteJid, senderPn } } const a = getChatAndNumberAndId(payload) expect(a[0]).toBe(remoteJid) expect(a[1]).toBe('5549988290955') @@ -296,7 +296,6 @@ describe('service transformer', () => { test('jidToPhoneNumber without + and put 9˚ digit', async () => { expect(jidToPhoneNumber('+554988290955@s.whatsapp.net', '')).toEqual('5549988290955') }) - test('fromBaileysMessageContent with editedMessage for imageMessage', async () => { const phoneNumer = '5549998360838' @@ -310,24 +309,24 @@ describe('service transformer', () => { key: { remoteJid, fromMe: false, - id + id, }, message: { editedMessage: { message: { protocolMessage: { key: { - id: '3AD0FEAAF5915DAEAA07' + id: '3AD0FEAAF5915DAEAA07', }, type: 'MESSAGE_EDIT', editedMessage: { imageMessage: { - caption: body - } - } - } - } - } + caption: body, + }, + }, + }, + }, + }, }, pushName, messageTimestamp, @@ -1093,12 +1092,12 @@ describe('service transformer', () => { messageTimestamp, pushName, message: { - editedMessage:{ + editedMessage: { message: { - conversation - } - } - } + conversation, + }, + }, + }, } const output = { object: 'whatsapp_business_account', @@ -1141,7 +1140,7 @@ describe('service transformer', () => { const messageTimestamp = Math.floor(new Date().getTime() / 1000).toString() const phoneNumer = '5549998093075' const conversation = `blablabla2.${new Date().getTime()}` - const input = { + const input = { key: { remoteJid: remoteJid, fromMe: true, @@ -1149,19 +1148,19 @@ describe('service transformer', () => { }, messageTimestamp, pushName, - message: { - protocolMessage: { - key: { - remoteJid, - fromMe: true, - id: id2 - }, - type: 'MESSAGE_EDIT', - editedMessage: { - conversation, - }, - } - } + message: { + protocolMessage: { + key: { + remoteJid, + fromMe: true, + id: id2, + }, + type: 'MESSAGE_EDIT', + editedMessage: { + conversation, + }, + }, + }, } const output = { object: 'whatsapp_business_account', @@ -1198,12 +1197,12 @@ describe('service transformer', () => { test('getMessageType with viewOnceMessage', async () => { const input = { message: { - protocolMessage: {}, + protocolMessage: {}, type: 'MESSAGE_EDIT', - editedMessage: { - conversation: 'blablabla2' - } - } + editedMessage: { + conversation: 'blablabla2', + }, + }, } expect(getMessageType(input)).toEqual('editedMessage') }) @@ -1240,15 +1239,11 @@ describe('service transformer', () => { contacts: [ { name: { formatted_name: displayName }, - phones: [{ phone, wa_id }] - } - ] + phones: [{ phone, wa_id }], + }, + ], } - const vcard = 'BEGIN:VCARD\n' - + 'VERSION:3.0\n' - + `N:${displayName}\n` - + `TEL;type=CELL;type=VOICE;waid=${wa_id}:${phone}\n` - + 'END:VCARD' + const vcard = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${displayName}\n` + `TEL;type=CELL;type=VOICE;waid=${wa_id}:${phone}\n` + 'END:VCARD' const output = { contacts: { displayName, contacts: [{ vcard }] } } expect(toBaileysMessageContent(input)).toEqual(output) }) @@ -1462,21 +1457,20 @@ describe('service transformer', () => { expect(toBaileysMessageContent(input)).toEqual(output) }) - test('fromBaileysMessageContent participant outside key', async () => { const phoneNumer = '5549998093075' const remotePhoneNumber = '11115551212' const input = { key: { remoteJid: '554988189915-1593526912@g.us', - fromMe: false, - id: '583871ED40A7FBC09B5C3A7C2CC760A0' + fromMe: false, + id: '583871ED40A7FBC09B5C3A7C2CC760A0', }, message: { - conversation: '🤷‍♂️' + conversation: '🤷‍♂️', }, participant: `${remotePhoneNumber}@s.whatsapp.net`, - isMentionedInStatus :false + isMentionedInStatus: false, } const resp = fromBaileysMessageContent(phoneNumer, input)[0] const from = resp.entry[0].changes[0].value.messages[0].from @@ -1493,10 +1487,10 @@ describe('service transformer', () => { const messageTimestamp = Math.floor(new Date().getTime() / 1000).toString() const phoneNumer = '5549998360838' const input = { - key:{ + key: { remoteJid, fromMe: false, - id + id, }, message: { extendedTextMessage: { @@ -1508,13 +1502,13 @@ describe('service transformer', () => { statusMentionMessage: { message: { protocolMessage: { - type: 'STATUS_MENTION_MESSAGE' - } - } - } - } - } - } + type: 'STATUS_MENTION_MESSAGE', + }, + }, + }, + }, + }, + }, }, pushName, messageTimestamp, @@ -1554,6 +1548,6 @@ describe('service transformer', () => { } expect(fromBaileysMessageContent(phoneNumer, input)[0]).toEqual(output) }) -// {"key":{"remoteJid":"555533800800@s.whatsapp.net","fromMe":false,"id":"1BE283407E62E5A073"},"messageTimestamp":1753900800,"pushName":"555533800800","broadcast":false,"message":{"messageContextInfo":{"deviceListMetadata":{"recipientKeyHash":"BuoOcp2GlUsdsQ==","recipientTimestamp":"1753278139","recipientKeyIndexes":[0,5]},"deviceListMetadataVersion":2},"buttonsMessage":{"contentText":"Para confirmar, estou falando com *IM Agronegócios* e o seu CNPJ é *41.281.5xx/xxxx-xx*?","buttons":[{"buttonId":"1","buttonText":{"displayText":"Sim"},"type":"RESPONSE"},{"buttonId":"2","buttonText":{"displayText":"Não"},"type":"RESPONSE"}],"headerType":"EMPTY"}},"verifiedBizName":"Unifique"} -// {"key":{"remoteJid":"555533800800@s.whatsapp.net","fromMe":true,"id":"3EB02FCD7C12A71F06DE34"}, "messageTimestamp":1753900805,"pushName":"Im Agronegócios","broadcast":false,"status":2, "message":{"buttonsResponseMessage":{"selectedButtonId":"1","selectedDisplayText":"Sim","contextInfo":{"stanzaId":"1BE283407E62E5A073","participant":"555533800800@s.whatsapp.net","quotedMessage":{"messageContextInfo":{},"buttonsMessage":{"contentText":"Para confirmar, estou falando com *IM Agronegócios* e o seu CNPJ é *41.281.5xx/xxxx-xx*?","buttons":[{"buttonId":"1","buttonText":{"displayText":"Sim"},"type":"RESPONSE"},{"buttonId":"2","buttonText":{"displayText":"Não"},"type":"RESPONSE"}],"headerType":"EMPTY"}}},"type":"DISPLAY_TEXT"}}} + // {"key":{"remoteJid":"555533800800@s.whatsapp.net","fromMe":false,"id":"1BE283407E62E5A073"},"messageTimestamp":1753900800,"pushName":"555533800800","broadcast":false,"message":{"messageContextInfo":{"deviceListMetadata":{"recipientKeyHash":"BuoOcp2GlUsdsQ==","recipientTimestamp":"1753278139","recipientKeyIndexes":[0,5]},"deviceListMetadataVersion":2},"buttonsMessage":{"contentText":"Para confirmar, estou falando com *IM Agronegócios* e o seu CNPJ é *41.281.5xx/xxxx-xx*?","buttons":[{"buttonId":"1","buttonText":{"displayText":"Sim"},"type":"RESPONSE"},{"buttonId":"2","buttonText":{"displayText":"Não"},"type":"RESPONSE"}],"headerType":"EMPTY"}},"verifiedBizName":"Unifique"} + // {"key":{"remoteJid":"555533800800@s.whatsapp.net","fromMe":true,"id":"3EB02FCD7C12A71F06DE34"}, "messageTimestamp":1753900805,"pushName":"Im Agronegócios","broadcast":false,"status":2, "message":{"buttonsResponseMessage":{"selectedButtonId":"1","selectedDisplayText":"Sim","contextInfo":{"stanzaId":"1BE283407E62E5A073","participant":"555533800800@s.whatsapp.net","quotedMessage":{"messageContextInfo":{},"buttonsMessage":{"contentText":"Para confirmar, estou falando com *IM Agronegócios* e o seu CNPJ é *41.281.5xx/xxxx-xx*?","buttons":[{"buttonId":"1","buttonText":{"displayText":"Sim"},"type":"RESPONSE"},{"buttonId":"2","buttonText":{"displayText":"Não"},"type":"RESPONSE"}],"headerType":"EMPTY"}}},"type":"DISPLAY_TEXT"}}} }) diff --git a/jest.config.js b/jest.config.js index b413e106..813f8ce3 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,4 +2,12 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', + transform: { + '^.+\\.(ts|tsx)$': 'ts-jest', + '^.+\\.(js|jsx)$': 'ts-jest', + }, + + transformIgnorePatterns: [ + '/node_modules/(?!(baileys|@adiwajshing/keyed-db|pino|pino-pretty)/)', + ], }; \ No newline at end of file diff --git a/src/amqp.ts b/src/amqp.ts index e711409a..f142b731 100644 --- a/src/amqp.ts +++ b/src/amqp.ts @@ -14,7 +14,7 @@ import { UNOAPI_SERVER_NAME, UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_EXCHANGE_BRIDGE_NAME, - IGNORED_TO_NUMBERS + IGNORED_TO_NUMBERS, } from './defaults' import logger from './services/logger' import { version } from '../package.json' @@ -22,14 +22,8 @@ import { extractDestinyPhone } from './services/transformer' const withTimeout = (millis, error, promise) => { let timeoutPid - const timeout = new Promise((_resolve, reject) => - timeoutPid = setTimeout( - () => reject(error), - millis)) - return Promise.race([ - promise, - timeout - ]).finally(() => { + const timeout = new Promise((_resolve, reject) => (timeoutPid = setTimeout(() => reject(error), millis))) + return Promise.race([promise, timeout]).finally(() => { if (timeoutPid) { clearTimeout(timeoutPid) } @@ -124,15 +118,18 @@ export const amqpGetExchange = async (exchange: string, type: ExchagenType, pref logger.info('Creating exchange %s...', exchange) const channel = await amqpGetChannel() await channel.prefetch(prefetch) - await channel.assertExchange(exchange, type, { durable: true, arguments: { 'x-max-priority': 5 }}) + await channel.assertExchange(exchange, type, { durable: true, arguments: { 'x-max-priority': 5 } }) const exchangeDeadId = queueDeadName(exchange) await amqpChannel.assertExchange(exchangeDeadId, 'topic', { durable: true }) const exchangeDelayedId = queueDelayedName(exchange) - await amqpChannel.assertExchange(exchangeDelayedId, 'topic', { durable: true , arguments: { - 'x-dead-letter-exchange': exchange - }}) + await amqpChannel.assertExchange(exchangeDelayedId, 'topic', { + durable: true, + arguments: { + 'x-dead-letter-exchange': exchange, + }, + }) logger.info('Created exchange %s!', exchange) exchanges.set(exchange, true) } @@ -159,7 +156,7 @@ export const amqpGetQueue = async ( priority: 0, notifyFailedMessages: NOTIFY_FAILED_MESSAGES, type: 'topic', - prefetch: 1 + prefetch: 1, }, ): Promise => { if (!queues.get(queue)) { @@ -176,16 +173,18 @@ export const amqpGetQueue = async ( const exchangeDelayedId = queueDelayedName(exchange) const queueDelayedId = queueDelayedName(queue) - const queueDelayed = await amqpChannel.assertQueue(queueDelayedId, { durable: true, arguments: { - 'x-dead-letter-exchange': deadLetterExchange - }}) + const queueDelayed = await amqpChannel.assertQueue(queueDelayedId, { + durable: true, + arguments: { + 'x-dead-letter-exchange': deadLetterExchange, + }, + }) await amqpChannel.bindQueue(queueDelayedId, exchangeDelayedId, `${queueDelayedId}.*`) queues.set(queue, { queueMain, queueDead, queueDelayed }) logger.info('Created queue %s!', queue) } - validateRoutingKey(routingKey) if (/^\d+$/.test(routingKey) && !routes.get(routingKey)) { await amqpPublish(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_BIND}.${UNOAPI_SERVER_NAME}`, '', { routingKey }, { type: 'direct' }) @@ -194,7 +193,6 @@ export const amqpGetQueue = async ( return queues.get(queue)! } - const getExchangeType = (exchange): ExchagenType => { if (UNOAPI_EXCHANGE_BRIDGE_NAME == exchange) { return 'direct' @@ -210,12 +208,12 @@ export const amqpPublish = async ( queue: string, routingKey: string, payload: object, - options: Partial = { + options: Partial = { delay: 0, dead: false, maxRetries: UNOAPI_MESSAGE_RETRY_LIMIT, countRetries: 0, - priority: 0 + priority: 0, }, ) => { validateRoutingKey(routingKey) @@ -254,7 +252,7 @@ export const amqpPublish = async ( exchangeUsed, destiny, JSON.stringify(payload), - JSON.stringify(properties) + JSON.stringify(properties), ) } @@ -264,9 +262,9 @@ export const amqpConsume = async ( routingKey: string, callback: ConsumeCallback, options: Partial = { - delay: UNOAPI_MESSAGE_RETRY_DELAY, + delay: UNOAPI_MESSAGE_RETRY_DELAY, priority: 0, - notifyFailedMessages: NOTIFY_FAILED_MESSAGES + notifyFailedMessages: NOTIFY_FAILED_MESSAGES, }, ) => { logger.debug('Configurate to consume exchange: %s, queue: %s, routing key: %s and type: %s', exchange, queue, routingKey, options.type) @@ -285,7 +283,13 @@ export const amqpConsume = async ( const maxRetries = parseInt(headers[UNOAPI_X_MAX_RETRIES] || UNOAPI_MESSAGE_RETRY_LIMIT) const countRetries = parseInt(headers[UNOAPI_X_COUNT_RETRIES] || '0') + 1 try { - logger.debug('Received in queue %s, with routing key: %s, with message: %s with headers: %s', queue, routingKey, content, JSON.stringify(payload.properties.headers)) + logger.debug( + 'Received in queue %s, with routing key: %s, with message: %s with headers: %s', + queue, + routingKey, + content, + JSON.stringify(payload.properties.headers), + ) if (IGNORED_CONNECTIONS_NUMBERS.includes(routingKey)) { logger.info(`Ignore messages from ${routingKey}`) } else if (IGNORED_TO_NUMBERS.length > 0 && IGNORED_TO_NUMBERS.includes(extractDestinyPhone(data.payload, false))) { @@ -311,8 +315,9 @@ export const amqpConsume = async ( to: routingKey, type: 'text', text: { - body: `Unoapi version ${version} message failed in queue ${queue}\n\nstack trace: ${error.stack}\n\n\nerror: ${error.message - }\n\ndata: ${JSON.stringify(data, undefined, 2)}`, + body: `Unoapi version ${version} message failed in queue ${queue}\n\nstack trace: ${error.stack}\n\n\nerror: ${ + error.message + }\n\ndata: ${JSON.stringify(data, undefined, 2)}`, }, }, }, diff --git a/src/app.ts b/src/app.ts index f8e46dac..16e442b1 100644 --- a/src/app.ts +++ b/src/app.ts @@ -46,21 +46,21 @@ export class App { this.socket = new Server(this.server, { path: '/ws', cors: { - origin: '*' - } + origin: '*', + }, }) this.router( - incoming, - outgoing, - baseUrl, + incoming, + outgoing, + baseUrl, getConfig, sessionStore, this.socket, onNewLogin, - addToBlacklist, - reload, + addToBlacklist, + reload, logout, - middleware, + middleware, injectRoute, contact, ) @@ -82,17 +82,17 @@ export class App { contact: Contact, ) { const roter = router( - incoming, - outgoing, - baseUrl, - getConfig, - sessionStore, - socket, - onNewLogin, - addToBlacklist, - reload, - logout, - middleware, + incoming, + outgoing, + baseUrl, + getConfig, + sessionStore, + socket, + onNewLogin, + addToBlacklist, + reload, + logout, + middleware, injectRoute, contact, ) diff --git a/src/bridge.ts b/src/bridge.ts index 0e4ef6b3..918de9c3 100644 --- a/src/bridge.ts +++ b/src/bridge.ts @@ -6,13 +6,7 @@ import { BindBridgeJob } from './jobs/bind_bridge' import { SessionStoreRedis } from './services/session_store_redis' import { SessionStore } from './services/session_store' import { autoConnect } from './services/auto_connect' -import { - UNOAPI_QUEUE_BIND, - UNOAPI_QUEUE_RELOAD, - UNOAPI_QUEUE_LOGOUT, - UNOAPI_SERVER_NAME, - UNOAPI_EXCHANGE_BRIDGE_NAME, -} from './defaults' +import { UNOAPI_QUEUE_BIND, UNOAPI_QUEUE_RELOAD, UNOAPI_QUEUE_LOGOUT, UNOAPI_SERVER_NAME, UNOAPI_EXCHANGE_BRIDGE_NAME } from './defaults' import { amqpConsume } from './amqp' import { startRedis } from './services/redis' import { getConfig } from './services/config' @@ -54,40 +48,22 @@ const startBrigde = async () => { logger.info('Unoapi Cloud version %s starting bridge...', version) logger.info('Starting bind consumer') - await amqpConsume( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_BIND}.${UNOAPI_SERVER_NAME}`, - '', - bindJob.consume.bind(bindJob), - { - prefetch: 1, - type: 'direct' - } - ) + await amqpConsume(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_BIND}.${UNOAPI_SERVER_NAME}`, '', bindJob.consume.bind(bindJob), { + prefetch: 1, + type: 'direct', + }) logger.info('Starting reload consumer') - await amqpConsume( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_RELOAD}.${UNOAPI_SERVER_NAME}`, - '', - reloadJob.consume.bind(reloadJob), - { - prefetch: 1, - type: 'direct' - } - ) + await amqpConsume(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_RELOAD}.${UNOAPI_SERVER_NAME}`, '', reloadJob.consume.bind(reloadJob), { + prefetch: 1, + type: 'direct', + }) logger.info('Starting logout consumer') - await amqpConsume( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_LOGOUT}.${UNOAPI_SERVER_NAME}`, - '', - logoutJob.consume.bind(logoutJob), - { - prefetch: 1, - type: 'direct' - } - ) + await amqpConsume(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_LOGOUT}.${UNOAPI_SERVER_NAME}`, '', logoutJob.consume.bind(logoutJob), { + prefetch: 1, + type: 'direct', + }) const sessionStore: SessionStore = new SessionStoreRedis() diff --git a/src/broker.ts b/src/broker.ts index 587e9dbc..f75f777c 100644 --- a/src/broker.ts +++ b/src/broker.ts @@ -1,7 +1,7 @@ import * as dotenv from 'dotenv' dotenv.config() -import { +import { UNOAPI_QUEUE_RELOAD, UNOAPI_SERVER_NAME, UNOAPI_QUEUE_MEDIA, @@ -65,85 +65,55 @@ const startBroker = async () => { logger.info('Unoapi Cloud version %s starting broker...', version) logger.info('Starting reload consumer') - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_RELOAD, - '*', - reloadJob.consume.bind(reloadJob), - { type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_RELOAD, '*', reloadJob.consume.bind(reloadJob), { type: 'topic' }) logger.info('Starting media consumer') - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_MEDIA, - '*', - mediaJob.consume.bind(mediaJob), - { type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_MEDIA, '*', mediaJob.consume.bind(mediaJob), { type: 'topic' }) logger.info('Binding queues consumer for server %s', UNOAPI_SERVER_NAME) const notifyFailedMessages = NOTIFY_FAILED_MESSAGES logger.info('Starting outgoing consumer %s', UNOAPI_SERVER_NAME) - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_OUTGOING, - '*', - outgingJob.consume.bind(outgingJob), - { notifyFailedMessages, prefetch, type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_OUTGOING, '*', outgingJob.consume.bind(outgingJob), { + notifyFailedMessages, + prefetch, + type: 'topic', + }) logger.info('Starting transcriber consumer %s', UNOAPI_SERVER_NAME) - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_TRANSCRIBER, - '*', - transcriberJob.consume.bind(transcriberJob), - { notifyFailedMessages, prefetch, type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_TRANSCRIBER, '*', transcriberJob.consume.bind(transcriberJob), { + notifyFailedMessages, + prefetch, + type: 'topic', + }) logger.info('Starting timer consumer %s', UNOAPI_SERVER_NAME) - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_TIMER, - '*', - timerJob.consume.bind(timerJob), - { notifyFailedMessages, prefetch, type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_TIMER, '*', timerJob.consume.bind(timerJob), { + notifyFailedMessages, + prefetch, + type: 'topic', + }) if (notifyFailedMessages) { logger.debug('Starting notification consumer %s', UNOAPI_SERVER_NAME) - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_NOTIFICATION, - '*', - notificationJob.consume.bind(notificationJob), - { notifyFailedMessages: false, type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_NOTIFICATION, '*', notificationJob.consume.bind(notificationJob), { + notifyFailedMessages: false, + type: 'topic', + }) } if (STATUS_FAILED_WEBHOOK_URL) { const job = new WebhookStatusFailedJob(STATUS_FAILED_WEBHOOK_URL) logger.debug('Starting webhook status failed consumer %s', UNOAPI_SERVER_NAME) - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_WEBHOOK_STATUS_FAILED, - '*', - job.consume.bind(job), - { notifyFailedMessages: false, type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_WEBHOOK_STATUS_FAILED, '*', job.consume.bind(job), { + notifyFailedMessages: false, + type: 'topic', + }) } logger.info('Starting blacklist add consumer %s', UNOAPI_SERVER_NAME) - await amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_BLACKLIST_ADD, - '*', - addToBlacklist, - { notifyFailedMessages, prefetch, type: 'topic' } - ) + await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_BLACKLIST_ADD, '*', addToBlacklist, { notifyFailedMessages, prefetch, type: 'topic' }) logger.info('Unoapi Cloud version %s started broker!', version) } diff --git a/src/bulker.ts b/src/bulker.ts index 0d0cebab..8c697910 100644 --- a/src/bulker.ts +++ b/src/bulker.ts @@ -35,7 +35,6 @@ if (process.env.SENTRY_DSN) { const getConfigLocal: getConfig = getConfigRedis const incomingAmqp: Incoming = new IncomingAmqp(getConfigLocal) - const outgoingCloudApi: Outgoing = new OutgoingCloudApi(getConfigLocal, isInBlacklistInRedis) const commanderJob = new CommanderJob(outgoingCloudApi, getConfigRedis) const bulkParserJob = new BulkParserJob(outgoingCloudApi, getConfigRedis) diff --git a/src/controllers/index_controller.ts b/src/controllers/index_controller.ts index d341d66c..98d0eba3 100644 --- a/src/controllers/index_controller.ts +++ b/src/controllers/index_controller.ts @@ -3,7 +3,6 @@ import logger from '../services/logger' import path from 'path' class IndexController { - public root(req: Request, res: Response) { logger.debug('root method %s', JSON.stringify(req.method)) logger.debug('root headers %s', JSON.stringify(req.headers)) diff --git a/src/controllers/marketing_messages_controller.ts b/src/controllers/marketing_messages_controller.ts index 91fb52d1..16993958 100644 --- a/src/controllers/marketing_messages_controller.ts +++ b/src/controllers/marketing_messages_controller.ts @@ -5,7 +5,6 @@ import { Outgoing } from '../services/outgoing' import { MessagesController } from './messages_controller' export class MarketingMessagesController extends MessagesController { - constructor(incoming: Incoming, outgoing: Outgoing) { super(incoming, outgoing) this.endpoint = 'marketing_messages' diff --git a/src/controllers/pairing_code_controller.ts b/src/controllers/pairing_code_controller.ts index d5e832f2..b7532e60 100644 --- a/src/controllers/pairing_code_controller.ts +++ b/src/controllers/pairing_code_controller.ts @@ -25,8 +25,8 @@ export class PairingCodeController { to: phone, type: 'text', text: { - body: 'Request Pairing code' - } + body: 'Request Pairing code', + }, } this.service.send(phone, message, {}) return res.status(200).json({ success: true }) diff --git a/src/controllers/registration_controller.ts b/src/controllers/registration_controller.ts index 004ecae4..56157a0f 100644 --- a/src/controllers/registration_controller.ts +++ b/src/controllers/registration_controller.ts @@ -43,4 +43,4 @@ export class RegistrationController { await this.logout.run(phone) return res.status(204).send() } -} \ No newline at end of file +} diff --git a/src/controllers/templates_controller.ts b/src/controllers/templates_controller.ts index 1bcc0a01..06adac94 100644 --- a/src/controllers/templates_controller.ts +++ b/src/controllers/templates_controller.ts @@ -58,7 +58,6 @@ export class TemplatesController { const templates = await store.dataStore.loadTemplates() return res.status(200).json({ data: templates }) } - } catch (e) { return res.status(400).json({ status: 'error', message: `${phone} could not create template, error: ${e.message}` }) } diff --git a/src/controllers/webhook_controller.ts b/src/controllers/webhook_controller.ts index add3e124..72b45926 100644 --- a/src/controllers/webhook_controller.ts +++ b/src/controllers/webhook_controller.ts @@ -35,7 +35,7 @@ export class WebhookController { const token = req.query['hub.verify_token'] const challenge = req.query['hub.challenge'] const config = (await this.getConfig(phone.replace('+', ''))) || { authToken: UNOAPI_AUTH_TOKEN } - + if (mode === 'subscribe' && token === config.authToken) { res.status(200).send(challenge) } else { diff --git a/src/controllers/webhook_fake_controller.ts b/src/controllers/webhook_fake_controller.ts index a061a5e4..1008963a 100644 --- a/src/controllers/webhook_fake_controller.ts +++ b/src/controllers/webhook_fake_controller.ts @@ -2,7 +2,6 @@ import { Request, Response } from 'express' import logger from '../services/logger' export class WebhookFakeController { - public async fake(req: Request, res: Response) { logger.debug('webhook fake method %s', req.method) logger.debug('webhook fake headers %s', JSON.stringify(req.headers)) diff --git a/src/defaults.ts b/src/defaults.ts index 313e8460..934d6803 100644 --- a/src/defaults.ts +++ b/src/defaults.ts @@ -14,7 +14,7 @@ export const UNO_LOG_LEVEL = process.env.UNO_LOG_LEVEL || LOG_LEVEL export const DEFAULT_LOCALE = process.env.DEFAULT_LOCALE || 'en' -export const VALIDATE_MEDIA_LINK_BEFORE_SEND = +export const VALIDATE_MEDIA_LINK_BEFORE_SEND = process.env.VALIDATE_MEDIA_LINK_BEFORE_SEND == _undefined ? false : process.env.VALIDATE_MEDIA_LINK_BEFORE_SEND == 'true' export const WEBHOOK_FORWARD_PHONE_NUMBER_ID = process.env.WEBHOOK_FORWARD_PHONE_NUMBER_ID || '' @@ -36,8 +36,10 @@ export const CONNECTION_TYPE = process.env.CONNECTION_TYPE || 'qrcode' export const CONSUMER_TIMEOUT_MS = parseInt(process.env.CONSUMER_TIMEOUT_MS || '360000') export const WEBHOOK_SEND_NEW_MESSAGES = process.env.WEBHOOK_SEND_NEW_MESSAGES == _undefined ? false : process.env.WEBHOOK_SEND_NEW_MESSAGES == 'true' -export const WEBHOOK_SEND_INCOMING_MESSAGES = process.env.WEBHOOK_SEND_INCOMING_MESSAGES == _undefined ? true : process.env.WEBHOOK_SEND_INCOMING_MESSAGES == 'true' -export const WEBHOOK_SEND_GROUP_MESSAGES = process.env.WEBHOOK_SEND_GROUP_MESSAGES == _undefined ? true : process.env.WEBHOOK_SEND_GROUP_MESSAGES == 'true' +export const WEBHOOK_SEND_INCOMING_MESSAGES = + process.env.WEBHOOK_SEND_INCOMING_MESSAGES == _undefined ? true : process.env.WEBHOOK_SEND_INCOMING_MESSAGES == 'true' +export const WEBHOOK_SEND_GROUP_MESSAGES = + process.env.WEBHOOK_SEND_GROUP_MESSAGES == _undefined ? true : process.env.WEBHOOK_SEND_GROUP_MESSAGES == 'true' export const WEBHOOK_SEND_OUTGOING_MESSAGES = process.env.WEBHOOK_SEND_OUTGOING_MESSAGES == _undefined ? true : process.env.WEBHOOK_SEND_OUTGOING_MESSAGES == 'true' export const WEBHOOK_SEND_TRANSCRIBE_AUDIO = @@ -65,7 +67,7 @@ export const SESSION_TTL: number = parseInt(process.env.SESSION_TTL || '-1') export const UNOAPI_X_COUNT_RETRIES: string = process.env.UNOAPI_X_COUNT_RETRIES || 'x-unoapi-count-retries' export const UNOAPI_X_MAX_RETRIES: string = process.env.UNOAPI_X_MAX_RETRIES || 'x-unoapi-max-retries' export const UNOAPI_EXCHANGE_NAME = process.env.UNOAPI_EXCHANGE_NAME || 'unoapi' -export const UNOAPI_EXCHANGE_BROKER_NAME =`${UNOAPI_EXCHANGE_NAME}.broker` +export const UNOAPI_EXCHANGE_BROKER_NAME = `${UNOAPI_EXCHANGE_NAME}.broker` export const UNOAPI_EXCHANGE_BRIDGE_NAME = `${UNOAPI_EXCHANGE_NAME}.brigde` export const UNOAPI_QUEUE_NAME = process.env.UNOAPI_QUEUE_NAME || 'unoapi' export const UNOAPI_QUEUE_OUTGOING_PREFETCH = parseInt(process.env.UNOAPI_QUEUE_OUTGOING_PREFETCH || '1') @@ -113,7 +115,8 @@ export const BASE_STORE = process.env.UNOAPI_BASE_STORE || process.env.BASE_STOR export const AUTO_CONNECT: boolean = process.env.AUTO_CONNECT === _undefined ? true : process.env.AUTO_CONNECT == 'true' export const COMPOSING_MESSAGE: boolean = process.env.COMPOSING_MESSAGE === _undefined ? false : process.env.COMPOSING_MESSAGE == 'true' export const IGNORE_GROUP_MESSAGES: boolean = process.env.IGNORE_GROUP_MESSAGES == _undefined ? true : process.env.IGNORE_GROUP_MESSAGES == 'true' -export const IGNORE_NEWSLETTER_MESSAGES: boolean = process.env.IGNORE_NEWSLETTER_MESSAGES == _undefined ? true : process.env.IGNORE_NEWSLETTER_MESSAGES == 'true' +export const IGNORE_NEWSLETTER_MESSAGES: boolean = + process.env.IGNORE_NEWSLETTER_MESSAGES == _undefined ? true : process.env.IGNORE_NEWSLETTER_MESSAGES == 'true' export const IGNORE_BROADCAST_STATUSES: boolean = process.env.IGNORE_BROADCAST_STATUSES === _undefined ? true : process.env.IGNORE_BROADCAST_STATUSES == 'true' export const READ_ON_RECEIPT: boolean = process.env.READ_ON_RECEIPT === _undefined ? false : process.env.READ_ON_RECEIPT == 'true' @@ -147,7 +150,7 @@ export const VALIDATE_ROUTING_KEY = process.env.VALIDATE_ROUTING_KEY === _undefi export const CONFIG_SESSION_PHONE_CLIENT = process.env.CONFIG_SESSION_PHONE_CLIENT || 'Unoapi' export const CONFIG_SESSION_PHONE_NAME = process.env.CONFIG_SESSION_PHONE_NAME || 'Chrome' export const MESSAGE_CHECK_WAAPP = process.env.MESSAGE_CHECK_WAAPP || '' -export const WHATSAPP_VERSION = process.env.WHATSAPP_VERSION ? JSON.parse(process.env.WHATSAPP_VERSION) as WAVersion : undefined +export const WHATSAPP_VERSION = process.env.WHATSAPP_VERSION ? (JSON.parse(process.env.WHATSAPP_VERSION) as WAVersion) : undefined export const AVAILABLE_LOCALES = JSON.parse(process.env.AVAILABLE_LOCALES || '["en", "pt_BR", "pt"]') export const WAVOIP_TOKEN = process.env.WAVOIP_TOKEN || '' export const ONLY_HELLO_TEMPLATE: boolean = process.env.ONLY_HELLO_TEMPLATE === _undefined ? false : process.env.ONLY_HELLO_TEMPLATE == 'true' diff --git a/src/i18n.ts b/src/i18n.ts index 6f5c608c..3b3ba8bc 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -12,7 +12,7 @@ const i18n = new I18n({ i18n.setLocale(DEFAULT_LOCALE) -export const t = (phraseOrOptions: string | TranslateOptions, ...replace: any[]) => { +export const t = (phraseOrOptions: string | TranslateOptions, ...replace: any[]) => { const string = i18n.__(phraseOrOptions, ...replace) return string -} \ No newline at end of file +} diff --git a/src/index.ts b/src/index.ts index 216a6033..88838260 100644 --- a/src/index.ts +++ b/src/index.ts @@ -43,7 +43,17 @@ const sessionStore: SessionStore = new SessionStoreFile() const reload = new ReloadBaileys(getClientBaileys, getConfigByEnv, listenerBaileys, onNewLoginn) const logout = new LogoutBaileys(getClientBaileys, getConfigByEnv, listenerBaileys, onNewLoginn) -const app: App = new App(incomingBaileys, outgoingCloudApi, BASE_URL, getConfigByEnv, sessionStore, onNewLoginn, addToBlacklistInMemory, reload, logout) +const app: App = new App( + incomingBaileys, + outgoingCloudApi, + BASE_URL, + getConfigByEnv, + sessionStore, + onNewLoginn, + addToBlacklistInMemory, + reload, + logout, +) broadcast.setSever(app.socket) app.server.listen(PORT, '0.0.0.0', async () => { @@ -68,4 +78,4 @@ process.on('unhandledRejection', (reason: any, promise) => { logger.error('unhandledRejection: %s', reason.stack) logger.error('promise: %s', promise) process.exit(1) -}) \ No newline at end of file +}) diff --git a/src/jobs/add_to_blacklist.ts b/src/jobs/add_to_blacklist.ts index 99241ddf..c63626da 100644 --- a/src/jobs/add_to_blacklist.ts +++ b/src/jobs/add_to_blacklist.ts @@ -6,4 +6,4 @@ export const addToBlacklist = async (_phone: string, data: object) => { logger.debug('Add blacklist from: %s, webhook: %s, to: %s, ttl: %s', from, webhookId, to, ttl) await addToBlacklistRedis(from, webhookId, to, ttl) } -export default addToBlacklist \ No newline at end of file +export default addToBlacklist diff --git a/src/jobs/bind_bridge.ts b/src/jobs/bind_bridge.ts index 93795eb3..be2b57fa 100644 --- a/src/jobs/bind_bridge.ts +++ b/src/jobs/bind_bridge.ts @@ -1,13 +1,7 @@ import { IncomingJob } from './incoming' import { ListenerJob } from './listener' import { Broadcast } from '../services/broadcast' -import { - UNOAPI_QUEUE_INCOMING, - UNOAPI_QUEUE_COMMANDER, - UNOAPI_QUEUE_LISTENER, - UNOAPI_SERVER_NAME, - UNOAPI_EXCHANGE_BRIDGE_NAME, -} from '../defaults' +import { UNOAPI_QUEUE_INCOMING, UNOAPI_QUEUE_COMMANDER, UNOAPI_QUEUE_LISTENER, UNOAPI_SERVER_NAME, UNOAPI_EXCHANGE_BRIDGE_NAME } from '../defaults' import { amqpConsume } from '../amqp' import { getConfig } from '../services/config' import { getConfigRedis } from '../services/config_redis' @@ -61,29 +55,29 @@ export class BindBridgeJob { logger.info('Starting listener baileys consumer %s', routingKey) await amqpConsume( UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_LISTENER}.${UNOAPI_SERVER_NAME}`, + `${UNOAPI_QUEUE_LISTENER}.${UNOAPI_SERVER_NAME}`, routingKey, listenerJob.consume.bind(listenerJob), { notifyFailedMessages, priority: 5, prefetch: 1, - type: 'direct' - } + type: 'direct', + }, ) logger.info('Starting incoming consumer %s', routingKey) await amqpConsume( UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_INCOMING}.${UNOAPI_SERVER_NAME}`, - routingKey, - incomingJob.consume.bind(incomingJob), + `${UNOAPI_QUEUE_INCOMING}.${UNOAPI_SERVER_NAME}`, + routingKey, + incomingJob.consume.bind(incomingJob), { notifyFailedMessages, priority: 5, prefetch: 1 /* allways 1 */, - type: 'direct' - } + type: 'direct', + }, ) } } diff --git a/src/jobs/bulk_parser.ts b/src/jobs/bulk_parser.ts index eec677dc..c19d86c0 100644 --- a/src/jobs/bulk_parser.ts +++ b/src/jobs/bulk_parser.ts @@ -235,9 +235,15 @@ export class BulkParserJob { }, } this.outgoing.formatAndSend(phone, phone, message) - await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, this.queueBulkSender, phone, { - payload: { messages, id, length: messages.length }, - }, { type: 'topic' }) + await amqpPublish( + UNOAPI_EXCHANGE_BROKER_NAME, + this.queueBulkSender, + phone, + { + payload: { messages, id, length: messages.length }, + }, + { type: 'topic' }, + ) } catch (error) { logger.error(error, 'Error on parse bulk') const message = { diff --git a/src/jobs/bulk_report.ts b/src/jobs/bulk_report.ts index fcc6b946..b717afca 100644 --- a/src/jobs/bulk_report.ts +++ b/src/jobs/bulk_report.ts @@ -29,13 +29,15 @@ export class BulkReportJob { if (count >= 10) { message = { body: `Bulk ${id} phone ${phone} with ${length}, has retried generate ${count} and not retried more` } } else { - message = { body: `Bulk ${id} phone ${phone} with ${length}, some messages is already scheduled status, try again later, this is ${count} try...` } + message = { + body: `Bulk ${id} phone ${phone} with ${length}, some messages is already scheduled status, try again later, this is ${count} try...`, + } await amqpPublish( UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_BULK_REPORT, phone, { payload: { id, length, count } }, - { delay: UNOAPI_BULK_DELAY * 1000, type: 'topic' } + { delay: UNOAPI_BULK_DELAY * 1000, type: 'topic' }, ) } } else { @@ -54,7 +56,7 @@ export class BulkReportJob { message = { url: base64, mime_type: 'text/csv', - filename, + filename, caption, id: mediaKey, } diff --git a/src/jobs/bulk_sender.ts b/src/jobs/bulk_sender.ts index 4e2cc375..c4d3d4d0 100644 --- a/src/jobs/bulk_sender.ts +++ b/src/jobs/bulk_sender.ts @@ -1,5 +1,12 @@ import { amqpPublish } from '../amqp' -import { UNOAPI_BULK_BATCH, UNOAPI_BULK_DELAY, UNOAPI_QUEUE_BULK_SENDER, UNOAPI_QUEUE_BULK_REPORT, UNOAPI_BULK_MESSAGE_DELAY, UNOAPI_EXCHANGE_BROKER_NAME } from '../defaults' +import { + UNOAPI_BULK_BATCH, + UNOAPI_BULK_DELAY, + UNOAPI_QUEUE_BULK_SENDER, + UNOAPI_QUEUE_BULK_REPORT, + UNOAPI_BULK_MESSAGE_DELAY, + UNOAPI_EXCHANGE_BROKER_NAME, +} from '../defaults' import { Incoming } from '../services/incoming' import { Outgoing } from '../services/outgoing' import { setMessageStatus, setbulkMessage } from '../services/redis' @@ -64,9 +71,10 @@ export class BulkSenderJob { statusMessage = `Bulk ${id} phone ${phone} is finished with ${messagesToSend.length} message(s)!` await amqpPublish( UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_BULK_REPORT, phone, - { payload: { id, length } }, - { delay: UNOAPI_BULK_DELAY * 1000, type: 'topic' } + UNOAPI_QUEUE_BULK_REPORT, + phone, + { payload: { id, length } }, + { delay: UNOAPI_BULK_DELAY * 1000, type: 'topic' }, ) } const messageUpdate = { diff --git a/src/jobs/commander.ts b/src/jobs/commander.ts index 6670ae7c..2fdcc324 100644 --- a/src/jobs/commander.ts +++ b/src/jobs/commander.ts @@ -39,16 +39,18 @@ export class CommanderJob { logger.debug(`Commander processing`) const id = uuid() await amqpPublish( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_BULK_PARSER, - phone, { + UNOAPI_EXCHANGE_BROKER_NAME, + UNOAPI_QUEUE_BULK_PARSER, + phone, + { phone, payload: { id, template: 'sisodonto', url: payload?.document?.link, }, - }, { type: 'topic' } + }, + { type: 'topic' }, ) const message = { type: 'text', @@ -73,7 +75,7 @@ export class CommanderJob { const config = { webhooks } logger.debug('Template webhooks %s', phone, JSON.stringify(webhooks)) await setConfig(phone, config) - await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, `${UNOAPI_QUEUE_RELOAD}.${currentConfig.server!}`, phone , { phone }, { type: 'topic' }) + await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, `${UNOAPI_QUEUE_RELOAD}.${currentConfig.server!}`, phone, { phone }, { type: 'topic' }) } else if (payload?.to && phone === payload?.to && payload?.template && payload?.template.name == 'unoapi-bulk-report') { logger.debug('Parsing bulk report template... %s', phone) const service = new Template(this.getConfig) @@ -85,7 +87,13 @@ export class CommanderJob { throw new YamlParseError(doc.errors) } const { bulk } = doc.toJS() - await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_BULK_REPORT, phone, { payload: { phone, id: bulk, unverified: true } }, { type: 'topic' }) + await amqpPublish( + UNOAPI_EXCHANGE_BROKER_NAME, + UNOAPI_QUEUE_BULK_REPORT, + phone, + { payload: { phone, id: bulk, unverified: true } }, + { type: 'topic' }, + ) } else if (payload?.to && phone === payload?.to && payload?.template && payload?.template.name == 'unoapi-config') { logger.debug('Parsing config template... %s', phone) const service = new Template(this.getConfig) diff --git a/src/jobs/incoming.ts b/src/jobs/incoming.ts index 1c233621..49471f22 100644 --- a/src/jobs/incoming.ts +++ b/src/jobs/incoming.ts @@ -26,7 +26,7 @@ export class IncomingJob { const config = await this.getConfig(phone) if (config.server !== UNOAPI_SERVER_NAME) { logger.info(`Ignore incoming with ${phone} server ${config.server} is not server current server ${UNOAPI_SERVER_NAME}...`) - return; + return } // eslint-disable-next-line @typescript-eslint/no-explicit-any const a = data as any @@ -46,7 +46,7 @@ export class IncomingJob { await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, this.queueCommander, phone, { payload }, { type: 'topic' }) } const { ok, error } = response - const optionsOutgoing: Partial = {} + const optionsOutgoing: Partial = {} if (ok && ok.messages && ok.messages[0] && ok.messages[0].id) { const idProvider: string = ok.messages[0].id logger.debug('%s id %s to Unoapi id %s', config.provider, idProvider, idUno) @@ -64,7 +64,7 @@ export class IncomingJob { const mimetype = getMimetype(payload) const extension = mime.extension(mimetype) const fileName = `${mediaKey}.${extension}` - const response: Response = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'GET'}) + const response: Response = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'GET' }) const buffer = toBuffer(await response.arrayBuffer()) await mediaStore.saveMediaBuffer(fileName, buffer) messagePayload = { @@ -176,13 +176,7 @@ export class IncomingJob { ], } } - await amqpPublish( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_BULK_STATUS, - phone, - { payload: outgingPayload, type: 'whatsapp' }, - { type: 'topic' } - ) + await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_BULK_STATUS, phone, { payload: outgingPayload, type: 'whatsapp' }, { type: 'topic' }) await Promise.all(config.webhooks.map((w) => this.outgoing.sendHttp(phone, w, outgingPayload, optionsOutgoing))) return response } diff --git a/src/jobs/listener.ts b/src/jobs/listener.ts index 765208de..41df09f6 100644 --- a/src/jobs/listener.ts +++ b/src/jobs/listener.ts @@ -17,15 +17,15 @@ export class ListenerJob { this.getConfig = getConfig } - async consume(phone: string, data: object, options?: { countRetries: number; maxRetries: number, priority: 0 }) { + async consume(phone: string, data: object, options?: { countRetries: number; maxRetries: number; priority: 0 }) { const config = await this.getConfig(phone) if (config.server !== UNOAPI_SERVER_NAME) { logger.info(`Ignore listener routing key ${phone} server ${config.server} is not server current server ${UNOAPI_SERVER_NAME}...`) - return; + return } if (config.provider !== 'baileys') { logger.info(`Ignore listener routing key ${phone} is not provider baileys...`) - return; + return } // eslint-disable-next-line @typescript-eslint/no-explicit-any const a = data as any @@ -50,21 +50,21 @@ export class ListenerJob { `${UNOAPI_QUEUE_LISTENER}.${UNOAPI_SERVER_NAME}`, phone, { messages: { keys: [m] }, type, splited: true }, - { type: 'direct' } + { type: 'direct' }, ) - }) + }), ) } else { - await Promise.all(messages. - map(async (m: object) => { + await Promise.all( + messages.map(async (m: object) => { return amqpPublish( UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_LISTENER}.${UNOAPI_SERVER_NAME}`, phone, { messages: [m], type, splited: true }, - { type: 'direct' } + { type: 'direct' }, ) - }) + }), ) } } diff --git a/src/jobs/outgoing.ts b/src/jobs/outgoing.ts index 2f74f573..5f1b7bdf 100644 --- a/src/jobs/outgoing.ts +++ b/src/jobs/outgoing.ts @@ -7,46 +7,48 @@ import { UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_OUTGOING, UNOAPI_QUEUE_TRANSCRIBER, - UNOAPI_QUEUE_WEBHOOK_STATUS_FAILED + UNOAPI_QUEUE_WEBHOOK_STATUS_FAILED, } from '../defaults' import { extractDestinyPhone, isAudioMessage, isIncomingMessage, jidToPhoneNumber, TYPE_MESSAGES_MEDIA } from '../services/transformer' import logger from '../services/logger' import { getConfig } from '../services/config' import { isUpdateMessage, isFailedStatus } from '../services/transformer' -const dUntil: Map = new Map() -const dVerified: Map = new Map() +const dUntil: Map = new Map() +const dVerified: Map = new Map() const sleep = (ms) => { return new Promise((resolve) => setTimeout(resolve, ms)) } -const delayFunc = UNOAPI_DELAY_AFTER_FIRST_MESSAGE_WEBHOOK_MS ? async (phone, payload) => { - const to = extractDestinyPhone(payload, false) - - if (to) { - const key = `${phone}:${to}` - if (!dVerified.get(key)) { - let nextMessageTime = dUntil.get(key) - const epochMS: number = Math.floor(Date.now()); - if (nextMessageTime === undefined) { - nextMessageTime = epochMS + UNOAPI_DELAY_AFTER_FIRST_MESSAGE_WEBHOOK_MS - dUntil.set(key, nextMessageTime); - logger.debug('Key %s First message', key) - } else { - const thisMessageDelay: number = Math.floor(nextMessageTime - epochMS) - if (thisMessageDelay > 0) { - logger.debug('Key %s Message delayed by %s ms', key, thisMessageDelay) - await sleep(thisMessageDelay) - } else { - logger.debug('Key %s doesn\'t need more delays', key) - dVerified.set(key, true); - dUntil.delete(key); +const delayFunc = UNOAPI_DELAY_AFTER_FIRST_MESSAGE_WEBHOOK_MS + ? async (phone, payload) => { + const to = extractDestinyPhone(payload, false) + + if (to) { + const key = `${phone}:${to}` + if (!dVerified.get(key)) { + let nextMessageTime = dUntil.get(key) + const epochMS: number = Math.floor(Date.now()) + if (nextMessageTime === undefined) { + nextMessageTime = epochMS + UNOAPI_DELAY_AFTER_FIRST_MESSAGE_WEBHOOK_MS + dUntil.set(key, nextMessageTime) + logger.debug('Key %s First message', key) + } else { + const thisMessageDelay: number = Math.floor(nextMessageTime - epochMS) + if (thisMessageDelay > 0) { + logger.debug('Key %s Message delayed by %s ms', key, thisMessageDelay) + await sleep(thisMessageDelay) + } else { + logger.debug("Key %s doesn't need more delays", key) + dVerified.set(key, true) + dUntil.delete(key) + } + } } - } + } } - } -} : async (_phone, _payload) => {} + : async (_phone, _payload) => {} export class OutgoingJob { private service: Outgoing @@ -64,28 +66,22 @@ export class OutgoingJob { if (a.webhooks) { const webhooks: Webhook[] = a.webhooks if (isFailedStatus(payload) && STATUS_FAILED_WEBHOOK_URL) { - await amqpPublish( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_WEBHOOK_STATUS_FAILED, - phone, - { payload }, - { type: 'topic' } - ) + await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_WEBHOOK_STATUS_FAILED, phone, { payload }, { type: 'topic' }) } await Promise.all( webhooks.map(async (webhook) => { - return amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_OUTGOING, phone, { payload, webhook }) + return amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_OUTGOING, phone, { payload, webhook }) }), ) if (isAudioMessage(payload)) { - const webhooks = a.webhooks.filter(w => { + const webhooks = a.webhooks.filter((w) => { if (w.sendTranscribeAudio) { logger.debug('Session phone %s webhook %s configured to send transcribe audio message for this webhook', phone, w.id) return true } }) if (webhooks.length > 0) { - await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_TRANSCRIBER, phone, { payload, webhooks }, { type: 'topic' }) + await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_TRANSCRIBER, phone, { payload, webhooks }, { type: 'topic' }) } } } else if (a.webhook) { @@ -97,25 +93,25 @@ export class OutgoingJob { const { dataStore } = store if (isUpdateMessage(payload)) { payload.entry[0].changes[0].value.statuses = await Promise.all( - payload.entry[0].changes[0].value.statuses.map(async status => { + payload.entry[0].changes[0].value.statuses.map(async (status) => { const currentId = status.id const unoId = await dataStore.loadUnoId(currentId) if (unoId) { status.id = unoId } return status - }) + }), ) } else { payload.entry[0].changes[0].value.contacts = await Promise.all( - payload.entry[0].changes[0].value.contacts.map(async contact => { + payload.entry[0].changes[0].value.contacts.map(async (contact) => { contact.wa_id = jidToPhoneNumber(contact.wa_id, '') return contact - }) + }), ) payload.entry[0].changes[0].value.messages = await Promise.all( - payload.entry[0].changes[0].value.messages.map(async message => { + payload.entry[0].changes[0].value.messages.map(async (message) => { if (TYPE_MESSAGES_MEDIA.includes(message.type)) { const { mediaStore } = store message = await mediaStore.saveMediaForwarder(message) @@ -134,7 +130,7 @@ export class OutgoingJob { } message.from = jidToPhoneNumber(message.from, '') return message - }) + }), ) } } diff --git a/src/jobs/reload.ts b/src/jobs/reload.ts index 85420b25..b3325c59 100644 --- a/src/jobs/reload.ts +++ b/src/jobs/reload.ts @@ -1,4 +1,4 @@ -import logger from '../services/logger'; +import logger from '../services/logger' import { Reload } from '../services/reload' export class ReloadJob { diff --git a/src/jobs/timer.ts b/src/jobs/timer.ts index c938045d..a15d96da 100644 --- a/src/jobs/timer.ts +++ b/src/jobs/timer.ts @@ -19,7 +19,7 @@ export class TimerJob { const string = await this.getLastTimerFunction(phone, to) const lastTime = string ? Date.parse(string) : undefined logger.debug('timer comsumer phone %s to %s time %s last time %s', phone, to, time, lastTime) - if (!lastTime || (lastTime > messageDate)) { + if (!lastTime || lastTime > messageDate) { logger.debug('timer comsumer expired phone %s to %s', phone, to) } else { logger.debug('timer consumer enqueue phone %s to %s', phone, to) @@ -28,8 +28,8 @@ export class TimerJob { to, type: 'text', text: { - body: message - } + body: message, + }, } await this.incoming.send(phone, body, {}) } diff --git a/src/jobs/transcriber.ts b/src/jobs/transcriber.ts index f3404470..51c9e9d9 100644 --- a/src/jobs/transcriber.ts +++ b/src/jobs/transcriber.ts @@ -22,20 +22,11 @@ export class TranscriberJob { const { payload, webhooks }: { payload: any; webhooks: Webhook[] } = data as any const destinyPhone = extractDestinyPhone(payload) const payloadEntry = payload?.entry && payload.entry[0] - const payloadValue = payloadEntry && - payload.entry[0].changes && - payload.entry[0].changes[0] && - payload.entry[0].changes[0].value - const audioMessage = payloadValue && - payload.entry[0].changes[0].value.messages && - payload.entry[0].changes[0].value.messages[0] + const payloadValue = payloadEntry && payload.entry[0].changes && payload.entry[0].changes[0] && payload.entry[0].changes[0].value + const audioMessage = payloadValue && payload.entry[0].changes[0].value.messages && payload.entry[0].changes[0].value.messages[0] const mediaKey = audioMessage.audio.id const mediaUrl = `${BASE_URL}/v13.0/${mediaKey}` - const { buffer, link }= await mediaToBuffer( - mediaUrl, - UNOAPI_AUTH_TOKEN!, - webhooks[0].timeoutMs || 0, - ) + const { buffer, link } = await mediaToBuffer(mediaUrl, UNOAPI_AUTH_TOKEN!, webhooks[0].timeoutMs || 0) let transcriptionText = '' if (OPENAI_API_KEY) { logger.debug('Transcriber audio with OpenAI for session %s to %s', phone, destinyPhone) @@ -50,9 +41,9 @@ export class TranscriberJob { } else { logger.debug('Transcriber audio with Audio2TextJS for session %s to %s', phone, destinyPhone) const converter = new Audio2TextJS({ - threads: 4, - processors: 1, - outputJson: true, + threads: 4, + processors: 1, + outputJson: true, }) if (!existsSync(SESSION_DIR)) { mkdirSync(SESSION_DIR) @@ -68,17 +59,19 @@ export class TranscriberJob { } logger.debug('Transcriber audio content for session %s and to %s is %s', phone, destinyPhone, transcriptionText) const output = { ...payload } - output.entry[0].changes[0].value.messages = [{ - context: { - message_id: audioMessage.id, - id: audioMessage.id, + output.entry[0].changes[0].value.messages = [ + { + context: { + message_id: audioMessage.id, + id: audioMessage.id, + }, + from: audioMessage.from, + id: uuid(), + text: { body: transcriptionText }, + type: 'text', + timestamp: `${parseInt(audioMessage.timestamp) + 1}`, }, - from: audioMessage.from, - id: uuid(), - text: { body: transcriptionText }, - type: 'text', - timestamp: `${parseInt(audioMessage.timestamp) + 1}`, - }] + ] await Promise.all( webhooks.map(async (w) => { logger.debug('Transcriber phone %s to %s sending webhook %s', phone, destinyPhone, w.id) diff --git a/src/jobs/webhook_status_failed.ts b/src/jobs/webhook_status_failed.ts index 317229a4..28b3139d 100644 --- a/src/jobs/webhook_status_failed.ts +++ b/src/jobs/webhook_status_failed.ts @@ -1,4 +1,4 @@ -import logger from "../services/logger"; +import logger from '../services/logger' export class WebhookStatusFailedJob { private url: string @@ -14,10 +14,10 @@ export class WebhookStatusFailedJob { await fetch(this.url, { method: 'POST', headers: { - 'Content-Type': 'application/json; charset=utf-8' + 'Content-Type': 'application/json; charset=utf-8', }, body: JSON.stringify({ text }), - }); + }) } catch (error) { logger.error('Error on webhook status failed') logger.error(error) diff --git a/src/locales/en.json b/src/locales/en.json index a180d859..55efcff4 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,27 +1,27 @@ { - "without_whatsapp": "The phone number %s does not have Whatsapp account!", - "invalid_phone_number": "The phone number %s is invalid!", - "offline_session": "offline session, connecting....", - "disconnected_session": "disconnect number, please send a message do try reconnect and read qr code if necessary", + "without_whatsapp": "The phone number %s does not have Whatsapp account!", + "invalid_phone_number": "The phone number %s is invalid!", + "offline_session": "offline session, connecting....", + "disconnected_session": "disconnect number, please send a message do try reconnect and read qr code if necessary", "reloaded_session": "Session reloaded, send a message to connect again", - "connecting_session": "Wait a moment, connecting process", + "connecting_session": "Wait a moment, connecting process", "invalid_link": "Error on retrieve media, http status %s in link %s", - "attempts_exceeded": "The %s times of generate qrcode is exceeded!", - "received_pending_notifications": "Received pending notifications", - "online_session": "Online session", - "connection_timed_out": "Connecting %s timed out %s ms, change to disconnect", - "connecting": "Connecting...", - "connected": "Connected with %s using Whatsapp Version v%s, latest Baileys version is v%s at %s", - "removed": "The session is removed in Whatsapp App, send a message here to reconnect!", - "unique": "The session must be unique, close connection, send a message here to reconnect if him was offline!", - "closed": "The connection is closed with status: %s, detail: %s!", - "connecting_attemps": "Try connnecting time %s of %s...", - "qrcode_attemps": "Please, read the QR Code to connect on Whatsapp Web, attempt %s of %s", - "auto_restart": "Config to auto restart in %s milliseconds.", - "failed_decrypt": "🕒 The message could not be read. Please ask to send it again or open WhatsApp on your phone.", - "error": "Error -> %s.", - "on_read_qrcode": "Awesome, read the qrcode if you not yet. For now you need to update config to use this auth token %s", - "pairing_code": "Open your WhatsApp and go to: Connected Devices > Connect a new Device > Connect using phone number > And put your connection code > %s", + "attempts_exceeded": "The %s times of generate qrcode is exceeded!", + "received_pending_notifications": "Received pending notifications", + "online_session": "Online session", + "connection_timed_out": "Connecting %s timed out %s ms, change to disconnect", + "connecting": "Connecting...", + "connected": "Connected with %s using Whatsapp Version v%s, latest Baileys version is v%s at %s", + "removed": "The session is removed in Whatsapp App, send a message here to reconnect!", + "unique": "The session must be unique, close connection, send a message here to reconnect if him was offline!", + "closed": "The connection is closed with status: %s, detail: %s!", + "connecting_attemps": "Try connnecting time %s of %s...", + "qrcode_attemps": "Please, read the QR Code to connect on Whatsapp Web, attempt %s of %s", + "auto_restart": "Config to auto restart in %s milliseconds.", + "failed_decrypt": "🕒 The message could not be read. Please ask to send it again or open WhatsApp on your phone.", + "error": "Error -> %s.", + "on_read_qrcode": "Awesome, read the qrcode if you not yet. For now you need to update config to use this auth token %s", + "pairing_code": "Open your WhatsApp and go to: Connected Devices > Connect a new Device > Connect using phone number > And put your connection code > %s", "restart": "Restarting session", "standby": "Standby session, waiting for time configured to try connect again, %s error in %s seconds", "proxy_error": "Error on connect to proxy: %s", @@ -29,4 +29,4 @@ "waiting_information": "Waiting for qrcode/pairing code", "reload": "Reload", "deleted_message": "Deleted message: " -} \ No newline at end of file +} diff --git a/src/locales/pt.json b/src/locales/pt.json index ff23a0b0..9f7deb4d 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -6,22 +6,22 @@ "reloaded_session": "Sessão terminada, envie uma mensagem para conectar novamente", "connecting_session": "Aguarde um momento, a estabelecer a sessão...", "invalid_link": "Houve um erro ao carregar o conteúdo, estado %s, link %s", - "attempts_exceeded": "O limite de %s vezes de geração de QR Code foi excedido!", - "received_pending_notifications": "A sincronizar mensagens enviadas enquanto estava offline", - "online_session": "Sessão estabelecida", - "connection_timed_out": "A sessão %s excedeu o tempo de %s ms, sessão alterada para estado Offline", - "connecting": "A estabelecer...", - "connected": "Sessão do número %s estabelecida, versão do WhatsApp v%s, a última versão do WhatsApp v%s, às %s", - "removed": "A sessão foi removida via aplicação WhatsApp, envie uma nova mensagem para gerar novo QR Code e voltar a estabelecer a ligação!", - "unique": "A sessão só pode ser estabelecida uma vez, a atual sessão está a ser desligada, envie uma mensagem para voltar a estabelecer a ligação!", - "closed": "A sessão foi encerrada com o estado: %s, detalhe: %s!", - "connecting_attemps": "Tentativa de estabelecimento de sessão %s de %s...", - "qrcode_attemps": "Por favor, leia QR Code para estabelecer a ligação, tentativa %s de %s", - "auto_restart": "Configurado para reiniciar a sessão a cada %s milliseconds.", - "failed_decrypt": "🕒 Não foi possível apresentar a mensagem. Peça para enviar novamente a mensagem ou abra a APP do Whatsapp para ver o conteúdo.", - "error": "Erro não previsto: %s.", - "on_read_qrcode": "Fantástico, se ainda não o fez, leia o QR Code. O token de authenticação para esta sessão é %s", - "pairing_code": "Informe o código para conectar no whatsapp > %s", + "attempts_exceeded": "O limite de %s vezes de geração de QR Code foi excedido!", + "received_pending_notifications": "A sincronizar mensagens enviadas enquanto estava offline", + "online_session": "Sessão estabelecida", + "connection_timed_out": "A sessão %s excedeu o tempo de %s ms, sessão alterada para estado Offline", + "connecting": "A estabelecer...", + "connected": "Sessão do número %s estabelecida, versão do WhatsApp v%s, a última versão do WhatsApp v%s, às %s", + "removed": "A sessão foi removida via aplicação WhatsApp, envie uma nova mensagem para gerar novo QR Code e voltar a estabelecer a ligação!", + "unique": "A sessão só pode ser estabelecida uma vez, a atual sessão está a ser desligada, envie uma mensagem para voltar a estabelecer a ligação!", + "closed": "A sessão foi encerrada com o estado: %s, detalhe: %s!", + "connecting_attemps": "Tentativa de estabelecimento de sessão %s de %s...", + "qrcode_attemps": "Por favor, leia QR Code para estabelecer a ligação, tentativa %s de %s", + "auto_restart": "Configurado para reiniciar a sessão a cada %s milliseconds.", + "failed_decrypt": "🕒 Não foi possível apresentar a mensagem. Peça para enviar novamente a mensagem ou abra a APP do Whatsapp para ver o conteúdo.", + "error": "Erro não previsto: %s.", + "on_read_qrcode": "Fantástico, se ainda não o fez, leia o QR Code. O token de authenticação para esta sessão é %s", + "pairing_code": "Informe o código para conectar no whatsapp > %s", "restart": "Reiniciando sessão", "standby": "Sessão colocada em standby, esperando pelo tempo configurado para tentar conectar novamente: %s", "proxy_error": "Erro ao conectar no proxy: %s", @@ -29,4 +29,4 @@ "waiting_information": "Esperando por qrcode/pairing code", "reload": "Recarregar", "deleted_message": "Esta mensagem foi apagada: " -} \ No newline at end of file +} diff --git a/src/locales/pt_BR.json b/src/locales/pt_BR.json index 3548a4db..c2f5497d 100644 --- a/src/locales/pt_BR.json +++ b/src/locales/pt_BR.json @@ -6,22 +6,22 @@ "reloaded_session": "Sessão terminada, envie uma mensagem para conectar novamente", "connecting_session": "Espere um momento, conectando a sessão...", "invalid_link": "Houve um erro ao recuperar a midia, status %s para o link %s", - "attempts_exceeded": "O limite de %s vezes de geração de qrcode foi excedida!", - "received_pending_notifications": "Recebendo mensagens enviadas enquanto estava offline", - "online_session": "Sessão está online", - "connection_timed_out": "A sessão %s excedeu o tempo de %s ms para conectar, sessão alterada para estado Offline", - "connecting": "Conectando...", - "connected": "Conectado com o número %s utilizando a versao do Whatsapp v%s, a última versão do WhatsApp v%s, às %s", - "removed": "A sessão foi removida no aplicativo do Whatsapp, envie uma mesagem para gerar o qrcode e conectar novamente!", - "unique": "A sessão só pode ser conectado uma vez, saindo da atual, envia uma mensagem para conectar novamente!", - "closed": "A sessão for encerrada com status: %s, detalhe: %s!", - "connecting_attemps": "Tentativa de conexão %s de %s...", - "qrcode_attemps": "Por favor, leia QR Code para conectar, tentativa %s de %s", - "auto_restart": "Configura para reiniciar a sessão a cada %s milliseconds.", - "failed_decrypt": "🕒 Não foi possível ler a mensagem. Peça para enviar novamente ou abra o Whatsapp no celular.", - "error": "Erro não tratado: %s.", - "on_read_qrcode": "Maravilha, leia o qrcode, se ainda não leu. O token de authenticação para essa sessão é %s", - "pairing_code": "Informe o código para conectar no whatsapp: %s", + "attempts_exceeded": "O limite de %s vezes de geração de qrcode foi excedida!", + "received_pending_notifications": "Recebendo mensagens enviadas enquanto estava offline", + "online_session": "Sessão está online", + "connection_timed_out": "A sessão %s excedeu o tempo de %s ms para conectar, sessão alterada para estado Offline", + "connecting": "Conectando...", + "connected": "Conectado com o número %s utilizando a versao do Whatsapp v%s, a última versão do WhatsApp v%s, às %s", + "removed": "A sessão foi removida no aplicativo do Whatsapp, envie uma mesagem para gerar o qrcode e conectar novamente!", + "unique": "A sessão só pode ser conectado uma vez, saindo da atual, envia uma mensagem para conectar novamente!", + "closed": "A sessão for encerrada com status: %s, detalhe: %s!", + "connecting_attemps": "Tentativa de conexão %s de %s...", + "qrcode_attemps": "Por favor, leia QR Code para conectar, tentativa %s de %s", + "auto_restart": "Configura para reiniciar a sessão a cada %s milliseconds.", + "failed_decrypt": "🕒 Não foi possível ler a mensagem. Peça para enviar novamente ou abra o Whatsapp no celular.", + "error": "Erro não tratado: %s.", + "on_read_qrcode": "Maravilha, leia o qrcode, se ainda não leu. O token de authenticação para essa sessão é %s", + "pairing_code": "Informe o código para conectar no whatsapp: %s", "restart": "Reiniciando sessão", "standby": "Sessão colocada em standby, esperando pelo tempo configurado para tentar conectar novamente: %s", "proxy_error": "Erro ao conectar no proxy: %s", @@ -29,4 +29,4 @@ "waiting_information": "Esperando por qrcode/pairing code", "reload": "Recarregar", "deleted_message": "Esta mensagem foi apagada: " -} \ No newline at end of file +} diff --git a/src/router.ts b/src/router.ts index b1662aa4..9d7e964d 100644 --- a/src/router.ts +++ b/src/router.ts @@ -30,7 +30,6 @@ import { ContactDummy } from './services/contact_dummy' import { middlewareNext } from './services/middleware_next' import { TimerController } from './controllers/timer_controller' - export const router = ( incoming: Incoming, outgoing: Outgoing, @@ -62,7 +61,6 @@ export const router = ( const connectController = new ConnectController(reload) const timerController = new TimerController() - // Webhook for forward connection router.post('/webhooks/whatsapp/:phone', webhookController.whatsapp.bind(webhookController)) router.get('/webhooks/whatsapp/:phone', middleware, webhookController.whatsappVerify.bind(webhookController)) diff --git a/src/services/auto_connect.ts b/src/services/auto_connect.ts index 6b1cc315..be82b4e7 100644 --- a/src/services/auto_connect.ts +++ b/src/services/auto_connect.ts @@ -22,22 +22,22 @@ export const autoConnect = async ( const config = await getConfig(phone) if (config.provider && !['forwarder', 'baileys'].includes(config.provider)) { logger.info(`Ignore connecting phone ${phone} provider ${config.provider}...`) - continue; + continue } if (config.server !== UNOAPI_SERVER_NAME) { logger.info(`Ignore connecting phone ${phone} server ${config.server} is not server current server ${UNOAPI_SERVER_NAME}...`) - continue; + continue } await sessionStore.syncConnection(phone) if (await sessionStore.isStatusStandBy(phone)) { logger.info(`Session standby ${phone}...`) - continue; + continue } logger.info(`Auto connecting phone ${phone}...`) try { const store = await config.getStore(phone, config) const { sessionStore } = store - if (await sessionStore.isStatusConnecting(phone) || await sessionStore.isStatusOnline(phone)) { + if ((await sessionStore.isStatusConnecting(phone)) || (await sessionStore.isStatusOnline(phone))) { logger.info(`Update session status to auto connect ${phone}...`) await sessionStore.setStatus(phone, 'offline') } diff --git a/src/services/blacklist.ts b/src/services/blacklist.ts index 09e110ad..c4c5128c 100644 --- a/src/services/blacklist.ts +++ b/src/services/blacklist.ts @@ -52,9 +52,9 @@ export const isInBlacklistInRedis: isInBlacklist = async (from: string, webhookI const pattern = `${blacklist('', '', '').replaceAll('::', '')}*` const keys = await redisKeys(pattern) logger.info(`Load ${keys.length} items in blacklist`) - const promises = keys.map(async key => { + const promises = keys.map(async (key) => { const ttl = await redisTtl(key) - const [ _k, from, webhookId, to ] = key.split(':') + const [_k, from, webhookId, to] = key.split(':') return addToBlacklistInMemory(from, webhookId, to, ttl) }) await Promise.all(promises) @@ -71,4 +71,4 @@ export const addToBlacklistRedis: addToBlacklist = async (from: string, webhookI export const addToBlacklistJob: addToBlacklist = async (from: string, webhookId: string, to: string, ttl: number) => { await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_BLACKLIST_ADD, from, { from, webhookId, to, ttl }, { type: 'topic' }) return true -} \ No newline at end of file +} diff --git a/src/services/broadcast.ts b/src/services/broadcast.ts index dcf5df12..077816c5 100644 --- a/src/services/broadcast.ts +++ b/src/services/broadcast.ts @@ -14,4 +14,3 @@ export class Broadcast { await this.server.emit('broadcast', { phone, type, content }) } } - \ No newline at end of file diff --git a/src/services/client.ts b/src/services/client.ts index 61b4fbc1..ddee571f 100644 --- a/src/services/client.ts +++ b/src/services/client.ts @@ -5,7 +5,7 @@ import { Listener } from './listener' export const clients: Map = new Map() -export type ContactStatus = 'valid' | 'processing' | 'invalid'| 'failed' +export type ContactStatus = 'valid' | 'processing' | 'invalid' | 'failed' export interface Contact { wa_id: String | undefined @@ -14,17 +14,7 @@ export interface Contact { } export interface getClient { - ({ - phone, - listener, - getConfig, - onNewLogin, - }: { - phone: string - listener: Listener - getConfig: getConfig - onNewLogin: OnNewLogin - }): Promise + ({ phone, listener, getConfig, onNewLogin }: { phone: string; listener: Listener; getConfig: getConfig; onNewLogin: OnNewLogin }): Promise } export class ConnectionInProgress extends Error { @@ -37,7 +27,7 @@ export interface Client { connect(time: number): Promise disconnect(): Promise - + logout(): Promise // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/services/client_baileys.ts b/src/services/client_baileys.ts index fdf8113b..dd1f7f12 100644 --- a/src/services/client_baileys.ts +++ b/src/services/client_baileys.ts @@ -19,7 +19,14 @@ import { } from './socket' import { Client, getClient, clients, Contact } from './client' import { Config, configs, defaultConfig, getConfig, getMessageMetadataDefault } from './config' -import { toBaileysMessageContent, phoneNumberToJid, jidToPhoneNumber, getMessageType, TYPE_MESSAGES_TO_READ, TYPE_MESSAGES_MEDIA } from './transformer' +import { + toBaileysMessageContent, + phoneNumberToJid, + jidToPhoneNumber, + getMessageType, + TYPE_MESSAGES_TO_READ, + TYPE_MESSAGES_MEDIA, +} from './transformer' import { v1 as uuid } from 'uuid' import { Response } from './response' import QRCode from 'qrcode' @@ -33,134 +40,127 @@ import { SendError } from './send_error' // Adicione esta classe antes da classe ClientBaileys class PresignedLinkValidator { private static isPresignedLink(url: string): boolean { - return url.includes('X-Amz-Algorithm') || - url.includes('response-content-disposition') || - url.includes('X-Amz-Signature'); + return url.includes('X-Amz-Algorithm') || url.includes('response-content-disposition') || url.includes('X-Amz-Signature') } static async validateLink(url: string): Promise { - const isPresigned = this.isPresignedLink(url); + const isPresigned = this.isPresignedLink(url) if (!isPresigned) { // Para links normais, tenta HEAD primeiro, depois GET como fallback try { const response = await fetch(url, { signal: AbortSignal.timeout(10000), - method: 'HEAD' - }); - return response.ok; + method: 'HEAD', + }) + return response.ok } catch (error) { - logger.warn(`Normal link HEAD failed, trying GET: ${error.message}`); + logger.warn(`Normal link HEAD failed, trying GET: ${error.message}`) try { const response = await fetch(url, { signal: AbortSignal.timeout(10000), method: 'GET', headers: { - 'Range': 'bytes=0-0' - } - }); - return response.ok; + Range: 'bytes=0-0', + }, + }) + return response.ok } catch (getError) { - logger.warn(`Normal link validation failed: ${getError.message}`); - return false; + logger.warn(`Normal link validation failed: ${getError.message}`) + return false } } } // Para links pré-assinados, usa GET com Range para evitar problemas com HEAD - logger.info(`Detected presigned link, starting validation with GET Range: ${url}`); + logger.info(`Detected presigned link, starting validation with GET Range: ${url}`) - const maxAttempts = 40; - const baseDelay = 1500; - const maxDelay = 15000; - const totalTimeout = 8 * 60 * 1000; + const maxAttempts = 40 + const baseDelay = 1500 + const maxDelay = 15000 + const totalTimeout = 8 * 60 * 1000 - const startTime = Date.now(); + const startTime = Date.now() for (let attempt = 1; attempt <= maxAttempts; attempt++) { if (Date.now() - startTime > totalTimeout) { - logger.warn(`Presigned link validation timeout after ${totalTimeout}ms: ${url}`); - throw new SendError(11, t('link_validation_timeout', url)); + logger.warn(`Presigned link validation timeout after ${totalTimeout}ms: ${url}`) + throw new SendError(11, t('link_validation_timeout', url)) } try { - logger.debug(`Validating presigned link attempt ${attempt}/${maxAttempts}: ${url}`); + logger.debug(`Validating presigned link attempt ${attempt}/${maxAttempts}: ${url}`) // Usa GET com Range para baixar apenas 1 byte (evita problema HEAD) const response = await fetch(url, { signal: AbortSignal.timeout(8000), method: 'GET', headers: { - 'Range': 'bytes=0-0', + Range: 'bytes=0-0', 'User-Agent': 'UnoAPI/1.0', - 'Accept': '*/*', - 'Cache-Control': 'no-cache' - } - }); + Accept: '*/*', + 'Cache-Control': 'no-cache', + }, + }) // Status 206 (Partial Content) ou 200 (OK) indicam sucesso if (response.ok || response.status === 206) { - logger.info(`Presigned link validated successfully on attempt ${attempt} (status: ${response.status}): ${url}`); + logger.info(`Presigned link validated successfully on attempt ${attempt} (status: ${response.status}): ${url}`) // Consume o response body para evitar memory leak try { - await response.text(); + await response.text() } catch (e) { // Ignora erro ao consumir body } - return true; + return true } // Para links pré-assinados, 403/404/416 podem ser temporários if ([403, 404, 416, 502, 503].includes(response.status)) { - logger.debug(`Presigned link not ready (${response.status}), attempt ${attempt}/${maxAttempts}`); + logger.debug(`Presigned link not ready (${response.status}), attempt ${attempt}/${maxAttempts}`) // Calcula delay inteligente - let delay = baseDelay; + let delay = baseDelay if (attempt <= 15) { - delay = baseDelay; + delay = baseDelay } else if (attempt <= 25) { - delay = baseDelay * 1.5; + delay = baseDelay * 1.5 } else { - delay = Math.min(baseDelay * 2, maxDelay); + delay = Math.min(baseDelay * 2, maxDelay) } if (attempt < maxAttempts) { - logger.debug(`Waiting ${delay}ms before next attempt...`); - await new Promise(resolve => setTimeout(resolve, delay)); + logger.debug(`Waiting ${delay}ms before next attempt...`) + await new Promise((resolve) => setTimeout(resolve, delay)) } - continue; + continue } // Outros códigos de erro são definitivos - logger.error(`Presigned link validation failed with status ${response.status}: ${url}`); - throw new SendError(11, t('invalid_link', response.status, url)); - + logger.error(`Presigned link validation failed with status ${response.status}: ${url}`) + throw new SendError(11, t('invalid_link', response.status, url)) } catch (error) { if (error instanceof SendError) { - throw error; + throw error } // Erros de rede/timeout podem ser temporários - if (error.name === 'AbortError' || - error.message.includes('timeout') || - error.name === 'FetchError' || - error.message.includes('ECONNRESET')) { - - logger.debug(`Network error on attempt ${attempt}: ${error.message}`); + if (error.name === 'AbortError' || error.message.includes('timeout') || error.name === 'FetchError' || error.message.includes('ECONNRESET')) { + logger.debug(`Network error on attempt ${attempt}: ${error.message}`) if (attempt < maxAttempts) { - await new Promise(resolve => setTimeout(resolve, baseDelay)); - continue; + await new Promise((resolve) => setTimeout(resolve, baseDelay)) + continue } } - logger.error(`Unexpected error validating presigned link: ${error.message}`); - throw new SendError(11, t('link_validation_error', error.message)); + logger.error(`Unexpected error validating presigned link: ${error.message}`) + throw new SendError(11, t('link_validation_error', error.message)) } } - throw new SendError(11, t('link_validation_failed_after_retries', maxAttempts, url)); + throw new SendError(11, t('link_validation_failed_after_retries', maxAttempts, url)) } } @@ -241,9 +241,9 @@ const closeDefault = async () => logger.info(`Close connection`) export class ClientBaileys implements Client { // eslint-disable-next-line @typescript-eslint/no-unused-vars readonly sendMessageDefault: sendMessage = async (_phone: string, _message: AnyMessageContent, _options: unknown) => { - const sessionStore = this?.phone && await (await this?.config?.getStore(this.phone, this.config)).sessionStore + const sessionStore = this?.phone && (await (await this?.config?.getStore(this.phone, this.config)).sessionStore) if (sessionStore) { - if (!await sessionStore.isStatusConnecting(this.phone)) { + if (!(await sessionStore.isStatusConnecting(this.phone))) { clients.delete(this.phone) } if (await sessionStore.isStatusOnline(this.phone)) { @@ -275,11 +275,7 @@ export class ClientBaileys implements Client { private onWebhookError = async (error: any) => { const { sessionStore } = this.store! if (!this.config.throwWebhookError && error.name === 'FetchError' && (await sessionStore.isStatusOnline(this.phone))) { - return this.sendMessage( - phoneNumberToJid(this.phone), - { text: `Error on send message to webhook: ${error.message}`}, - {} - ) + return this.sendMessage(phoneNumberToJid(this.phone), { text: `Error on send message to webhook: ${error.message}` }, {}) } if (this.config.throwWebhookError) { throw error @@ -332,7 +328,7 @@ export class ClientBaileys implements Client { remoteJid, id, } - const message = t('qrcode_attemps', time, limit) + const message = t('qrcode_attemps', time, limit) const waMessage: WAMessage = { key: waMessageKey, message: { @@ -412,7 +408,7 @@ export class ClientBaileys implements Client { onNewLogin: this.onNewLogin, config: this.config, onDisconnected: async () => this.disconnect(), - onReconnect: this.onReconnect + onReconnect: this.onReconnect, }) if (!result) { logger.error('Socket connect return empty %s', this.phone) @@ -468,7 +464,7 @@ export class ClientBaileys implements Client { }) .map(async (message: any) => { return this.readMessages([message.key!]) - }) + }), ) } }) @@ -500,7 +496,7 @@ export class ClientBaileys implements Client { this.calls.set(from, true) if (this.config.rejectCalls && this.rejectCall) { await this.rejectCall(id, from) - const response = await this.sendMessage(from, { text: this.config.rejectCalls }, {}); + const response = await this.sendMessage(from, { text: this.config.rejectCalls }, {}) const message = { key: { fromMe: true, @@ -607,21 +603,21 @@ export class ClientBaileys implements Client { // Na função send(), substitua a validação existente: // Na função send(), substitua toda a validação de mídia por: if (VALIDATE_MEDIA_LINK_BEFORE_SEND && TYPE_MESSAGES_MEDIA.includes(type)) { - const link = payload[type] && payload[type].link; + const link = payload[type] && payload[type].link if (link) { - logger.info(`Starting media link validation for ${type}: ${link}`); + logger.info(`Starting media link validation for ${type}: ${link}`) try { - await PresignedLinkValidator.validateLink(link); - logger.info(`Media link validation completed successfully for ${type}`); + await PresignedLinkValidator.validateLink(link) + logger.info(`Media link validation completed successfully for ${type}`) } catch (error) { - logger.error(`Media link validation failed for ${type}: ${error.message}`); + logger.error(`Media link validation failed for ${type}: ${error.message}`) if (error instanceof SendError) { - throw error; + throw error } - throw new SendError(11, t('media_validation_error', error.message)); + throw new SendError(11, t('media_validation_error', error.message)) } } } @@ -714,7 +710,7 @@ export class ClientBaileys implements Client { if (ee.message == 'Media upload failed on all hosts') { const link = payload[type] && payload[type].link if (link) { - const response: FetchResponse = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'HEAD'}) + const response: FetchResponse = await fetch(link, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'HEAD' }) if (!response.ok) { e = new SendError(11, t('invalid_link', response.status, link)) } @@ -788,7 +784,7 @@ export class ClientBaileys implements Client { } async getMessageMetadata(message: T) { - if (!this.store || !await this.store.sessionStore.isStatusOnline(this.phone)) { + if (!this.store || !(await this.store.sessionStore.isStatusOnline(this.phone))) { return message } const key = message && message['key'] @@ -859,7 +855,7 @@ export class ClientBaileys implements Client { contacts.push({ wa_id: realJid, input: number, - status: realJid ? 'valid' : 'invalid' + status: realJid ? 'valid' : 'invalid', }) } return contacts diff --git a/src/services/client_forward.ts b/src/services/client_forward.ts index f9d26686..fd855a7d 100644 --- a/src/services/client_forward.ts +++ b/src/services/client_forward.ts @@ -1,7 +1,7 @@ -import { Client, Contact } from './client'; -import { getConfig } from './config'; -import { Listener } from './listener'; -import logger from './logger'; +import { Client, Contact } from './client' +import { getConfig } from './config' +import { Listener } from './listener' +import logger from './logger' export class ClientForward implements Client { private phone: string @@ -19,7 +19,7 @@ export class ClientForward implements Client { const body = JSON.stringify(payload) const headers = { 'Content-Type': 'application/json; charset=utf-8', - 'Authorization': `Bearer ${config.webhookForward.token}` + Authorization: `Bearer ${config.webhookForward.token}`, } const endpoint = options.endpoint && payload.type ? options.endpoint : 'messages' const url = `${config.webhookForward.url}/${config.webhookForward.version}/${config.webhookForward.phoneNumberId}/${endpoint}` @@ -46,10 +46,10 @@ export class ClientForward implements Client { public async connect(_time: number) { const message = { message: { - conversation: 'Starting unoapi forwarder......' - } + conversation: 'Starting unoapi forwarder......', + }, } - return this.listener.process(this.phone, [message] , 'status') + return this.listener.process(this.phone, [message], 'status') } public getMessageMetadata(_message: T): Promise { @@ -63,7 +63,7 @@ export class ClientForward implements Client { public async disconnect() { throw 'ClientCloudApi not disconnect' } - + public async logout() { throw 'ClientCloudApi not logout' } diff --git a/src/services/config.ts b/src/services/config.ts index f1de9a3a..ac6e260a 100644 --- a/src/services/config.ts +++ b/src/services/config.ts @@ -14,7 +14,7 @@ export interface GetMessageMetadata { export const getMessageMetadataDefault: GetMessageMetadata = async (data: T) => data export type Webhook = { - id: string, + id: string url: string urlAbsolute: string token: string @@ -73,17 +73,17 @@ export type Config = { authToken: string | undefined authHeader: string | undefined provider: 'baileys' | 'forwarder' | undefined - server: string | undefined + server: string | undefined connectionType: connectionType - wavoipToken: string | undefined + wavoipToken: string | undefined useRedis: boolean useS3: boolean qrTimeoutMs: number label: string overrideWebhooks: boolean customMessageCharacters: string[] - customMessageCharactersFunction: (message: string) => string, - whatsappVersion: WAVersion | undefined, + customMessageCharactersFunction: (message: string) => string + whatsappVersion: WAVersion | undefined } export const defaultConfig: Config = { @@ -149,7 +149,7 @@ export const defaultConfig: Config = { overrideWebhooks: false, customMessageCharacters: [], customMessageCharactersFunction: (message: string) => message, - whatsappVersion: undefined + whatsappVersion: undefined, } export interface getConfig { diff --git a/src/services/config_by_env.ts b/src/services/config_by_env.ts index da66acf5..a046238d 100644 --- a/src/services/config_by_env.ts +++ b/src/services/config_by_env.ts @@ -116,7 +116,7 @@ export const getConfigByEnv: getConfig = async (phone: string): Promise if (config.customMessageCharacters.length > 0) { const getRandomChar = () => { - const randomIndex = Math.floor(Math.random() * config.customMessageCharacters.length); + const randomIndex = Math.floor(Math.random() * config.customMessageCharacters.length) return config.customMessageCharacters[randomIndex] } config.customMessageCharactersFunction = (message: string) => { diff --git a/src/services/config_redis.ts b/src/services/config_redis.ts index 186642fd..1542f855 100644 --- a/src/services/config_redis.ts +++ b/src/services/config_redis.ts @@ -24,11 +24,11 @@ export const getConfigRedis: getConfig = async (phone: string): Promise // override by env, if not present in redis webhook[keyWebhook] = config.webhooks[0][keyWebhook] } - }); + }) webhooks.push(webhook) }) configRedis[key] = webhooks - } else if (key === 'webhookForward'){ + } else if (key === 'webhookForward') { const webhookForward = configRedis[key] Object.keys(configRedis[key]).forEach((k) => { if (!webhookForward[k]) { @@ -37,15 +37,15 @@ export const getConfigRedis: getConfig = async (phone: string): Promise }) configRedis[key] = webhookForward } - logger.debug('Override env config by redis config in %s: %s => %s', phone, key, JSON.stringify(configRedis[key])); - config[key] = configRedis[key]; + logger.debug('Override env config by redis config in %s: %s => %s', phone, key, JSON.stringify(configRedis[key])) + config[key] = configRedis[key] } - }); + }) } config.server = config.server || 'server_1' config.provider = config.provider || 'baileys' - + const filter: MessageFilter = new MessageFilter(phone, config) config.shouldIgnoreJid = filter.isIgnoreJid.bind(filter) config.shouldIgnoreKey = filter.isIgnoreKey.bind(filter) diff --git a/src/services/contact_baileys.ts b/src/services/contact_baileys.ts index 2505d090..62a6fdcb 100644 --- a/src/services/contact_baileys.ts +++ b/src/services/contact_baileys.ts @@ -29,7 +29,7 @@ export default class ContactBaileys implements Contact { if (webhook) { const body = JSON.stringify({ contacts }) const headers = { - 'Content-Type': 'application/json; charset=utf-8' + 'Content-Type': 'application/json; charset=utf-8', } let response: Response try { @@ -47,4 +47,4 @@ export default class ContactBaileys implements Contact { } return { contacts } } -} \ No newline at end of file +} diff --git a/src/services/contact_dummy.ts b/src/services/contact_dummy.ts index d3f7056c..6da317cf 100644 --- a/src/services/contact_dummy.ts +++ b/src/services/contact_dummy.ts @@ -1,7 +1,7 @@ -import { Contact, ContactResponse } from './contact'; +import { Contact, ContactResponse } from './contact' export class ContactDummy implements Contact { public async verify(_phone: String, _numbers: String[], webhook: string | undefined) { return { contacts: [] } as ContactResponse } -} \ No newline at end of file +} diff --git a/src/services/data_store.ts b/src/services/data_store.ts index dfd24860..46139a25 100644 --- a/src/services/data_store.ts +++ b/src/services/data_store.ts @@ -7,20 +7,21 @@ export interface getDataStore { (phone: string, config: Config): Promise } -export type MessageStatus = 'scheduled' - | 'pending' - | 'without-whatsapp' - | 'invalid-phone-number' - | 'error' - | 'failed' - | 'sent' - | 'delivered' - | 'read' - | 'played' - | 'accepted' - | 'deleted' +export type MessageStatus = + | 'scheduled' + | 'pending' + | 'without-whatsapp' + | 'invalid-phone-number' + | 'error' + | 'failed' + | 'sent' + | 'delivered' + | 'read' + | 'played' + | 'accepted' + | 'deleted' -export type DataStore = { +export type DataStore = { state: AuthenticationState saveCreds: () => Promise type: string diff --git a/src/services/data_store_file.ts b/src/services/data_store_file.ts index f04288ae..474ad972 100644 --- a/src/services/data_store_file.ts +++ b/src/services/data_store_file.ts @@ -1,11 +1,4 @@ -import { - proto, - WAMessage, - WAMessageKey, - WASocket, - useMultiFileAuthState, - GroupMetadata -} from 'baileys' +import { proto, WAMessage, WAMessageKey, WASocket, useMultiFileAuthState, GroupMetadata } from 'baileys' import { isIndividualJid, jidToPhoneNumber, phoneNumberToJid } from './transformer' import { existsSync, readFileSync, rmSync, writeFileSync, mkdirSync } from 'fs' import { DataStore, MessageStatus } from './data_store' @@ -31,17 +24,17 @@ export const getDataStoreFile: getDataStore = async (phone: string, config: Conf } const deepMerge = (obj1, obj2) => { - const result = { ...obj1 }; + const result = { ...obj1 } for (let key in obj2) { if (obj2.hasOwnProperty(key)) { if (obj2[key] instanceof Object && obj1[key] instanceof Object) { - result[key] = deepMerge(obj1[key], obj2[key]); + result[key] = deepMerge(obj1[key], obj2[key]) } else { - result[key] = obj2[key]; + result[key] = obj2[key] } } } - return result; + return result } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -56,22 +49,21 @@ const dataStoreFile = async (phone: string, config: Config): Promise const store = await useMultiFileAuthState(SESSION_DIR) const dataStore = store as DataStore dataStore.type = 'file' - - dataStore.loadMessage = async(jid: string, id: string) => messages.get(`${jid}-${id}`), - dataStore.toJSON = () => { - return { - messages, - keys, - jids, - ids, - statuses, - groups: groups.keys().reduce((acc, key) => { + ;((dataStore.loadMessage = async (jid: string, id: string) => messages.get(`${jid}-${id}`)), + (dataStore.toJSON = () => { + return { + messages, + keys, + jids, + ids, + statuses, + groups: groups.keys().reduce((acc, key) => { acc.set(key, groups.get(key)) return acc }, new Map()), - medias, - } - } + medias, + } + })) dataStore.fromJSON = (json) => { json?.messages.entries().forEach(([key, value]) => { messages.set(key, value) @@ -95,7 +87,7 @@ const dataStoreFile = async (phone: string, config: Config): Promise medias.set(key, value) }) } - dataStore.writeToFile = (path: string) => { + dataStore.writeToFile = (path: string) => { const { writeFileSync } = require('fs') // for(const a in Object.keys(dataStore.toJSON())) { // console.log(a) @@ -104,7 +96,7 @@ const dataStoreFile = async (phone: string, config: Config): Promise } dataStore.readFromFile = (path: string) => { const { readFileSync, existsSync } = require('fs') - if(existsSync(path)) { + if (existsSync(path)) { logger.debug({ path }, 'reading from file') const jsonStr = readFileSync(path, { encoding: 'utf-8' }) const json = JSON.parse(jsonStr) @@ -170,7 +162,7 @@ const dataStoreFile = async (phone: string, config: Config): Promise return statuses.get(id) } - dataStore.loadUnoId = async (id: string) => ids.get(id) || ids.get(`${phone}-${id}`) + dataStore.loadUnoId = async (id: string) => ids.get(id) || ids.get(`${phone}-${id}`) dataStore.setUnoId = async (id: string, unoId: string) => { ids.set(`${phone}-${id}`, unoId) } @@ -195,9 +187,7 @@ const dataStoreFile = async (phone: string, config: Config): Promise } else if ('status@broadcast' == phoneOrJid) { return phoneOrJid } - } catch (error) { - - } + } catch (error) {} } const result = results && results[0] const test = result && result?.exists && result?.jid diff --git a/src/services/data_store_redis.ts b/src/services/data_store_redis.ts index d3a80b06..81f674cc 100644 --- a/src/services/data_store_redis.ts +++ b/src/services/data_store_redis.ts @@ -136,7 +136,7 @@ const dataStoreRedis = async (phone: string, config: Config): Promise ], } - if(!ONLY_HELLO_TEMPLATE) { + if (!ONLY_HELLO_TEMPLATE) { const bulkReport = { id: 2, name: 'unoapi-bulk-report', @@ -213,7 +213,6 @@ const dataStoreRedis = async (phone: string, config: Config): Promise } else { return [hello] } - } } return store diff --git a/src/services/incoming_amqp.ts b/src/services/incoming_amqp.ts index 70fe2dba..efb57282 100644 --- a/src/services/incoming_amqp.ts +++ b/src/services/incoming_amqp.ts @@ -15,17 +15,11 @@ export class IncomingAmqp implements Incoming { public async send(phone: string, payload: object, options: object = {}) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const { status, type, to } = payload as any - const config = await this.getConfig(phone); + const config = await this.getConfig(phone) if (status) { options['type'] = 'direct' options['priority'] = 3 // update status is always middle important - await amqpPublish( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_INCOMING}.${config.server!}`, - phone, - { payload, options }, - options - ) + await amqpPublish(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_INCOMING}.${config.server!}`, phone, { payload, options }, options) return { ok: { success: true } } } else if (type) { const id = uuid() @@ -33,13 +27,7 @@ export class IncomingAmqp implements Incoming { options['priority'] = 5 // send message without bulk is very important } options['type'] = 'direct' - await amqpPublish( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_INCOMING}.${config.server!}`, - phone, - { payload, id, options }, - options - ) + await amqpPublish(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_INCOMING}.${config.server!}`, phone, { payload, id, options }, options) const ok = { messaging_product: 'whatsapp', contacts: [ diff --git a/src/services/listener_amqp.ts b/src/services/listener_amqp.ts index 192db657..f9017b3f 100644 --- a/src/services/listener_amqp.ts +++ b/src/services/listener_amqp.ts @@ -3,22 +3,22 @@ import { PublishOption, amqpPublish } from '../amqp' import { UNOAPI_EXCHANGE_BRIDGE_NAME, UNOAPI_QUEUE_LISTENER, UNOAPI_SERVER_NAME } from '../defaults' const priorities = { - 'qrcode': 5, - 'status': 3, - 'history': 0, - 'append': 5, - 'notify': 5, - 'message': 5, - 'update': 3, - 'delete': 3, + qrcode: 5, + status: 3, + history: 0, + append: 5, + notify: 5, + message: 5, + update: 3, + delete: 3, } const delay = new Map() const delays = { - 'qrcode': _ => 0, - 'status': _ => 0, - 'history': (phone: string) => { + qrcode: (_) => 0, + status: (_) => 0, + history: (phone: string) => { const current = delay.get(phone) if (current) { delay.set(phone, current + 1000) @@ -28,26 +28,19 @@ const delays = { return 0 } }, - 'append': _ => 0, - 'notify': _ => 0, - 'message': _ => 0, - 'update': _ => 0, - 'delete': _ => 0, + append: (_) => 0, + notify: (_) => 0, + message: (_) => 0, + update: (_) => 0, + delete: (_) => 0, } - export class ListenerAmqp implements Listener { public async process(phone: string, messages: object[], type: eventType) { const options: Partial = {} options.priority = options.priority || priorities[type] || 5 options.delay = options.delay || delays[type](phone) || 0 options.type = 'direct' - await amqpPublish( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_LISTENER}.${UNOAPI_SERVER_NAME}`, - phone, - { messages, type }, - options - ) + await amqpPublish(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_LISTENER}.${UNOAPI_SERVER_NAME}`, phone, { messages, type }, options) } } diff --git a/src/services/listener_baileys.ts b/src/services/listener_baileys.ts index 815422c6..b7ba2bd9 100644 --- a/src/services/listener_baileys.ts +++ b/src/services/listener_baileys.ts @@ -10,24 +10,29 @@ import { Template } from './template' import { UNOAPI_DELAY_AFTER_FIRST_MESSAGE_MS, UNOAPI_DELAY_BETWEEN_MESSAGES_MS } from '../defaults' import { v1 as uuid } from 'uuid' -const delays: Map = new Map() +const delays: Map = new Map() -const delayFunc = UNOAPI_DELAY_AFTER_FIRST_MESSAGE_MS && UNOAPI_DELAY_BETWEEN_MESSAGES_MS ? async (phone, to) => { - if (to) { - const key = `${phone}:${to}` - const epochMS: number = Math.floor(Date.now()); - const lastMessage = (delays.get(key) || 0) as number - const timeForNextMessage = lastMessage ? Math.floor(lastMessage + (UNOAPI_DELAY_BETWEEN_MESSAGES_MS)) : Math.floor(epochMS + (UNOAPI_DELAY_AFTER_FIRST_MESSAGE_MS)) - const ms = timeForNextMessage - epochMS > 0 ? Math.floor((timeForNextMessage - epochMS)) : 0; - logger.debug(`Delay for this message is: %s`, ms) - if (ms) { - delays.set(key, timeForNextMessage) - await delay(ms) - } else { - delays.set(key, epochMS) - } - } -} : async (_phone, _to) => {} +const delayFunc = + UNOAPI_DELAY_AFTER_FIRST_MESSAGE_MS && UNOAPI_DELAY_BETWEEN_MESSAGES_MS + ? async (phone, to) => { + if (to) { + const key = `${phone}:${to}` + const epochMS: number = Math.floor(Date.now()) + const lastMessage = (delays.get(key) || 0) as number + const timeForNextMessage = lastMessage + ? Math.floor(lastMessage + UNOAPI_DELAY_BETWEEN_MESSAGES_MS) + : Math.floor(epochMS + UNOAPI_DELAY_AFTER_FIRST_MESSAGE_MS) + const ms = timeForNextMessage - epochMS > 0 ? Math.floor(timeForNextMessage - epochMS) : 0 + logger.debug(`Delay for this message is: %s`, ms) + if (ms) { + delays.set(key, timeForNextMessage) + await delay(ms) + } else { + delays.set(key, epochMS) + } + } + } + : async (_phone, _to) => {} export class ListenerBaileys implements Listener { private outgoing: Outgoing @@ -46,28 +51,30 @@ export class ListenerBaileys implements Listener { if (type == 'delete' && messages.keys) { const store = await config.getStore(phone, config) // eslint-disable-next-line @typescript-eslint/no-explicit-any - messages = await Promise.all((messages.keys as any).map(async (key: any) => { - if (key.fromMe) { - return { key, update: { status: 'DELETED' } } - } - const original = await store.dataStore.loadMessage(key.remoteJid!, key.id) - let originalText = '' - if (original) { - const normalized = getNormalizedMessage(original) - const bin = normalized && getBinMessage(normalized) - if (bin) { - if (bin.messageType === 'conversation') { - originalText = bin.message as string - } else if (bin.messageType === 'extendedTextMessage') { - originalText = bin.message.text - } else if (bin.message && bin.message.caption) { - originalText = bin.message.caption + messages = await Promise.all( + (messages.keys as any).map(async (key: any) => { + if (key.fromMe) { + return { key, update: { status: 'DELETED' } } + } + const original = await store.dataStore.loadMessage(key.remoteJid!, key.id) + let originalText = '' + if (original) { + const normalized = getNormalizedMessage(original) + const bin = normalized && getBinMessage(normalized) + if (bin) { + if (bin.messageType === 'conversation') { + originalText = bin.message as string + } else if (bin.messageType === 'extendedTextMessage') { + originalText = bin.message.text + } else if (bin.message && bin.message.caption) { + originalText = bin.message.caption + } } } - } - const text = originalText ? `${t('deleted_message')}${originalText}` : t('deleted_message') - return { key, message: { editedMessage: { message: { conversation: text } } } } - })) + const text = originalText ? `${t('deleted_message')}${originalText}` : t('deleted_message') + return { key, message: { editedMessage: { message: { conversation: text } } } } + }), + ) type = 'update' } if (type === 'append' && !config.ignoreOwnMessages) { @@ -79,22 +86,14 @@ export class ListenerBaileys implements Listener { return } } else if (type == 'qrcode') { - await this.broadcast.send( - phone, - type, - messages[0]['message']['imageMessage']['url'] - ) + await this.broadcast.send(phone, type, messages[0]['message']['imageMessage']['url']) // await this.broadcast.send( // phone, // 'status', // messages[0]['message']['imageMessage']['caption'] // ) - } else if(type === 'status') { - await this.broadcast.send( - phone, - type, - messages[0]['message']['conversation'] - ) + } else if (type === 'status') { + await this.broadcast.send(phone, type, messages[0]['message']['conversation']) } // eslint-disable-next-line @typescript-eslint/no-explicit-any const filteredMessages = messages.filter((m: any) => { @@ -134,7 +133,7 @@ export class ListenerBaileys implements Listener { const key = i.key // possible update message or delete message - if (key?.id && (key?.fromMe || (!key?.fromMe && ((message as any)?.update?.messageStubType == 1)))) { + if (key?.id && (key?.fromMe || (!key?.fromMe && (message as any)?.update?.messageStubType == 1))) { const idUno = await store.dataStore.loadUnoId(key.id) logger.debug('Unoapi id %s to Baileys id %s', idUno, key.id) if (idUno) { @@ -202,4 +201,4 @@ export class ListenerBaileys implements Listener { logger.debug(`Not send message type ${messageType} to http phone %s message id %s`, phone, i?.key?.id) } } -} \ No newline at end of file +} diff --git a/src/services/logout_amqp.ts b/src/services/logout_amqp.ts index 8073af46..e06b4ade 100644 --- a/src/services/logout_amqp.ts +++ b/src/services/logout_amqp.ts @@ -10,14 +10,8 @@ export class LogoutAmqp implements Logout { this.getConfig = getConfig } - public async run(phone: string) { + public async run(phone: string) { const config = await this.getConfig(phone) - await amqpPublish( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_LOGOUT}.${config.server!}`, - '', - { phone }, - { type: 'direct' } - ) + await amqpPublish(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_LOGOUT}.${config.server!}`, '', { phone }, { type: 'direct' }) } } diff --git a/src/services/media_store_file.ts b/src/services/media_store_file.ts index c5221ec0..79b813ed 100644 --- a/src/services/media_store_file.ts +++ b/src/services/media_store_file.ts @@ -40,7 +40,7 @@ export const mediaStoreFile = (phone: string, config: Config, getDataStore: getD mediaStore.saveMediaForwarder = async (message: any) => { const filePath = mediaStore.getFilePath(phone, message.id, message[message.type].mime_type) - const url = `${config.webhookForward.url}/${config.webhookForward.version}/${ message[message.type].id}` + const url = `${config.webhookForward.url}/${config.webhookForward.version}/${message[message.type].id}` const { buffer } = await mediaToBuffer(url, config.webhookForward.token!, config.webhookForward?.timeoutMs || 0) logger.debug('Saving buffer %s...', filePath) await mediaStore.saveMediaBuffer(filePath, buffer) @@ -175,7 +175,7 @@ export const mediaStoreFile = (phone: string, config: Config, getDataStore: getD if (!existsSync(base)) { mkdirSync(base, { recursive: true }) } - const response: FetchResponse = await fetch(contact.imgUrl, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'GET'}) + const response: FetchResponse = await fetch(contact.imgUrl, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'GET' }) const buffer = toBuffer(await response.arrayBuffer()) await writeFile(complete, buffer) logger.debug('Saved profile picture file %s!!', phoneNumber) diff --git a/src/services/media_store_s3.ts b/src/services/media_store_s3.ts index 4d3d4483..52820752 100644 --- a/src/services/media_store_s3.ts +++ b/src/services/media_store_s3.ts @@ -13,7 +13,6 @@ import { Config } from './config' import logger from './logger' import fetch, { Response as FetchResponse } from 'node-fetch' - export const getMediaStoreS3: getMediaStore = (phone: string, config: Config, getDataStore: getDataStore): MediaStore => { if (!mediaStores.has(phone)) { logger.debug('Creating s3 data store %s', phone) @@ -45,13 +44,7 @@ export const mediaStoreS3 = (phone: string, config: Config, getDataStore: getDat const abortSignal = AbortSignal.timeout(s3Config.timeoutMs) await s3Client.send(new PutObjectCommand(putParams), { abortSignal }) logger.debug(`Uploaded file ${fileName} to bucket ${bucket}!`) - await amqpPublish( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_MEDIA, - phone, - { fileName: fileName }, - { delay: DATA_TTL * 1000, type: 'topic' } - ) + await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_MEDIA, phone, { fileName: fileName }, { delay: DATA_TTL * 1000, type: 'topic' }) return true } @@ -65,9 +58,7 @@ export const mediaStoreS3 = (phone: string, config: Config, getDataStore: getDat const link = await getSignedUrl(s3Client, command, { expiresIn }) return link } catch (error) { - logger.error( - `Error on generate s3 signed url for bucket: ${bucket} file name: ${fileName} expires in: ${expiresIn} -> ${error.message}` - ) + logger.error(`Error on generate s3 signed url for bucket: ${bucket} file name: ${fileName} expires in: ${expiresIn} -> ${error.message}`) throw error } } @@ -90,7 +81,7 @@ export const mediaStoreS3 = (phone: string, config: Config, getDataStore: getDat logger.debug(`Downloaded media ${file}!`) return response.Body as Readable } - + mediaStore.getProfilePictureUrl = async (_baseUrl: string, jid: string) => { const phoneNumber = jidToPhoneNumberIfUser(jid) const fileName = `${phone}/${PROFILE_PICTURE_FOLDER}/${profilePictureFileName(phoneNumber)}` @@ -114,7 +105,7 @@ export const mediaStoreS3 = (phone: string, config: Config, getDataStore: getDat await mediaStore.removeMedia(fileName) } else if (contact.imgUrl) { logger.debug('Saving profile picture s3 %s...', phoneNumber) - const response: FetchResponse = await fetch(contact.imgUrl, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'GET'}) + const response: FetchResponse = await fetch(contact.imgUrl, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), method: 'GET' }) const buffer = toBuffer(await response.arrayBuffer()) await mediaStore.saveMediaBuffer(fileName, buffer) logger.debug('Saved profile picture s3 %s!', phoneNumber) diff --git a/src/services/outgoing_amqp.ts b/src/services/outgoing_amqp.ts index 1f9c3024..d67fdf7a 100644 --- a/src/services/outgoing_amqp.ts +++ b/src/services/outgoing_amqp.ts @@ -20,9 +20,10 @@ export class OutgoingAmqp implements Outgoing { const config = await this.getConfig(phone) await amqpPublish( UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_OUTGOING, phone, + UNOAPI_QUEUE_OUTGOING, + phone, { webhooks: config.webhooks, payload, split: true }, - { type: 'topic' } + { type: 'topic' }, ) } diff --git a/src/services/outgoing_cloud_api.ts b/src/services/outgoing_cloud_api.ts index 87351ecf..2d8310c6 100644 --- a/src/services/outgoing_cloud_api.ts +++ b/src/services/outgoing_cloud_api.ts @@ -54,7 +54,7 @@ export class OutgoingCloudApi implements Outgoing { } const body = JSON.stringify(message) const headers = { - 'Content-Type': 'application/json; charset=utf-8' + 'Content-Type': 'application/json; charset=utf-8', } if (webhook.header && webhook.token) { headers[webhook.header] = webhook.token diff --git a/src/services/redis.ts b/src/services/redis.ts index 94d25388..891f08f3 100644 --- a/src/services/redis.ts +++ b/src/services/redis.ts @@ -253,7 +253,7 @@ export const getTemplates = async (phone: string) => { export const setTemplates = async (phone: string, value: any) => { const { id } = value if (!id) { - throw new Error(`New template has no ID or an invalid format`); + throw new Error(`New template has no ID or an invalid format`) } const current = (await getTemplates(phone)) || {} const key = templateKey(phone) @@ -267,11 +267,11 @@ export const setTemplates = async (phone: string, value: any) => { } } else { config = [] - current.forEach(element => { + current.forEach((element) => { if (element.id !== id) { config.push(element) } - }); + }) config.push(value) } } @@ -292,12 +292,12 @@ export const getConfig = async (phone: string) => { export const setConfig = async (phone: string, value: any) => { const currentConfig = await getConfig(phone) const key = configKey(phone) - const currentWebhooks: Webhook[] = currentConfig && currentConfig.webhooks || [] - const newWebhooks: Webhook[] = value && value.webhooks || [] + const currentWebhooks: Webhook[] = (currentConfig && currentConfig.webhooks) || [] + const newWebhooks: Webhook[] = (value && value.webhooks) || [] const updatedWebooks: Webhook[] = [] const baseWebhook = value.overrideWebhooks || currentWebhooks.length == 0 ? newWebhooks : currentWebhooks const searchWebhooks = value.overrideWebhooks ? currentWebhooks : newWebhooks - baseWebhook.forEach(n => { + baseWebhook.forEach((n) => { const c = searchWebhooks.find((c) => c.id === n.id) if (c) { updatedWebooks.push({ ...c, ...n }) @@ -398,17 +398,17 @@ export const getMessage = async (phone: string, jid: string, id: string): Pro } } -export const getConnectCount = async(phone: string) => { +export const getConnectCount = async (phone: string) => { const keyPattern = connectCountKey(phone, '*') const keys = await redisKeys(keyPattern) return keys.length || 0 } -export const clearConnectCount = async(phone: string) => { +export const clearConnectCount = async (phone: string) => { const keyPattern = connectCountKey(phone, '*') const keys = await redisKeys(keyPattern) for (let index = 0; index < keys.length.length; index++) { - const key = keys[index]; + const key = keys[index] await redisDel(key) } } diff --git a/src/services/reload_amqp.ts b/src/services/reload_amqp.ts index bbd13692..79c74df8 100644 --- a/src/services/reload_amqp.ts +++ b/src/services/reload_amqp.ts @@ -13,19 +13,7 @@ export class ReloadAmqp extends Reload { public async run(phone: string) { const config = await this.getConfig(phone) - await amqpPublish( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_RELOAD, - phone, - { phone }, - { type: 'topic' } - ) - await amqpPublish( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_RELOAD}.${config.server!}`, - '', - { phone }, - { type: 'direct' } - ) + await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_RELOAD, phone, { phone }, { type: 'topic' }) + await amqpPublish(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_RELOAD}.${config.server!}`, '', { phone }, { type: 'direct' }) } } diff --git a/src/services/reload_baileys.ts b/src/services/reload_baileys.ts index 2ea0b7f9..af9634e6 100644 --- a/src/services/reload_baileys.ts +++ b/src/services/reload_baileys.ts @@ -35,7 +35,7 @@ export class ReloadBaileys extends Reload { }) const store = await config.getStore(phone, config) const { sessionStore } = store - if (await sessionStore.isStatusOnline(phone) || await sessionStore.isStatusStandBy(phone) || await sessionStore.isStatusConnecting(phone)) { + if ((await sessionStore.isStatusOnline(phone)) || (await sessionStore.isStatusStandBy(phone)) || (await sessionStore.isStatusConnecting(phone))) { logger.warn('Reload disconnect session %s!', phone) await currentClient.disconnect() } diff --git a/src/services/send_error.ts b/src/services/send_error.ts index f6c902b9..2ef15d61 100644 --- a/src/services/send_error.ts +++ b/src/services/send_error.ts @@ -6,4 +6,4 @@ export class SendError extends Error { this.code = code this.title = title } -} \ No newline at end of file +} diff --git a/src/services/session_store.ts b/src/services/session_store.ts index 04dfc162..809fc4aa 100644 --- a/src/services/session_store.ts +++ b/src/services/session_store.ts @@ -6,7 +6,6 @@ export type sessionStatus = 'offline' | 'online' | 'disconnected' | 'connecting' const statuses: Map = new Map() const retries: Map = new Map() - export abstract class SessionStore { abstract getPhones(): Promise @@ -16,27 +15,27 @@ export abstract class SessionStore { async setStatus(phone: string, status: sessionStatus) { logger.info(`Session status ${phone} change from ${await this.getStatus(phone)} to ${status}`) - statuses.set(phone, status) + statuses.set(phone, status) } async isStatusOnline(phone: string) { - return await this.getStatus(phone) == 'online' + return (await this.getStatus(phone)) == 'online' } async isStatusConnecting(phone: string) { - return await this.getStatus(phone) == 'connecting' + return (await this.getStatus(phone)) == 'connecting' } async isStatusOffline(phone: string) { - return await this.getStatus(phone) == 'offline' + return (await this.getStatus(phone)) == 'offline' } async isStatusDisconnect(phone: string) { - return await this.getStatus(phone) == 'disconnected' + return (await this.getStatus(phone)) == 'disconnected' } async isStatusRestartRequired(phone: string) { - return await this.getStatus(phone) == 'restart_required' + return (await this.getStatus(phone)) == 'restart_required' } async getConnectCount(phone: string) { @@ -48,12 +47,12 @@ export abstract class SessionStore { } async isStatusStandBy(phone: string) { - return await this.getStatus(phone) == 'standby' + return (await this.getStatus(phone)) == 'standby' } async verifyStatusStandBy(phone: string) { const count = await this.getConnectCount(phone) - if (await this.getStatus(phone) == 'standby') { + if ((await this.getStatus(phone)) == 'standby') { if (count < MAX_CONNECT_RETRY) { logger.warn('Standby removed %s', phone) await this.setStatus(phone, 'offline') @@ -61,7 +60,7 @@ export abstract class SessionStore { } logger.warn('Standby %s', phone) return true - } else if (count > MAX_CONNECT_RETRY && !await this.isStatusRestartRequired(phone)) { + } else if (count > MAX_CONNECT_RETRY && !(await this.isStatusRestartRequired(phone))) { this.setStatus(phone, 'standby') return true } diff --git a/src/services/session_store_redis.ts b/src/services/session_store_redis.ts index 38b5da64..8650d279 100644 --- a/src/services/session_store_redis.ts +++ b/src/services/session_store_redis.ts @@ -1,5 +1,17 @@ import { SessionStore, sessionStatus } from './session_store' -import { configKey, authKey, redisKeys, getSessionStatus, setSessionStatus, sessionStatusKey, redisGet, getConnectCount, setConnectCount, delAuth, clearConnectCount } from './redis' +import { + configKey, + authKey, + redisKeys, + getSessionStatus, + setSessionStatus, + sessionStatusKey, + redisGet, + getConnectCount, + setConnectCount, + delAuth, + clearConnectCount, +} from './redis' import logger from './logger' import { MAX_CONNECT_RETRY, MAX_CONNECT_TIME } from '../defaults' @@ -19,7 +31,7 @@ export class SessionStoreRedis extends SessionStore { } async getStatus(phone: string) { - return await getSessionStatus(phone) || 'disconnected' + return (await getSessionStatus(phone)) || 'disconnected' } async setStatus(phone: string, status: sessionStatus) { @@ -50,7 +62,7 @@ export class SessionStoreRedis extends SessionStore { const pattern = sessionStatusKey('*') const keys = await redisKeys(pattern) for (let i = 0; i < keys.length; i++) { - const key = keys[i]; + const key = keys[i] const phone = key.replace(toReplaceStatus, '') await this.syncConnection(phone) } @@ -63,7 +75,7 @@ export class SessionStoreRedis extends SessionStore { async syncConnection(phone: string) { logger.info(`Syncing ${phone} lost connection`) - if(await this.isStatusRestartRequired(phone)) { + if (await this.isStatusRestartRequired(phone)) { logger.info(`Is not lost connection, is restart required ${phone}`) return } @@ -75,9 +87,9 @@ export class SessionStoreRedis extends SessionStore { await this.setStatus(phone, 'disconnected') } const key = sessionStatusKey(phone) - if (await redisGet(key) == 'standby' && await this.getConnectCount(phone) < MAX_CONNECT_RETRY) { + if ((await redisGet(key)) == 'standby' && (await this.getConnectCount(phone)) < MAX_CONNECT_RETRY) { logger.info(`Sync ${phone} standby!`) await this.setStatus(phone, 'offline') } } -} \ No newline at end of file +} diff --git a/src/services/socket.ts b/src/services/socket.ts index dbb7da44..33a39c97 100644 --- a/src/services/socket.ts +++ b/src/services/socket.ts @@ -24,7 +24,7 @@ import { Level } from 'pino' import { SocksProxyAgent } from 'socks-proxy-agent' import { HttpsProxyAgent } from 'https-proxy-agent' import { useVoiceCallsBaileys } from 'voice-calls-baileys/lib/services/transport.model' -import { +import { DEFAULT_BROWSER, LOG_LEVEL, CONNECTING_TIMEOUT_MS, @@ -142,7 +142,7 @@ export const connect = async ({ logger.info(`First save creds with number is ${phoneCreds} and configured number ${phone}`) if (VALIDATE_SESSION_NUMBER && phoneCreds != phone) { await logout() - const message = t('session_conflict', phoneCreds, phone) + const message = t('session_conflict', phoneCreds, phone) logger.error(message) await onNotification(message, true) currentSaveCreds = async () => logger.error(message) @@ -164,7 +164,7 @@ export const connect = async ({ logger.debug('onConnectionUpdate connectionType %s ==> %s %s', config.connectionType, phone, JSON.stringify(event)) if (event.qr && config.connectionType == 'qrcode') { if (status.attempt > attempts) { - const message = t('attempts_exceeded', attempts) + const message = t('attempts_exceeded', attempts) logger.debug(message) await onNotification(message, true) status.attempt = 1 @@ -188,13 +188,13 @@ export const connect = async ({ await sessionStore.setStatus(phone, 'online') await onNotification(t('online_session'), true) } - + switch (event.connection) { case 'open': await onOpen() break - - case 'close': + + case 'close': await onClose(event) break @@ -259,7 +259,7 @@ export const connect = async ({ logger.info(`${phone} disconnected with status: ${statusCode}`) if ([DisconnectReason.loggedOut, DisconnectReason.forbidden].includes(statusCode)) { status.attempt = 1 - if (!await sessionStore.isStatusConnecting(phone)) { + if (!(await sessionStore.isStatusConnecting(phone))) { const message = t('removed') await onNotification(message, true) } @@ -318,12 +318,12 @@ export const connect = async ({ const reconnect = async () => { logger.info(`${phone} reconnecting`, status.attempt) if (status.attempt > attempts) { - const message = t('attempts_exceeded', attempts) + const message = t('attempts_exceeded', attempts) await onNotification(message, true) status.attempt = 1 return close() } else { - const message = t('connecting_attemps', status.attempt, attempts) + const message = t('connecting_attemps', status.attempt, attempts) await onNotification(message, false) await close() return onReconnect(status.attempt++) @@ -344,8 +344,8 @@ export const connect = async ({ // WebSocket.OPEN (1) // WebSocket.CLOSING (2) // WebSocket.CLOSED (3) - if (`${webSocket['readyState']}` == '1'){ - if (await sessionStore.isStatusConnecting(phone) || await sessionStore.isStatusOnline(phone)) { + if (`${webSocket['readyState']}` == '1') { + if ((await sessionStore.isStatusConnecting(phone)) || (await sessionStore.isStatusOnline(phone))) { try { await sock?.end(undefined) } catch (e) { @@ -359,7 +359,7 @@ export const connect = async ({ } } sock = undefined - if (!await sessionStore.isStatusRestartRequired(phone)) { + if (!(await sessionStore.isStatusRestartRequired(phone))) { await sessionStore.setStatus(phone, 'offline') } } @@ -367,9 +367,9 @@ export const connect = async ({ const logout = async () => { logger.info(`${phone} logout`) try { - return sock && await sock.logout() + return sock && (await sock.logout()) } catch (error) { - logger.error(`Error on remove session ${phone}: ${error.message}`,) + logger.error(`Error on remove session ${phone}: ${error.message}`) // ignore de unique error if already diconected session } finally { logger.info(`${phone} destroyed`) @@ -397,7 +397,7 @@ export const connect = async ({ if (await sessionStore.isStatusConnecting(phone)) { await verifyConnectingTimeout() throw new SendError(5, t('connecting_session')) - } else if (await sessionStore.isStatusDisconnect(phone) || !sock) { + } else if ((await sessionStore.isStatusDisconnect(phone)) || !sock) { throw new SendError(3, t('disconnected_session')) } else if (await sessionStore.isStatusOffline(phone)) { throw new SendError(12, t('offline_session')) @@ -416,7 +416,7 @@ export const connect = async ({ options: { composing: boolean; quoted: boolean | undefined } = { composing: false, quoted: undefined }, ) => { await validateStatus() - const id = isIndividualJid(to) ? await exists(to) : to + const id = isIndividualJid(to) ? await exists(to) : to if (id) { if (options.composing) { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -489,7 +489,7 @@ export const connect = async ({ const loggerBaileys = MAIN_LOGGER.child({}) logger.level = config.logLevel as Level - loggerBaileys.level = (LOG_LEVEL) as Level + loggerBaileys.level = LOG_LEVEL as Level let agent let fetchAgent @@ -537,7 +537,7 @@ export const connect = async ({ throw error } } - } + }, } sock = new Proxy(proxy, handler) } catch (error: any) { @@ -555,9 +555,9 @@ export const connect = async ({ if (sock) { event('connection.update', onConnectionUpdate) event('creds.update', verifyAndSaveCreds) - sock.ev.process(async(events) => { + sock.ev.process(async (events) => { const keys = Object.keys(events) - for(const i in keys) { + for (const i in keys) { const key = keys[i] if (eventsMap.has(key)) { eventsMap.get(key)(events[key]) @@ -587,7 +587,7 @@ export const connect = async ({ return false } - if (!await connect()) { + if (!(await connect())) { await sessionStore.setStatus(phone, 'offline') return } diff --git a/src/services/store.ts b/src/services/store.ts index 0ca04d42..910fa479 100644 --- a/src/services/store.ts +++ b/src/services/store.ts @@ -11,8 +11,8 @@ export interface getStore { } export type Store = { - dataStore: DataStore, - sessionStore: SessionStore, + dataStore: DataStore + sessionStore: SessionStore state: AuthenticationState saveCreds: () => Promise mediaStore: MediaStore diff --git a/src/services/store_file.ts b/src/services/store_file.ts index 2e5b32d9..24992305 100644 --- a/src/services/store_file.ts +++ b/src/services/store_file.ts @@ -81,7 +81,7 @@ const storeFile: store = async (phone: string, config: Config): Promise = } } setInterval(() => { - dataStore.writeToFile(dataFile), 10_0000 + ;(dataStore.writeToFile(dataFile), 10_0000) }) } else { logger.info('Store data not save') diff --git a/src/services/timer.ts b/src/services/timer.ts index 55362b1c..200dcedb 100644 --- a/src/services/timer.ts +++ b/src/services/timer.ts @@ -3,23 +3,19 @@ import { UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_TIMER } from '../defaults' import { setLastTimer } from './redis' import logger from './logger' - export const start = async (phone, to, timeout, message) => { const now = new Date() const payload = { - phone, to, message, time: now.toISOString() + phone, + to, + message, + time: now.toISOString(), } logger.debug('timer start phone %s to %s timeout %s', phone, to, timeout) await setLastTimer(phone, to, now) - await amqpPublish( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_TIMER, - phone, - { payload }, - { type: 'topic', delay: timeout } - ) + await amqpPublish(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_TIMER, phone, { payload }, { type: 'topic', delay: timeout }) } export const stop = async (from, to) => { return setLastTimer(from, to, new Date()) -} \ No newline at end of file +} diff --git a/src/services/transformer.ts b/src/services/transformer.ts index 216db078..656c0053 100644 --- a/src/services/transformer.ts +++ b/src/services/transformer.ts @@ -63,12 +63,7 @@ export const TYPE_MESSAGES_TO_READ = [ 'ptvMessage', ] -const OTHER_MESSAGES_TO_PROCESS = [ - 'protocolMessage', - 'senderKeyDistributionMessage', - 'messageContextInfo', - 'messageStubType', -] +const OTHER_MESSAGES_TO_PROCESS = ['protocolMessage', 'senderKeyDistributionMessage', 'messageContextInfo', 'messageStubType'] export const getMimetype = (payload: any) => { const { type } = payload @@ -120,9 +115,7 @@ export const getMessageType = (payload: any) => { return 'receipt' } else if (payload.message) { const { message } = payload - return TYPE_MESSAGES_TO_READ.find((t) => message[t]) || - OTHER_MESSAGES_TO_PROCESS.find((t) => message[t]) || - Object.keys(payload.message)[0] + return TYPE_MESSAGES_TO_READ.find((t) => message[t]) || OTHER_MESSAGES_TO_PROCESS.find((t) => message[t]) || Object.keys(payload.message)[0] } else if (payload.messageStubType) { return 'messageStubType' } @@ -149,7 +142,7 @@ export const getNormalizedMessage = (waMessage: WAMessage): WAMessage | undefine let { message } = binMessage if (message.editedMessage) { message = message.protocolMessage?.editedMessage - }else if (message.protocolMessage?.editedMessage) { + } else if (message.protocolMessage?.editedMessage) { message = message.protocolMessage?.editedMessage } return { key: waMessage.key, message: { [binMessage.messageType]: message } } @@ -277,11 +270,7 @@ export const toBaileysMessageContent = (payload: any, customMessageCharactersFun const phone = contact['phones'][index] const waid = phone['wa_id'] const number = phone['phone'] - const vcard = 'BEGIN:VCARD\n' - + 'VERSION:3.0\n' - + `N:${contacName}\n` - + `TEL;type=CELL;type=VOICE;waid=${waid}:${number}\n` - + 'END:VCARD' + const vcard = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${contacName}\n` + `TEL;type=CELL;type=VOICE;waid=${waid}:${number}\n` + 'END:VCARD' contacts.push({ vcard }) } const displayName = contact['phones'].length > 1 ? `${contact['phones'].length} contacts` : contacName @@ -324,7 +313,9 @@ export const isIndividualMessage = (payload: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any export const getChatAndNumberAndId = (payload: any): [string, string, string] => { - const { key: { remoteJid } } = payload + const { + key: { remoteJid }, + } = payload if (isIndividualJid(remoteJid)) { return [remoteJid, jidToPhoneNumber(remoteJid), remoteJid] } else { @@ -337,7 +328,7 @@ export const getNumberAndId = (payload: any): [string, string] => { const { key: { remoteJid, senderPn, participantPn, participant, senderLid, participantLid }, participant: participant2, - participantPn: participantPn2 + participantPn: participantPn2, } = payload const value = senderLid || participantLid || participant || participant2 || remoteJid @@ -366,29 +357,22 @@ export const isValidPhoneNumber = (value: string, nine = false): boolean => { export const extractDestinyPhone = (payload: object, throwError = true) => { const data = payload as any - const number = data?.to || ( - ( - data?.entry - && data.entry[0] - && data.entry[0].changes - && data.entry[0].changes[0] - && data.entry[0].changes[0].value - ) && ( - ( - data.entry[0].changes[0].value.contacts - && data.entry[0].changes[0].value.contacts[0] - && data.entry[0].changes[0].value.contacts[0].wa_id?.replace('+', '') - ) || ( - data.entry[0].changes[0].value.statuses - && data.entry[0].changes[0].value.statuses[0] - && data.entry[0].changes[0].value.statuses[0].recipient_id?.replace('+', '') - ) || ( - data.entry[0].changes[0].value.messages - && data.entry[0].changes[0].value.messages[0] - && data.entry[0].changes[0].value.messages[0].from?.replace('+', '') - ) - ) - ) + const number = + data?.to || + (data?.entry && + data.entry[0] && + data.entry[0].changes && + data.entry[0].changes[0] && + data.entry[0].changes[0].value && + ((data.entry[0].changes[0].value.contacts && + data.entry[0].changes[0].value.contacts[0] && + data.entry[0].changes[0].value.contacts[0].wa_id?.replace('+', '')) || + (data.entry[0].changes[0].value.statuses && + data.entry[0].changes[0].value.statuses[0] && + data.entry[0].changes[0].value.statuses[0].recipient_id?.replace('+', '')) || + (data.entry[0].changes[0].value.messages && + data.entry[0].changes[0].value.messages[0] && + data.entry[0].changes[0].value.messages[0].from?.replace('+', '')))) if (!number && throwError) { throw Error(`error on get phone number from ${JSON.stringify(payload)}`) } @@ -398,18 +382,15 @@ export const extractDestinyPhone = (payload: object, throwError = true) => { export const getGroupId = (payload: object) => { const data = payload as any return ( - data.entry - && data.entry[0] - && data.entry[0].changes - && data.entry[0].changes[0] - && data.entry[0].changes[0].value - ) && ( - ( - data.entry[0].changes[0].value.contacts - && data.entry[0].changes[0].value.contacts[0] - && data.entry[0].changes[0].value.contacts[0].group_id - ) - ) + data.entry && + data.entry[0] && + data.entry[0].changes && + data.entry[0].changes[0] && + data.entry[0].changes[0].value && + data.entry[0].changes[0].value.contacts && + data.entry[0].changes[0].value.contacts[0] && + data.entry[0].changes[0].value.contacts[0].group_id + ) } export const isGroupMessage = (payload: object) => { @@ -421,13 +402,12 @@ export const isNewsletterMessage = (payload: object) => { return groupId && isJidNewsletter(groupId) } -export const extractSessionPhone = (payload: object) => { +export const extractSessionPhone = (payload: object) => { const data = payload as any - const session = data.entry[0].changes[0].value.messages - && data.entry[0].changes[0].value.metadata - && data.entry[0].changes[0].value.metadata.display_phone_number + const session = + data.entry[0].changes[0].value.messages && data.entry[0].changes[0].value.metadata && data.entry[0].changes[0].value.metadata.display_phone_number - return `${(session || '')}`.replaceAll('+', '') + return `${session || ''}`.replaceAll('+', '') } export const isOutgoingMessage = (payload: object) => { @@ -450,17 +430,14 @@ export const isIncomingMessage = (payload: object) => { export const extractTypeMessage = (payload: object) => { const data = payload as any return ( - ( - data?.entry - && data.entry[0] - && data.entry[0].changes - && data.entry[0].changes[0] - && data.entry[0].changes[0].value - ) && ( - data.entry[0].changes[0].value.messages - && data.entry[0].changes[0].value.messages[0] - && data.entry[0].changes[0].value.messages[0].type - ) + data?.entry && + data.entry[0] && + data.entry[0].changes && + data.entry[0].changes[0] && + data.entry[0].changes[0].value && + data.entry[0].changes[0].value.messages && + data.entry[0].changes[0].value.messages[0] && + data.entry[0].changes[0].value.messages[0].type ) } @@ -468,12 +445,12 @@ export const isAudioMessage = (payload: object) => { return 'audio' == extractTypeMessage(payload) } - export const isFailedStatus = (payload: object) => { const data = payload as any - return 'failed' == (data.entry[0].changes[0].value.statuses - && data.entry[0].changes[0].value.statuses[0] - && data.entry[0].changes[0].value.statuses[0].status) + return ( + 'failed' == + (data.entry[0].changes[0].value.statuses && data.entry[0].changes[0].value.statuses[0] && data.entry[0].changes[0].value.statuses[0].status) + ) } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -497,7 +474,7 @@ export const jidToPhoneNumber = (value: any, plus = '+', retry = true): string = } export const jidToPhoneNumberIfUser = (value: any): string => { - return isIndividualJid(value) ? jidToPhoneNumber(value, '') : value + return isIndividualJid(value) ? jidToPhoneNumber(value, '') : value } /* @@ -541,7 +518,9 @@ export const jidToPhoneNumberIfUser = (value: any): string => { // eslint-disable-next-line @typescript-eslint/no-explicit-any export const fromBaileysMessageContent = (phone: string, payload: any, config?: Partial): [any, string, string] => { try { - const { key: { id: whatsappMessageId, fromMe } } = payload + const { + key: { id: whatsappMessageId, fromMe }, + } = payload const [chatJid, senderPhone, senderId] = getChatAndNumberAndId(payload) const messageType = getMessageType(payload) const binMessage = payload.update || payload.receipt || (messageType && payload.message && payload.message[messageType]) @@ -621,7 +600,7 @@ export const fromBaileysMessageContent = (phone: string, payload: any, config?: if (mediaType == 'pvt') { mediaType = mimetype.split('/')[0] } - message[mediaType] = { + message[mediaType] = { caption: binMessage.caption, filename, mime_type: mimetype, @@ -670,18 +649,22 @@ export const fromBaileysMessageContent = (phone: string, payload: any, config?: } const editedMessageType = getMessageType(editedMessagePayload) const editedBinMessage = getBinMessage(editedMessagePayload) - if (editedMessageType && TYPE_MESSAGES_TO_PROCESS_FILE.includes(editedMessageType) && !editedBinMessage?.message?.url && editedBinMessage?.message?.caption) { + if ( + editedMessageType && + TYPE_MESSAGES_TO_PROCESS_FILE.includes(editedMessageType) && + !editedBinMessage?.message?.url && + editedBinMessage?.message?.caption + ) { editedMessagePayload.message = { - conversation: editedBinMessage?.message?.caption + conversation: editedBinMessage?.message?.caption, } } return fromBaileysMessageContent(phone, editedMessagePayload, config) - case 'protocolMessage': // {"key":{"remoteJid":"351912490567@s.whatsapp.net","fromMe":false,"id":"3EB0C77FBE5C8DACBEC5"},"messageTimestamp":1741714271,"pushName":"Pedro Paiva","broadcast":false,"message":{"protocolMessage":{"key":{"remoteJid":"351211450051@s.whatsapp.net","fromMe":true,"id":"3EB05C0B7B1A0C12284EE0"},"type":"MESSAGE_EDIT","editedMessage":{"conversation":"blablabla2","messageContextInfo":{"messageSecret":"4RYW9eIV1O4j5vjNmY059bZRymJ+B2aTfi9it9+2RxA="}},"timestampMs":"1741714271693"},"messageContextInfo":{"deviceListMetadata":{"senderKeyHash":"UgdPt0CEKvqhyg==","senderTimestamp":"1741018303","senderAccountType":"E2EE","receiverAccountType":"E2EE","recipientKeyHash":"EhuHta8R2tH+8g==","recipientTimestamp":"1740522549"},"deviceListMetadataVersion":2,"messageSecret":"4RYW9eIV1O4j5vjNmY059bZRymJ+B2aTfi9it9+2RxA="}}} if (binMessage.editedMessage) { - return fromBaileysMessageContent(phone, { ...payload, message: { editedMessage: { message: { protocolMessage: binMessage }}}}, config) + return fromBaileysMessageContent(phone, { ...payload, message: { editedMessage: { message: { protocolMessage: binMessage } } } }, config) } else { logger.debug(`Ignore message type ${messageType}`) return [null, senderPhone, senderId] @@ -755,10 +738,12 @@ export const fromBaileysMessageContent = (phone: string, payload: any, config?: case 'messageStubType': MESSAGE_STUB_TYPE_ERRORS - if (payload.messageStubType == 2 && - payload.messageStubParameters && - payload.messageStubParameters[0] && - MESSAGE_STUB_TYPE_ERRORS.includes(payload.messageStubParameters[0].toLowerCase())) { + if ( + payload.messageStubType == 2 && + payload.messageStubParameters && + payload.messageStubParameters[0] && + MESSAGE_STUB_TYPE_ERRORS.includes(payload.messageStubParameters[0].toLowerCase()) + ) { message.text = { body: MESSAGE_CHECK_WAAPP || t('failed_decrypt'), } @@ -933,10 +918,10 @@ export const fromBaileysMessageContent = (phone: string, payload: any, config?: } export const toBuffer = (arrayBuffer) => { - const buffer = Buffer.alloc(arrayBuffer.byteLength); - const view = new Uint8Array(arrayBuffer); + const buffer = Buffer.alloc(arrayBuffer.byteLength) + const view = new Uint8Array(arrayBuffer) for (let i = 0; i < buffer.length; ++i) { - buffer[i] = view[i]; + buffer[i] = view[i] } - return buffer; + return buffer } diff --git a/src/standalone.ts b/src/standalone.ts index fa94e55d..a6623148 100644 --- a/src/standalone.ts +++ b/src/standalone.ts @@ -39,14 +39,14 @@ import { OnNewLogin } from './services/socket' import { onNewLoginAlert } from './services/on_new_login_alert' import { onNewLoginGenerateToken } from './services/on_new_login_generate_token' import { Broadcast } from './services/broadcast' -import { +import { isInBlacklistInMemory, addToBlacklistInMemory, addToBlacklist, addToBlacklistRedis, addToBlacklistJob, isInBlacklist, - isInBlacklistInRedis + isInBlacklistInRedis, } from './services/blacklist' import { Listener } from './services/listener' import { ListenerBaileys } from './services/listener_baileys' @@ -97,7 +97,7 @@ let middlewareVar: middleware = middlewareNext if (process.env.REDIS_URL) { logger.info('Starting with redis') - startRedis().catch( error => { + startRedis().catch((error) => { console.error(error, 'Erro on start') process.exit(1) }) @@ -111,7 +111,7 @@ if (process.env.REDIS_URL) { if (process.env.AMQP_URL) { logger.info('Starting with broker') - amqpConnect().catch( error => { + amqpConnect().catch((error) => { console.error(error, 'Erro on start rabbitmq') process.exit(1) }) @@ -125,29 +125,13 @@ if (process.env.AMQP_URL) { const bindBridgeJob = new BindBridgeJob() const logoutJob = new LogoutJob(logout) logger.info('Starting bind bridge consumer') - amqpConsume( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_BIND}.${UNOAPI_SERVER_NAME}`, - '*', - bindBridgeJob.consume.bind(bindBridgeJob), - { type: 'direct' } - ) + amqpConsume(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_BIND}.${UNOAPI_SERVER_NAME}`, '*', bindBridgeJob.consume.bind(bindBridgeJob), { + type: 'direct', + }) logger.info('Starting reload consumer') - amqpConsume( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_RELOAD}.${UNOAPI_SERVER_NAME}`, - '', - reloadJob.consume.bind(reloadJob), - { type: 'direct' } - ) + amqpConsume(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_RELOAD}.${UNOAPI_SERVER_NAME}`, '', reloadJob.consume.bind(reloadJob), { type: 'direct' }) logger.info('Starting logout consumer') - amqpConsume( - UNOAPI_EXCHANGE_BRIDGE_NAME, - `${UNOAPI_QUEUE_LOGOUT}.${UNOAPI_SERVER_NAME}`, - '', - logoutJob.consume.bind(logoutJob), - { type: 'direct' } - ) + amqpConsume(UNOAPI_EXCHANGE_BRIDGE_NAME, `${UNOAPI_QUEUE_LOGOUT}.${UNOAPI_SERVER_NAME}`, '', logoutJob.consume.bind(logoutJob), { type: 'direct' }) logger.info('Starting media consumer') const mediaJob = new MediaJob(getConfigVar) amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_MEDIA, '*', mediaJob.consume.bind(mediaJob), { type: 'topic' }) @@ -157,32 +141,22 @@ if (process.env.AMQP_URL) { logger.info('Starting outgoing consumer %s', UNOAPI_SERVER_NAME) const outgoingCloudApi: Outgoing = new OutgoingCloudApi(getConfigRedis, isInBlacklistInRedis) const outgoinJob = new OutgoingJob(getConfigVar, outgoingCloudApi) - amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_OUTGOING, - '*', - outgoinJob.consume.bind(outgoinJob), - { notifyFailedMessages, prefetch, type: 'topic' } - ) + amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_OUTGOING, '*', outgoinJob.consume.bind(outgoinJob), { + notifyFailedMessages, + prefetch, + type: 'topic', + }) if (notifyFailedMessages) { logger.debug('Starting notification consumer %s', UNOAPI_SERVER_NAME) const notificationJob = new NotificationJob(incoming) - amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_NOTIFICATION, - '*', - notificationJob.consume.bind(notificationJob), - { notifyFailedMessages: false, type: 'topic' }) + amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_NOTIFICATION, '*', notificationJob.consume.bind(notificationJob), { + notifyFailedMessages: false, + type: 'topic', + }) } logger.info('Starting blacklist add consumer %s', UNOAPI_SERVER_NAME) - amqpConsume( - UNOAPI_EXCHANGE_BROKER_NAME, - UNOAPI_QUEUE_BLACKLIST_ADD, - '*', - atbl, - { notifyFailedMessages, prefetch, type: 'topic' } - ) + amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_BLACKLIST_ADD, '*', atbl, { notifyFailedMessages, prefetch, type: 'topic' }) } else { logger.info('Starting standard mode') } @@ -209,7 +183,7 @@ const app: App = new App( logout, middlewareVar, injectRouteDummy, - contact + contact, ) broadcast.setSever(app.socket) @@ -233,4 +207,4 @@ process.on('unhandledRejection', (reason: any, promise) => { logger.error('unhandledRejection: %s', reason.stack) logger.error('promise: %s', promise) process.exit(1) -}) \ No newline at end of file +}) diff --git a/src/utils/media_to_buffer.ts b/src/utils/media_to_buffer.ts index a862b670..6f01122c 100644 --- a/src/utils/media_to_buffer.ts +++ b/src/utils/media_to_buffer.ts @@ -1,4 +1,3 @@ - import fetch, { Response, RequestInit } from 'node-fetch' import logger from '../services/logger' import { toBuffer } from '../services/transformer' @@ -6,7 +5,7 @@ import { toBuffer } from '../services/transformer' export default async function (url: string, token: string, timeoutMs: number) { const headers = { 'Content-Type': 'application/json; charset=utf-8', - 'Authorization': `Bearer ${token}` + Authorization: `Bearer ${token}`, } const options: RequestInit = { method: 'GET', headers } if (timeoutMs > 0) { @@ -36,4 +35,4 @@ export default async function (url: string, token: string, timeoutMs: number) { } const arrayBuffer = await response.arrayBuffer() return { buffer: toBuffer(arrayBuffer), link: json['url'] } -} \ No newline at end of file +} diff --git a/src/waker.ts b/src/waker.ts index 7485aba6..819552ac 100644 --- a/src/waker.ts +++ b/src/waker.ts @@ -28,7 +28,7 @@ const bridgeQueues = [UNOAPI_QUEUE_LISTENER, UNOAPI_QUEUE_INCOMING] const queues = bridgeQueues.concat(brokerQueues) -const getExchangeName = queue => { +const getExchangeName = (queue) => { if (bridgeQueues.includes(queue)) { return UNOAPI_EXCHANGE_BRIDGE_NAME } else if (brokerQueues.includes(queue)) { @@ -38,10 +38,10 @@ const getExchangeName = queue => { } } -(async () => { +;(async () => { return Promise.all( - queues.map(async queue => { - const connection = await amqpConnect() + queues.map(async (queue) => { + const connection = await amqpConnect() const queueName = queueDeadName(queue) const exchangeName = queueDeadName(getExchangeName(queue)) const exchangeType = 'topic' @@ -54,17 +54,13 @@ const getExchangeName = queue => { if (!payload) { throw 'payload not be null' } - await amqpPublish( - exchangeName, - queue, - extractRoutingKeyFromBindingKey(payload.fields.routingKey), - JSON.parse(payload.content.toString()), - { type: exchangeType } - ) + await amqpPublish(exchangeName, queue, extractRoutingKeyFromBindingKey(payload.fields.routingKey), JSON.parse(payload.content.toString()), { + type: exchangeType, + }) return channel.ack(payload) }) await channel.unbindQueue(queueName, exchangeName) - }) + }), ) })() @@ -83,4 +79,4 @@ process.on('unhandledRejection', (reason: any, promise) => { logger.error('unhandledRejection: %s', reason.stack) logger.error('promise: %s', promise) process.exit(1) -}) \ No newline at end of file +}) diff --git a/src/web.ts b/src/web.ts index e9716579..95d58483 100644 --- a/src/web.ts +++ b/src/web.ts @@ -8,8 +8,8 @@ import { Outgoing } from './services/outgoing' import { OutgoingAmqp } from './services/outgoing_amqp' import { SessionStore } from './services/session_store' import { SessionStoreRedis } from './services/session_store_redis' -import { - BASE_URL, +import { + BASE_URL, PORT, CONFIG_SESSION_PHONE_CLIENT, CONFIG_SESSION_PHONE_NAME, @@ -58,10 +58,15 @@ app.server.listen(PORT, '0.0.0.0', async () => { logger.info('Starting broadcast consumer') await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_BROADCAST, '*', broadcastJob.consume.bind(broadcastJob), { type: 'topic' }) await amqpConsume(UNOAPI_EXCHANGE_BROKER_NAME, UNOAPI_QUEUE_RELOAD, '*', reload.run.bind(reloadJob), { type: 'topic' }) - logger.info('Unoapi Cloud version: %s, listening on port: %s | Linked Device: %s(%s)', version, PORT, CONFIG_SESSION_PHONE_CLIENT, CONFIG_SESSION_PHONE_NAME) + logger.info( + 'Unoapi Cloud version: %s, listening on port: %s | Linked Device: %s(%s)', + version, + PORT, + CONFIG_SESSION_PHONE_CLIENT, + CONFIG_SESSION_PHONE_NAME, + ) }) - process.on('uncaughtException', (reason: any) => { if (process.env.SENTRY_DSN) { Sentry.captureException(reason) diff --git a/tsconfig.json b/tsconfig.json index 0315d95b..9c4acf30 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "module": "NodeNext", "moduleResolution": "nodenext", "experimentalDecorators": true, - "allowJs": false, + "allowJs": true, "checkJs": false, "outDir": "dist", "strict": false, @@ -21,7 +21,7 @@ "include": ["src/**/*.ts", "src/**/*.json"], "ts-node": { "compilerOptions": { - "esModuleInterop": true, + "esModuleInterop": true } } } diff --git a/yarn.lock b/yarn.lock index 6ce61f78..5aeade07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -871,6 +871,16 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@borewit/text-codec@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@borewit/text-codec/-/text-codec-0.1.1.tgz#7e7f27092473d5eabcffef693a849f2cc48431da" + integrity sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA== + +"@borewit/text-codec@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@borewit/text-codec/-/text-codec-0.2.0.tgz#1dbf3097b136b0dda56bce3ef53886c338ea3202" + integrity sha512-X999CKBxGwX8wW+4gFibsbiNdwqmdQEXmUejIWaIqdrHBgS5ARIOOeyiQbHjP9G58xVEPcuvP6VwwH3A0OFTOA== + "@cacheable/node-cache@^1.4.0": version "1.6.1" resolved "https://registry.yarnpkg.com/@cacheable/node-cache/-/node-cache-1.6.1.tgz#8e845eea011518ab96999a4c893e273812eeb00f" @@ -2611,6 +2621,15 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== +"@tokenizer/inflate@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@tokenizer/inflate/-/inflate-0.2.7.tgz#32dd9dfc9abe457c89b3d9b760fc0690c85a103b" + integrity sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg== + dependencies: + debug "^4.4.0" + fflate "^0.8.2" + token-types "^6.0.0" + "@tokenizer/token@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" @@ -3876,7 +3895,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7: +debug@4, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.5, debug@^4.3.7, debug@^4.4.0, debug@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== @@ -4457,6 +4476,11 @@ fetch-blob@^3.1.2, fetch-blob@^3.1.4: node-domexception "^1.0.0" web-streams-polyfill "^3.0.3" +fflate@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" + integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4473,6 +4497,16 @@ file-type@^16.5.4: strtok3 "^6.2.4" token-types "^4.1.1" +file-type@^21.0.0: + version "21.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-21.0.0.tgz#b6c5990064bc4b704f8e5c9b6010c59064d268bc" + integrity sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg== + dependencies: + "@tokenizer/inflate" "^0.2.7" + strtok3 "^10.2.2" + token-types "^6.0.0" + uint8array-extras "^1.4.0" + fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -5633,6 +5667,13 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +"libsignal@git+https://github.com/whiskeysockets/libsignal-node.git": + version "2.0.1" + resolved "git+https://github.com/whiskeysockets/libsignal-node.git#4d08331a833727c338c1a90041d17b870210dfae" + dependencies: + curve25519-js "^0.0.4" + protobufjs "6.8.8" + "libsignal@github:WhiskeySockets/libsignal-node": version "2.0.1" resolved "https://codeload.github.com/WhiskeySockets/libsignal-node/tar.gz/4d08331a833727c338c1a90041d17b870210dfae" @@ -5873,6 +5914,21 @@ ms@2.1.3, ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +music-metadata@^11.7.0: + version "11.8.3" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-11.8.3.tgz#fcba77613e11644bfd9b3c11876aecbee18f95be" + integrity sha512-Tgiv4MlCgDb6XzelziB1mmL2xeoHls0KTpCm3Z3qr+LfF4mBEpkuc5vNrc927IT5+S5fv+vzStfI+HYC0igDpA== + dependencies: + "@borewit/text-codec" "^0.2.0" + "@tokenizer/token" "^0.3.0" + content-type "^1.0.5" + debug "^4.4.1" + file-type "^21.0.0" + media-typer "^1.1.0" + strtok3 "^10.3.4" + token-types "^6.1.1" + uint8array-extras "^1.4.1" + music-metadata@^7.12.3: version "7.14.0" resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-7.14.0.tgz#74e3e5fc8e09b86d1a3e791fb5ce9ccdc4347ad9" @@ -7105,6 +7161,13 @@ strnum@^2.1.0: resolved "https://registry.yarnpkg.com/strnum/-/strnum-2.1.1.tgz#cf2a6e0cf903728b8b2c4b971b7e36b4e82d46ab" integrity sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw== +strtok3@^10.2.2, strtok3@^10.3.4: + version "10.3.4" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.3.4.tgz#793ebd0d59df276a085586134b73a406e60be9c1" + integrity sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg== + dependencies: + "@tokenizer/token" "^0.3.0" + strtok3@^6.2.4, strtok3@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" @@ -7241,6 +7304,15 @@ token-types@^4.1.1, token-types@^4.2.1: "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" +token-types@^6.0.0, token-types@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.1.1.tgz#85bd0ada82939b9178ecd5285881a538c4c00fdd" + integrity sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ== + dependencies: + "@borewit/text-codec" "^0.1.0" + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + touch@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694" @@ -7385,6 +7457,11 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== +uint8array-extras@^1.4.0, uint8array-extras@^1.4.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.5.0.tgz#10d2a85213de3ada304fea1c454f635c73839e86" + integrity sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A== + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" From 444126ec94f230ac675849d573640d413aedb60b Mon Sep 17 00:00:00 2001 From: mbap-dev Date: Mon, 1 Sep 2025 18:05:41 -0300 Subject: [PATCH 21/21] chore: update version to 2.5.0 in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7625aa0f..47747b19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unoapi-cloud", - "version": "2.5.0-alpha-11", + "version": "2.5.0", "description": "Unoapi Cloud", "exports": "./dist/index.js", "types": "./dist/index.d.ts",