@omnizap-system/omnizap 2.6.0 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +58 -13
- package/.github/workflows/ci.yml +5 -5
- package/.github/workflows/codeql.yml +1 -1
- package/.github/workflows/db-migration-check.yml +2 -2
- package/.github/workflows/dependency-review.yml +1 -1
- package/.github/workflows/deploy.yml +2 -2
- package/.github/workflows/release.yml +2 -2
- package/.github/workflows/security-attest-provenance.yml +2 -2
- package/.github/workflows/security-gitleaks.yml +13 -4
- package/.github/workflows/security-runner-hardening.yml +2 -2
- package/.github/workflows/security-scorecard.yml +1 -1
- package/.github/workflows/security-zap-baseline.yml +1 -1
- package/.github/workflows/security-zap-full-scan.yml +2 -1
- package/.github/workflows/security-zizmor.yml +1 -1
- package/.github/workflows/wiki-sync.yml +1 -1
- package/.gitleaksignore +9 -0
- package/CODE_OF_CONDUCT.md +2 -2
- package/GEMINI.md +64 -0
- package/README.md +52 -82
- package/SECURITY.md +1 -1
- package/app/config/index.js +2 -0
- package/app/configParts/adminIdentity.js +5 -5
- package/app/configParts/baileysConfig.js +230 -58
- package/app/configParts/groupUtils.js +5 -0
- package/app/configParts/messagePersistenceService.js +145 -4
- package/app/configParts/sessionConfig.js +157 -0
- package/app/connection/baileysCompatibility.test.js +1 -1
- package/app/connection/groupOwnerWriteStateResolver.js +109 -0
- package/app/connection/socketController.js +660 -158
- package/app/connection/socketController.multiSession.test.js +108 -0
- package/app/controllers/messageController.js +1 -1
- package/app/controllers/messagePipeline/commandMiddleware.js +12 -10
- package/app/controllers/messagePipeline/conversationMiddleware.js +2 -1
- package/app/controllers/messagePipeline/messagePipelineMiddlewares.test.js +104 -0
- package/app/controllers/messagePipeline/preProcessingMiddlewares.js +80 -2
- package/app/controllers/messageProcessingPipeline.js +93 -13
- package/app/controllers/messageProcessingPipeline.test.js +200 -0
- package/app/modules/adminModule/AGENT.md +1 -1
- package/app/modules/adminModule/commandConfig.json +3318 -1347
- package/app/modules/adminModule/groupCommandHandlers.js +858 -15
- package/app/modules/adminModule/groupCommandHandlers.test.js +378 -11
- package/app/modules/adminModule/groupWarningRepository.js +152 -0
- package/app/modules/aiModule/AGENT.md +47 -30
- package/app/modules/aiModule/aiConfigRuntime.js +1 -0
- package/app/modules/aiModule/catCommand.js +135 -27
- package/app/modules/aiModule/commandConfig.json +114 -28
- package/app/modules/analyticsModule/messageAnalysisEventRepository.js +54 -6
- package/app/modules/gameModule/AGENT.md +1 -1
- package/app/modules/gameModule/commandConfig.json +29 -0
- package/app/modules/menuModule/AGENT.md +1 -1
- package/app/modules/menuModule/commandConfig.json +45 -10
- package/app/modules/menuModule/menuCatalogService.js +190 -0
- package/app/modules/menuModule/menuCommandUsageRepository.js +109 -0
- package/app/modules/menuModule/menuDynamicService.js +511 -0
- package/app/modules/menuModule/menuDynamicService.test.js +141 -0
- package/app/modules/menuModule/menus.js +36 -5
- package/app/modules/playModule/AGENT.md +10 -5
- package/app/modules/playModule/commandConfig.json +140 -12
- package/app/modules/playModule/playCommand.js +1 -1417
- package/app/modules/playModule/playCommandConstants.js +80 -0
- package/app/modules/playModule/playCommandCore.js +361 -0
- package/app/modules/playModule/playCommandHandlers.js +41 -0
- package/app/modules/playModule/playCommandMediaClient.js +1872 -0
- package/app/modules/playModule/playConfigRuntime.js +245 -4
- package/app/modules/playModule/playModuleCriticalFlows.test.js +152 -0
- package/app/modules/quoteModule/AGENT.md +1 -1
- package/app/modules/quoteModule/commandConfig.json +29 -0
- package/app/modules/quoteModule/quoteCommand.js +3 -2
- package/app/modules/rpgPokemonModule/AGENT.md +1 -1
- package/app/modules/rpgPokemonModule/commandConfig.json +29 -0
- package/app/modules/rpgPokemonModule/rpgBattleCanvasRenderer.js +5 -4
- package/app/modules/rpgPokemonModule/rpgBattleService.test.js +2 -1
- package/app/modules/rpgPokemonModule/rpgPokemonDomain.js +2 -1
- package/app/modules/rpgPokemonModule/rpgPokemonService.js +38 -37
- package/app/modules/rpgPokemonModule/rpgProfileCanvasRenderer.js +4 -3
- package/app/modules/statsModule/AGENT.md +1 -1
- package/app/modules/statsModule/commandConfig.json +58 -0
- package/app/modules/statsModule/rankingCommon.js +5 -4
- package/app/modules/stickerModule/AGENT.md +1 -1
- package/app/modules/stickerModule/addStickerMetadata.js +4 -3
- package/app/modules/stickerModule/commandConfig.json +145 -0
- package/app/modules/stickerModule/stickerCommand.js +1 -1
- package/app/modules/stickerPackModule/AGENT.md +1 -1
- package/app/modules/stickerPackModule/autoPackCollectorService.js +5 -1
- package/app/modules/stickerPackModule/commandConfig.json +29 -0
- package/app/modules/stickerPackModule/semanticThemeClusterService.js +7 -6
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +10 -9
- package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +9 -8
- package/app/modules/stickerPackModule/stickerDomainEventConsumerRuntime.js +3 -2
- package/app/modules/stickerPackModule/stickerMarketplaceDriftService.js +2 -1
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +80 -58
- package/app/modules/stickerPackModule/stickerPackMarketplaceService.js +2 -1
- package/app/modules/stickerPackModule/stickerPackRepository.js +2 -1
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRuntime.js +5 -4
- package/app/modules/stickerPackModule/stickerPackService.js +13 -6
- package/app/modules/stickerPackModule/stickerStorageService.js +3 -2
- package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +2 -1
- package/app/modules/systemMetricsModule/AGENT.md +1 -1
- package/app/modules/systemMetricsModule/commandConfig.json +29 -0
- package/app/modules/systemMetricsModule/pingCommand.js +6 -5
- package/app/modules/tiktokModule/AGENT.md +1 -1
- package/app/modules/tiktokModule/commandConfig.json +29 -0
- package/app/modules/tiktokModule/tiktokCommand.js +2 -1
- package/app/modules/userModule/AGENT.md +1 -1
- package/app/modules/userModule/commandConfig.json +29 -0
- package/app/modules/userModule/userCommand.js +72 -23
- package/app/modules/waifuPicsModule/AGENT.md +57 -27
- package/app/modules/waifuPicsModule/commandConfig.json +87 -0
- package/app/modules/waifuPicsModule/waifuPicsCommand.js +3 -2
- package/app/observability/metrics.js +136 -0
- package/app/services/ai/commandConfigEnrichmentService.js +229 -47
- package/app/services/ai/conversationRouterService.js +4 -3
- package/app/services/ai/geminiService.js +132 -7
- package/app/services/ai/geminiService.test.js +59 -2
- package/app/services/ai/globalModuleAiHelpService.js +3 -2
- package/app/services/ai/messageCommandExecutionService.js +2 -1
- package/app/services/ai/moduleAiHelpCoreService.js +45 -14
- package/app/services/ai/moduleToolExecutorService.js +3 -2
- package/app/services/ai/moduleToolRegistryService.js +2 -1
- package/app/services/ai/toolCandidateSelectorService.js +6 -5
- package/app/services/auth/googleWebLinkService.js +3 -2
- package/app/services/auth/whatsappLoginLinkService.js +3 -2
- package/app/services/external/pokeApiService.js +4 -3
- package/app/services/group/groupMetadataService.js +24 -1
- package/app/services/infra/dbWriteQueue.js +57 -26
- package/app/services/infra/featureFlagService.js +2 -1
- package/app/services/messaging/captchaService.js +3 -2
- package/app/services/messaging/newsBroadcastService.js +846 -29
- package/app/services/multiSession/assignmentBalancerService.js +457 -0
- package/app/services/multiSession/groupOwnershipRepository.js +381 -0
- package/app/services/multiSession/groupOwnershipService.js +890 -0
- package/app/services/multiSession/groupOwnershipService.test.js +309 -0
- package/app/services/multiSession/sessionRegistryService.js +293 -0
- package/app/services/sticker/stickerFocusService.js +11 -10
- package/app/store/aiPromptStore.js +36 -19
- package/app/store/conversationSessionStore.js +7 -6
- package/app/store/groupConfigStore.js +41 -5
- package/app/store/premiumUserStore.js +21 -7
- package/app/utils/antiLink/antiLinkModule.js +352 -16
- package/app/workers/aiHelperContinuousLearningWorker.js +512 -0
- package/app/workers/aiLearningWorker.js +6 -5
- package/app/workers/commandConfigEnrichmentWorker.js +4 -3
- package/database/index.js +14 -8
- package/database/migrations/20260307_d0_hardening_down.sql +1 -1
- package/database/migrations/20260314_d7_canonical_sender_down.sql +1 -1
- package/database/migrations/20260406_d30_security_analytics_down.sql +1 -1
- package/database/migrations/20260411_d35_group_community_metadata_down.sql +59 -0
- package/database/migrations/20260411_d35_group_community_metadata_up.sql +62 -0
- package/database/migrations/20260412_d36_system_config_tables_down.sql +32 -0
- package/database/migrations/20260412_d36_system_config_tables_up.sql +66 -0
- package/database/migrations/20260413_d37_group_user_warnings_down.sql +11 -0
- package/database/migrations/20260413_d37_group_user_warnings_up.sql +24 -0
- package/database/migrations/20260414_d38_multi_session_foundation_down.sql +72 -0
- package/database/migrations/20260414_d38_multi_session_foundation_up.sql +125 -0
- package/database/migrations/20260414_d39_multi_session_cutover_down.sql +103 -0
- package/database/migrations/20260414_d39_multi_session_cutover_up.sql +83 -0
- package/database/schema.sql +102 -1
- package/docker-compose.yml +4 -1
- package/docs/compliance/acceptable-use-policy-2026-03-07.md +1 -1
- package/docs/compliance/dpa-b2b-standard-2026-03-07.md +1 -1
- package/docs/compliance/privacy-policy-2026-03-07.md +4 -4
- package/docs/security/dsar-lgpd-runbook-2026-03-07.md +1 -1
- package/docs/security/incident-response-lgpd-anpd-runbook-2026-03-07.md +1 -1
- package/docs/security/network-hardening-runbook-2026-03-07.md +53 -0
- package/docs/security/omnizap-static-security-headers.conf +25 -0
- package/docs/wiki/Home.md +1 -1
- package/ecosystem.prod.config.cjs +32 -12
- package/index.js +57 -23
- package/observability/alert-rules.yml +20 -0
- package/observability/grafana/dashboards/omnizap-system-admin.json +229 -0
- package/observability/mysql-setup.sql +4 -4
- package/observability/system-admin-observability.md +26 -0
- package/package.json +20 -6
- package/public/apple-touch-icon.png +0 -0
- package/public/comandos/commands-catalog.json +2853 -3326
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/js/apps/apiDocsApp.js +3 -2
- package/public/js/apps/commandsReactApp.js +280 -99
- package/public/js/apps/createPackApp.js +11 -10
- package/public/js/apps/homeReactApp.js +181 -130
- package/public/js/apps/loginReactApp.js +1 -1
- package/public/js/apps/stickersApp.js +263 -110
- package/public/js/apps/termsReactApp.js +73 -24
- package/public/js/apps/userApp.js +4 -3
- package/public/js/apps/userPasswordResetReactApp.js +406 -0
- package/public/js/apps/userReactApp.js +355 -280
- package/public/js/apps/userSystemAdmReactApp.js +1506 -0
- package/public/pages/api-docs.html +1 -1
- package/public/pages/aup.html +2 -2
- package/public/pages/dpa.html +3 -3
- package/public/pages/licenca.html +4 -4
- package/public/pages/login.html +1 -1
- package/public/pages/notice-and-takedown.html +2 -2
- package/public/pages/politica-de-privacidade.html +6 -6
- package/public/pages/seo-bot-whatsapp-para-grupo.html +3 -3
- package/public/pages/seo-bot-whatsapp-sem-programar.html +3 -3
- package/public/pages/seo-como-automatizar-avisos-no-whatsapp.html +3 -3
- package/public/pages/seo-como-criar-comandos-whatsapp.html +3 -3
- package/public/pages/seo-como-evitar-spam-no-whatsapp.html +3 -3
- package/public/pages/seo-como-moderar-grupo-whatsapp.html +3 -3
- package/public/pages/seo-como-organizar-comunidade-whatsapp.html +3 -3
- package/public/pages/seo-melhor-bot-whatsapp-para-grupos.html +3 -3
- package/public/pages/stickers-admin.html +1 -1
- package/public/pages/stickers-create.html +1 -1
- package/public/pages/stickers.html +6 -6
- package/public/pages/suboperadores.html +2 -2
- package/public/pages/termos-de-uso-texto-integral.html +6 -6
- package/public/pages/termos-de-uso.html +3 -3
- package/public/pages/user-password-reset.html +4 -5
- package/public/pages/user-systemadm.html +9 -463
- package/public/pages/user.html +2 -2
- package/scripts/clear-whatsapp-session.sh +123 -0
- package/scripts/core-ai-mode.mjs +163 -0
- package/scripts/deploy.sh +11 -1
- package/scripts/email-broadcast-terms-update.mjs +2 -1
- package/scripts/enrich-command-config-ux-openai.mjs +492 -0
- package/scripts/generate-commands-catalog.mjs +166 -2
- package/scripts/generate-module-agents.mjs +2 -1
- package/scripts/generate-seo-satellite-pages.mjs +5 -4
- package/scripts/github-deploy-notify.mjs +2 -1
- package/scripts/github-release-notify.mjs +25 -10
- package/scripts/new-whatsapp-session.sh +317 -0
- package/scripts/release.sh +2 -19
- package/scripts/security-smoketest.mjs +6 -5
- package/scripts/security-web-surface-check.mjs +218 -0
- package/scripts/sticker-catalog-loadtest.mjs +5 -4
- package/server/auth/googleWebAuth/googleWebAuthService.js +8 -7
- package/server/auth/jwt/webJwtService.js +1 -1
- package/server/auth/stickerCatalogAuthContext.js +2 -1
- package/server/auth/termsAcceptance/termsAcceptanceHandler.js +2 -1
- package/server/auth/userPassword/userPasswordAuthService.js +2 -1
- package/server/auth/userPassword/userPasswordRecoveryService.js +4 -3
- package/server/auth/webAccount/webAccountHandlers.js +9 -10
- package/server/controllers/admin/adminPanelHandlers.js +267 -16
- package/server/controllers/admin/systemAdminController.js +267 -0
- package/server/controllers/seo/stickerCatalogSeoContext.js +10 -9
- package/server/controllers/sticker/nonCatalogHandlers.js +2 -1
- package/server/controllers/sticker/stickerCatalogController.js +23 -36
- package/server/controllers/system/contactController.js +9 -17
- package/server/controllers/system/githubController.js +3 -2
- package/server/controllers/system/stickerCatalogSystemContext.js +41 -19
- package/server/controllers/system/systemController.js +254 -1
- package/server/controllers/system/systemMetricsController.js +2 -1
- package/server/controllers/userController.js +6 -0
- package/server/email/emailTemplateService.js +5 -3
- package/server/http/httpServer.js +11 -6
- package/server/middleware/rateLimit.js +2 -1
- package/server/middleware/securityHeaders.js +20 -1
- package/server/routes/admin/systemAdminRouter.js +6 -0
- package/server/routes/indexRouter.js +30 -6
- package/server/routes/observability/grafanaProxyRouter.js +254 -0
- package/server/routes/static/staticPageRouter.js +27 -1
- package/server/utils/publicContact.js +31 -0
- package/utils/time/timeModule.js +135 -0
- package/utils/time/timeModule.test.js +65 -0
- package/utils/whatsapp/contactEnv.js +39 -0
- package/vite.config.mjs +7 -1
- package/public/assets/images/brand-icon-192.png +0 -0
- package/scripts/sync-readme-snapshot.mjs +0 -133
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { encodeJid, getJidUser, isSameJidUser, normalizeJid } from './baileysConfig.js';
|
|
2
2
|
import { extractUserIdInfo, resolveUserId, resolveUserIdCached } from './baileysConfig.js';
|
|
3
|
+
import { normalizePhoneDigits, resolveAdminIdentityRawFromEnv, resolveAdminPhoneFromEnv } from '../../utils/whatsapp/contactEnv.js';
|
|
3
4
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const normalizePhoneDigits = (value) => String(value || '').replace(/\D+/g, '');
|
|
7
|
-
|
|
8
|
-
export const getAdminRawValue = () => String(process.env[ADMIN_ENV_KEY] || '').trim();
|
|
5
|
+
export const getAdminRawValue = () => resolveAdminIdentityRawFromEnv();
|
|
9
6
|
|
|
10
7
|
export const getAdminJid = () => {
|
|
11
8
|
const raw = getAdminRawValue();
|
|
@@ -28,6 +25,9 @@ export const getAdminJid = () => {
|
|
|
28
25
|
};
|
|
29
26
|
|
|
30
27
|
export const getAdminPhone = () => {
|
|
28
|
+
const explicitAdminPhone = resolveAdminPhoneFromEnv({ fallback: '' });
|
|
29
|
+
if (explicitAdminPhone) return explicitAdminPhone;
|
|
30
|
+
|
|
31
31
|
const adminJid = getAdminJid();
|
|
32
32
|
if (!adminJid) return null;
|
|
33
33
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { now as __timeNow, nowIso as __timeNowIso, toUnixMs as __timeNowMs } from '#time';
|
|
1
2
|
/* eslint-disable no-unused-vars */
|
|
2
3
|
/* eslint-disable no-useless-escape */
|
|
3
4
|
import { fetchLatestBaileysVersion, downloadContentFromMessage, jidNormalizedUser, jidEncode, jidDecode, areJidsSameUser, normalizeMessageContent, isJidMetaAI, isPnUser, isLidUser, isJidBroadcast, isJidGroup, isJidStatusBroadcast, isJidNewsletter, isHostedPnUser, isHostedLidUser, isJidBot, SERVER_JID, PSA_WID, STORIES_JID, META_AI_JID, delay } from '@whiskeysockets/baileys';
|
|
@@ -12,20 +13,164 @@ import path from 'node:path';
|
|
|
12
13
|
import { pipeline } from 'node:stream/promises';
|
|
13
14
|
import { Readable } from 'node:stream';
|
|
14
15
|
import { fileURLToPath } from 'node:url';
|
|
16
|
+
import { getMultiSessionRuntimeConfig } from './sessionConfig.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Utilitários centrais de integração com Baileys.
|
|
20
|
+
*
|
|
21
|
+
* Responsabilidades deste módulo:
|
|
22
|
+
* - validar/normalizar JIDs e tipos de presença;
|
|
23
|
+
* - encapsular chamadas seguras no socket ativo;
|
|
24
|
+
* - extrair/detectar mídia em mensagens;
|
|
25
|
+
* - resolver mapeamento LID <-> JID com cache e persistência.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {import('@whiskeysockets/baileys').WASocket} BaileysSocket
|
|
30
|
+
* @typedef {import('@whiskeysockets/baileys').WAMessage} BaileysMessage
|
|
31
|
+
* @typedef {import('@whiskeysockets/baileys').WAProto.IMessage} BaileysProtoMessage
|
|
32
|
+
* @typedef {'lid'|'pn'} AddressingMode
|
|
33
|
+
* @typedef {{includeAllTypes?: boolean, includeQuoted?: boolean, includeUnknown?: boolean}} MediaExtractionOptions
|
|
34
|
+
* @typedef {{
|
|
35
|
+
* mediaType: string,
|
|
36
|
+
* mediaKey: Record<string, any>,
|
|
37
|
+
* messageKey: string,
|
|
38
|
+
* isQuoted: boolean,
|
|
39
|
+
* isBinary: boolean,
|
|
40
|
+
* isUnknownType?: boolean,
|
|
41
|
+
* hasUrl: boolean,
|
|
42
|
+
* hasDirectPath: boolean,
|
|
43
|
+
* hasMediaKey: boolean,
|
|
44
|
+
* hasFileEncSha256: boolean,
|
|
45
|
+
* mimetype: string|null,
|
|
46
|
+
* fileLength: number|string|null,
|
|
47
|
+
* fileName: string|null,
|
|
48
|
+
* caption: string|null
|
|
49
|
+
* }} MediaEntry
|
|
50
|
+
* @typedef {{
|
|
51
|
+
* mediaType: string,
|
|
52
|
+
* mediaKey: Record<string, any>,
|
|
53
|
+
* isQuoted: boolean,
|
|
54
|
+
* details: {
|
|
55
|
+
* messageKey: string,
|
|
56
|
+
* isBinary: boolean,
|
|
57
|
+
* isUnknownType?: boolean,
|
|
58
|
+
* hasUrl: boolean,
|
|
59
|
+
* hasDirectPath: boolean,
|
|
60
|
+
* hasMediaKey: boolean,
|
|
61
|
+
* hasFileEncSha256: boolean,
|
|
62
|
+
* mimetype: string|null,
|
|
63
|
+
* fileLength: number|string|null,
|
|
64
|
+
* fileName: string|null,
|
|
65
|
+
* caption: string|null,
|
|
66
|
+
* allMediaFound: MediaEntry[]|null
|
|
67
|
+
* }
|
|
68
|
+
* }} MediaExtractionResult
|
|
69
|
+
* @typedef {{lid?: string|null, jid?: string|null, participantAlt?: string|null}} IdentityParams
|
|
70
|
+
* @typedef {{jid: string|null, expiresAt: number, lastStoredAt: number|null}} LidCacheEntry
|
|
71
|
+
* @typedef {{
|
|
72
|
+
* lid: string|null,
|
|
73
|
+
* jid: string|null,
|
|
74
|
+
* participantAlt: string|null,
|
|
75
|
+
* remoteJid: string|null,
|
|
76
|
+
* remoteJidAlt: string|null,
|
|
77
|
+
* groupMessage: boolean
|
|
78
|
+
* }} SenderInfo
|
|
79
|
+
*/
|
|
15
80
|
|
|
16
81
|
const DEFAULT_BAILEYS_VERSION = [7, 0, 0];
|
|
82
|
+
const multiSessionRuntimeConfig = getMultiSessionRuntimeConfig();
|
|
83
|
+
const PRIMARY_BAILEYS_SESSION_ID = String(multiSessionRuntimeConfig?.primarySessionId || process.env.BAILEYS_AUTH_SESSION_ID || 'default').trim() || 'default';
|
|
84
|
+
|
|
85
|
+
const normalizeSessionId = (sessionId) => {
|
|
86
|
+
const normalized = String(sessionId || '').trim();
|
|
87
|
+
return normalized || PRIMARY_BAILEYS_SESSION_ID;
|
|
88
|
+
};
|
|
17
89
|
|
|
90
|
+
const sessionSocketMap = new Map();
|
|
18
91
|
let activeSocket = null;
|
|
19
92
|
|
|
20
|
-
|
|
21
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Atualiza a referência global do socket ativo e o registro por sessão.
|
|
95
|
+
* Mantém compatibilidade com chamadas legadas que não informam `sessionId`.
|
|
96
|
+
* @param {BaileysSocket|null} socket Instância conectada ou `null` para limpar.
|
|
97
|
+
* @param {string} [sessionId=PRIMARY_BAILEYS_SESSION_ID] Sessão da conexão.
|
|
98
|
+
* @returns {void}
|
|
99
|
+
*/
|
|
100
|
+
export const setActiveSocket = (socket, sessionId = PRIMARY_BAILEYS_SESSION_ID) => {
|
|
101
|
+
const safeSessionId = normalizeSessionId(sessionId);
|
|
102
|
+
const previousSocket = sessionSocketMap.get(safeSessionId) || null;
|
|
103
|
+
|
|
104
|
+
if (socket) {
|
|
105
|
+
sessionSocketMap.set(safeSessionId, socket);
|
|
106
|
+
} else {
|
|
107
|
+
sessionSocketMap.delete(safeSessionId);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (safeSessionId === PRIMARY_BAILEYS_SESSION_ID) {
|
|
111
|
+
activeSocket = socket || null;
|
|
112
|
+
} else if (!socket && previousSocket && activeSocket === previousSocket) {
|
|
113
|
+
activeSocket = null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!activeSocket) {
|
|
117
|
+
activeSocket = sessionSocketMap.get(PRIMARY_BAILEYS_SESSION_ID) || sessionSocketMap.values().next()?.value || null;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Atualiza o socket ativo de uma sessão específica.
|
|
123
|
+
* @param {string} sessionId Sessão alvo.
|
|
124
|
+
* @param {BaileysSocket|null} socket Instância conectada ou `null`.
|
|
125
|
+
* @returns {void}
|
|
126
|
+
*/
|
|
127
|
+
export const setSocketBySession = (sessionId, socket) => {
|
|
128
|
+
setActiveSocket(socket, sessionId);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Retorna a instância de socket ativa no processo.
|
|
133
|
+
* @returns {BaileysSocket|null}
|
|
134
|
+
*/
|
|
135
|
+
export const getActiveSocket = () => {
|
|
136
|
+
if (isSocketOpen(activeSocket)) return activeSocket;
|
|
137
|
+
|
|
138
|
+
const primarySocket = sessionSocketMap.get(PRIMARY_BAILEYS_SESSION_ID) || null;
|
|
139
|
+
if (isSocketOpen(primarySocket)) {
|
|
140
|
+
activeSocket = primarySocket;
|
|
141
|
+
return activeSocket;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const socket of sessionSocketMap.values()) {
|
|
145
|
+
if (isSocketOpen(socket)) {
|
|
146
|
+
activeSocket = socket;
|
|
147
|
+
return activeSocket;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
activeSocket = null;
|
|
152
|
+
return activeSocket;
|
|
22
153
|
};
|
|
23
154
|
|
|
24
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Retorna o socket ativo associado a uma sessão.
|
|
157
|
+
* @param {string} [sessionId=PRIMARY_BAILEYS_SESSION_ID]
|
|
158
|
+
* @returns {BaileysSocket|null}
|
|
159
|
+
*/
|
|
160
|
+
export const getSocketBySession = (sessionId = PRIMARY_BAILEYS_SESSION_ID) => {
|
|
161
|
+
const safeSessionId = normalizeSessionId(sessionId);
|
|
162
|
+
return sessionSocketMap.get(safeSessionId) || null;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Snapshot dos sockets ativos por sessão.
|
|
167
|
+
* @returns {Map<string, BaileysSocket>}
|
|
168
|
+
*/
|
|
169
|
+
export const getActiveSocketsBySession = () => new Map(sessionSocketMap);
|
|
25
170
|
|
|
26
171
|
/**
|
|
27
172
|
* Indica se uma instância de socket está aberta para operações.
|
|
28
|
-
* @param {
|
|
173
|
+
* @param {BaileysSocket|null|undefined} socket Instância de socket.
|
|
29
174
|
* @returns {boolean}
|
|
30
175
|
*/
|
|
31
176
|
export const isSocketOpen = (socket) => {
|
|
@@ -42,7 +187,7 @@ export const isActiveSocketOpen = () => isSocketOpen(activeSocket);
|
|
|
42
187
|
|
|
43
188
|
/**
|
|
44
189
|
* Executa um método em uma instância de socket validando disponibilidade.
|
|
45
|
-
* @param {
|
|
190
|
+
* @param {BaileysSocket|null|undefined} socket Instância de socket.
|
|
46
191
|
* @param {string} methodName Nome do método no socket.
|
|
47
192
|
* @param {...any} args Argumentos do método.
|
|
48
193
|
* @returns {Promise<any>}
|
|
@@ -68,9 +213,18 @@ export const runSocketMethod = async (socket, methodName, ...args) => {
|
|
|
68
213
|
*/
|
|
69
214
|
export const runActiveSocketMethod = async (methodName, ...args) => runSocketMethod(activeSocket, methodName, ...args);
|
|
70
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Executa um método no socket de uma sessão específica.
|
|
218
|
+
* @param {string} sessionId Sessão alvo.
|
|
219
|
+
* @param {string} methodName Nome do método no socket.
|
|
220
|
+
* @param {...any} args Argumentos do método.
|
|
221
|
+
* @returns {Promise<any>}
|
|
222
|
+
*/
|
|
223
|
+
export const runSessionSocketMethod = async (sessionId, methodName, ...args) => runSocketMethod(getSocketBySession(sessionId), methodName, ...args);
|
|
224
|
+
|
|
71
225
|
/**
|
|
72
226
|
* Recupera a blocklist da conta conectada.
|
|
73
|
-
* @returns {Promise<
|
|
227
|
+
* @returns {Promise<string[]>}
|
|
74
228
|
*/
|
|
75
229
|
export const fetchBlocklistFromActiveSocket = async () => runActiveSocketMethod('fetchBlocklist');
|
|
76
230
|
|
|
@@ -127,7 +281,8 @@ const decodeJidParts = (() => {
|
|
|
127
281
|
|
|
128
282
|
/**
|
|
129
283
|
* Tipos de mensagem conhecidos do Baileys
|
|
130
|
-
*
|
|
284
|
+
* (mapeamento de chaves do proto.Message para tipos normalizados).
|
|
285
|
+
* @type {Record<string, string>}
|
|
131
286
|
*/
|
|
132
287
|
export const MEDIA_TYPE_MAPPING = {
|
|
133
288
|
conversation: 'text',
|
|
@@ -181,7 +336,8 @@ export const MEDIA_TYPE_MAPPING = {
|
|
|
181
336
|
};
|
|
182
337
|
|
|
183
338
|
/**
|
|
184
|
-
* Tipos de
|
|
339
|
+
* Tipos de mídia que carregam conteúdo binário/arquivo.
|
|
340
|
+
* @type {Set<string>}
|
|
185
341
|
*/
|
|
186
342
|
export const BINARY_MEDIA_TYPES = new Set(['image', 'video', 'videoNote', 'audio', 'voice', 'document', 'sticker']);
|
|
187
343
|
|
|
@@ -520,13 +676,22 @@ export function isWhatsAppJid(jid) {
|
|
|
520
676
|
return Boolean(server && WHATSAPP_USER_JID_SERVERS.has(server));
|
|
521
677
|
}
|
|
522
678
|
|
|
679
|
+
/**
|
|
680
|
+
* Modo de endereçamento por LID.
|
|
681
|
+
* @type {'lid'}
|
|
682
|
+
*/
|
|
523
683
|
export const ADDRESSING_MODE_LID = 'lid';
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Modo de endereçamento por PN/JID canônico.
|
|
687
|
+
* @type {'pn'}
|
|
688
|
+
*/
|
|
524
689
|
export const ADDRESSING_MODE_PN = 'pn';
|
|
525
690
|
|
|
526
691
|
/**
|
|
527
692
|
* Normaliza um modo de endereçamento (lid/pn).
|
|
528
693
|
* @param {unknown} value
|
|
529
|
-
* @returns {
|
|
694
|
+
* @returns {AddressingMode|undefined}
|
|
530
695
|
*/
|
|
531
696
|
export const normalizeAddressingMode = (value) => {
|
|
532
697
|
if (value === undefined || value === null) return undefined;
|
|
@@ -539,8 +704,8 @@ export const normalizeAddressingMode = (value) => {
|
|
|
539
704
|
/**
|
|
540
705
|
* Resolve modo de endereçamento a partir da chave da mensagem.
|
|
541
706
|
* @param {object} [key={}]
|
|
542
|
-
* @param {
|
|
543
|
-
* @returns {
|
|
707
|
+
* @param {SenderInfo|Record<string, any>} [senderInfo={}]
|
|
708
|
+
* @returns {AddressingMode|undefined}
|
|
544
709
|
*/
|
|
545
710
|
export const resolveAddressingModeFromMessageKey = (key = {}, senderInfo = {}) => {
|
|
546
711
|
const explicit = normalizeAddressingMode(key?.addressingMode);
|
|
@@ -559,7 +724,7 @@ export const resolveAddressingModeFromMessageKey = (key = {}, senderInfo = {}) =
|
|
|
559
724
|
|
|
560
725
|
/**
|
|
561
726
|
* Resolve JID canônico de usuário WhatsApp a partir de candidatos.
|
|
562
|
-
* @param {...string} candidates
|
|
727
|
+
* @param {...(string|null|undefined)} candidates
|
|
563
728
|
* @returns {string}
|
|
564
729
|
*/
|
|
565
730
|
export const resolveCanonicalWhatsAppJid = (...candidates) => {
|
|
@@ -715,7 +880,7 @@ export async function resolveBaileysVersion() {
|
|
|
715
880
|
|
|
716
881
|
/**
|
|
717
882
|
* Baixa a foto de perfil associada à mensagem recebida.
|
|
718
|
-
* @param {
|
|
883
|
+
* @param {BaileysSocket} sock - Instância conectada do socket.
|
|
719
884
|
* @param {import('@whiskeysockets/baileys').proto.IWebMessageInfo} msg - Mensagem usada para resolver o JID.
|
|
720
885
|
* @returns {Promise<Buffer|null>} Buffer da imagem ou `null` se indisponível.
|
|
721
886
|
*/
|
|
@@ -739,17 +904,17 @@ export async function getProfilePicBuffer(sock, msg) {
|
|
|
739
904
|
|
|
740
905
|
/**
|
|
741
906
|
* Extrai o valor de expiração de uma mensagem do WhatsApp, ou retorna 24 horas (em segundos) por padrão.
|
|
742
|
-
* @param {{message?:
|
|
907
|
+
* @param {{message?: Record<string, any>}|null|undefined} messageInfo - Estrutura contendo a propriedade `message`.
|
|
743
908
|
* @returns {number} Tempo de expiração em segundos.
|
|
744
909
|
*/
|
|
745
|
-
export function getExpiration(
|
|
910
|
+
export function getExpiration(messageInfo) {
|
|
746
911
|
const DEFAULT_EXPIRATION_SECONDS = 24 * 60 * 60;
|
|
747
912
|
|
|
748
|
-
if (!
|
|
913
|
+
if (!messageInfo || typeof messageInfo !== 'object' || !messageInfo.message) {
|
|
749
914
|
return DEFAULT_EXPIRATION_SECONDS;
|
|
750
915
|
}
|
|
751
916
|
|
|
752
|
-
const normalizedMessage = normalizeMessage(
|
|
917
|
+
const normalizedMessage = normalizeMessage(messageInfo.message);
|
|
753
918
|
const expiration = findExpiration(normalizedMessage);
|
|
754
919
|
|
|
755
920
|
return typeof expiration === 'number' ? expiration : DEFAULT_EXPIRATION_SECONDS;
|
|
@@ -757,7 +922,7 @@ export function getExpiration(sock) {
|
|
|
757
922
|
|
|
758
923
|
/**
|
|
759
924
|
* Extrai o conteúdo de texto de uma mensagem do WhatsApp.
|
|
760
|
-
* @param {{message?:
|
|
925
|
+
* @param {{message?: Record<string, any>}} messageInfo - Objeto que contém o payload da mensagem.
|
|
761
926
|
* @returns {string} Conteúdo textual extraído ou descrição do tipo de mensagem.
|
|
762
927
|
*/
|
|
763
928
|
export const extractMessageContent = ({ message }) => {
|
|
@@ -809,7 +974,7 @@ export const extractMessageContent = ({ message }) => {
|
|
|
809
974
|
|
|
810
975
|
/**
|
|
811
976
|
* Faz o download de mídia a partir de uma mensagem do Baileys.
|
|
812
|
-
* @param {
|
|
977
|
+
* @param {BaileysProtoMessage} message - Objeto da mídia a ser baixada.
|
|
813
978
|
* @param {string} type - Tipo de mídia (ex.: `image`, `video`, `audio`, `document`).
|
|
814
979
|
* @param {string} outputPath - Diretório onde o arquivo será salvo.
|
|
815
980
|
* @returns {Promise<string|null>} Caminho do arquivo salvo ou `null` em caso de falha.
|
|
@@ -837,9 +1002,9 @@ export const downloadMediaMessage = async (message, type, outputPath) => {
|
|
|
837
1002
|
try {
|
|
838
1003
|
const stream = await downloadContentFromMessage(message, type);
|
|
839
1004
|
|
|
840
|
-
const fileId = message.key?.id ||
|
|
1005
|
+
const fileId = message.key?.id || __timeNowMs();
|
|
841
1006
|
const extension = getMediaExtension(type);
|
|
842
|
-
const fileName = `${
|
|
1007
|
+
const fileName = `${__timeNowMs()}-${fileId}.${extension}`;
|
|
843
1008
|
const filePath = path.join(outputPath, fileName);
|
|
844
1009
|
|
|
845
1010
|
await pipeline(Readable.from(stream), createWriteStream(filePath));
|
|
@@ -866,10 +1031,10 @@ export const downloadMediaMessage = async (message, type, outputPath) => {
|
|
|
866
1031
|
};
|
|
867
1032
|
|
|
868
1033
|
/**
|
|
869
|
-
* Detecta dinamicamente
|
|
870
|
-
* @param {
|
|
871
|
-
* @param {boolean} isQuoted
|
|
872
|
-
* @returns {
|
|
1034
|
+
* Detecta dinamicamente os tipos de mídia presentes em um payload de mensagem.
|
|
1035
|
+
* @param {Record<string, any>} messageContent Conteúdo da mensagem (normal ou quoted).
|
|
1036
|
+
* @param {boolean} [isQuoted=false] Sinaliza se o payload veio de uma citação.
|
|
1037
|
+
* @returns {MediaEntry[]} Lista de mídias detectadas (pode estar vazia).
|
|
873
1038
|
*/
|
|
874
1039
|
export function detectAllMediaTypes(messageContent, isQuoted = false) {
|
|
875
1040
|
if (!messageContent || typeof messageContent !== 'object') {
|
|
@@ -913,13 +1078,10 @@ export function detectAllMediaTypes(messageContent, isQuoted = false) {
|
|
|
913
1078
|
}
|
|
914
1079
|
|
|
915
1080
|
/**
|
|
916
|
-
* Extrai
|
|
917
|
-
* @param {
|
|
918
|
-
* @param {
|
|
919
|
-
* @
|
|
920
|
-
* @param {boolean} options.includeQuoted - Se deve incluir midia de mensagens citadas
|
|
921
|
-
* @param {boolean} options.includeUnknown - Se deve incluir tipos desconhecidos
|
|
922
|
-
* @returns {{mediaType: string, mediaKey: object, details: object}|null} - Detalhes da midia ou null se nao encontrada
|
|
1081
|
+
* Extrai a mídia primária de uma mensagem com filtros configuráveis.
|
|
1082
|
+
* @param {BaileysMessage|{message?: Record<string, any>}|Record<string, any>} message Objeto da mensagem.
|
|
1083
|
+
* @param {MediaExtractionOptions} [options={}] Opções de filtragem.
|
|
1084
|
+
* @returns {MediaExtractionResult|null} Estrutura da mídia primária ou `null` quando não houver mídia.
|
|
923
1085
|
*/
|
|
924
1086
|
export function extractMediaDetails(message, options = {}) {
|
|
925
1087
|
const { includeAllTypes = false, includeQuoted = true, includeUnknown = false } = options;
|
|
@@ -954,10 +1116,10 @@ export function extractMediaDetails(message, options = {}) {
|
|
|
954
1116
|
}
|
|
955
1117
|
|
|
956
1118
|
/**
|
|
957
|
-
* Extrai
|
|
958
|
-
* @param {
|
|
959
|
-
* @param {
|
|
960
|
-
* @returns {
|
|
1119
|
+
* Extrai todas as mídias detectadas de uma mensagem.
|
|
1120
|
+
* @param {BaileysMessage|{message?: Record<string, any>}|Record<string, any>} message Objeto da mensagem.
|
|
1121
|
+
* @param {MediaExtractionOptions} [options={}] Opções de filtragem.
|
|
1122
|
+
* @returns {MediaEntry[]} Array com todas as mídias encontradas.
|
|
961
1123
|
*/
|
|
962
1124
|
export function extractAllMediaDetails(message, options = {}) {
|
|
963
1125
|
const { includeAllTypes = true, includeQuoted = true, includeUnknown = true } = options;
|
|
@@ -967,10 +1129,10 @@ export function extractAllMediaDetails(message, options = {}) {
|
|
|
967
1129
|
}
|
|
968
1130
|
|
|
969
1131
|
/**
|
|
970
|
-
* Verifica se uma mensagem
|
|
971
|
-
* @param {
|
|
972
|
-
* @param {string} specificType
|
|
973
|
-
* @returns {boolean}
|
|
1132
|
+
* Verifica se uma mensagem contém mídia.
|
|
1133
|
+
* @param {BaileysMessage|{message?: Record<string, any>}|Record<string, any>} message Objeto da mensagem.
|
|
1134
|
+
* @param {string|null} [specificType=null] Tipo específico para filtrar (ex.: `image`).
|
|
1135
|
+
* @returns {boolean} `true` quando ao menos uma mídia compatível é encontrada.
|
|
974
1136
|
*/
|
|
975
1137
|
export function hasMedia(message, specificType = null) {
|
|
976
1138
|
const allMedia = collectMediaFromMessage(message, { includeQuoted: true });
|
|
@@ -988,8 +1150,13 @@ export function hasMedia(message, specificType = null) {
|
|
|
988
1150
|
}
|
|
989
1151
|
|
|
990
1152
|
/**
|
|
991
|
-
*
|
|
992
|
-
* @returns {
|
|
1153
|
+
* Obtém metadados dos tipos de mídia suportados.
|
|
1154
|
+
* @returns {{
|
|
1155
|
+
* knownTypes: string[],
|
|
1156
|
+
* binaryTypes: string[],
|
|
1157
|
+
* typeMapping: Record<string, string>,
|
|
1158
|
+
* totalKnownTypes: number
|
|
1159
|
+
* }}
|
|
993
1160
|
*/
|
|
994
1161
|
export function getMediaTypeInfo() {
|
|
995
1162
|
return {
|
|
@@ -1001,9 +1168,9 @@ export function getMediaTypeInfo() {
|
|
|
1001
1168
|
}
|
|
1002
1169
|
|
|
1003
1170
|
/**
|
|
1004
|
-
*
|
|
1171
|
+
* ===========================
|
|
1005
1172
|
* LID Map Utilities
|
|
1006
|
-
*
|
|
1173
|
+
* ===========================
|
|
1007
1174
|
*/
|
|
1008
1175
|
const CACHE_TTL_MS = 20 * 60 * 1000;
|
|
1009
1176
|
const NEGATIVE_TTL_MS = 5 * 60 * 1000;
|
|
@@ -1014,10 +1181,7 @@ const BACKFILL_SOURCE = 'backfill';
|
|
|
1014
1181
|
const __filename = fileURLToPath(import.meta.url);
|
|
1015
1182
|
const __dirname = path.dirname(__filename);
|
|
1016
1183
|
const BAILEYS_AUTH_DIR = path.resolve(__dirname, '../connection/auth');
|
|
1017
|
-
const BAILEYS_AUTH_SESSION_ID =
|
|
1018
|
-
const raw = String(process.env.BAILEYS_AUTH_SESSION_ID || '').trim();
|
|
1019
|
-
return raw || 'default';
|
|
1020
|
-
})();
|
|
1184
|
+
const BAILEYS_AUTH_SESSION_ID = PRIMARY_BAILEYS_SESSION_ID;
|
|
1021
1185
|
|
|
1022
1186
|
const lidCache = new Map();
|
|
1023
1187
|
const lidWriteBuffer = new Map();
|
|
@@ -1033,7 +1197,7 @@ const updateLidQueueMetric = () => {
|
|
|
1033
1197
|
* Retorna timestamp atual em ms.
|
|
1034
1198
|
* @returns {number}
|
|
1035
1199
|
*/
|
|
1036
|
-
const now = () =>
|
|
1200
|
+
const now = () => __timeNowMs();
|
|
1037
1201
|
|
|
1038
1202
|
const normalizeLid = (lid) => {
|
|
1039
1203
|
if (!lid || !isLidJid(lid)) return null;
|
|
@@ -1131,7 +1295,7 @@ const maskJid = (jid) => {
|
|
|
1131
1295
|
/**
|
|
1132
1296
|
* Busca entrada do cache (com expiração).
|
|
1133
1297
|
* @param {string|null|undefined} lid
|
|
1134
|
-
* @returns {
|
|
1298
|
+
* @returns {LidCacheEntry|null}
|
|
1135
1299
|
*/
|
|
1136
1300
|
const getCacheEntry = (lid) => {
|
|
1137
1301
|
if (!lid) return null;
|
|
@@ -1193,9 +1357,10 @@ export const getCachedJidForLid = (lid) => {
|
|
|
1193
1357
|
|
|
1194
1358
|
/**
|
|
1195
1359
|
* Divide lista em batches.
|
|
1196
|
-
* @
|
|
1360
|
+
* @template T
|
|
1361
|
+
* @param {T[]} items
|
|
1197
1362
|
* @param {number} [limit=BATCH_LIMIT]
|
|
1198
|
-
* @returns {
|
|
1363
|
+
* @returns {T[][]}
|
|
1199
1364
|
*/
|
|
1200
1365
|
const buildChunks = (items, limit = BATCH_LIMIT) => {
|
|
1201
1366
|
const chunks = [];
|
|
@@ -1325,7 +1490,7 @@ const buildServerLikeFilter = (column, servers) => {
|
|
|
1325
1490
|
/**
|
|
1326
1491
|
* Resolve candidatos principais de identidade de usuário.
|
|
1327
1492
|
* Centraliza regra usada por `resolveUserIdCached` e `resolveUserId`.
|
|
1328
|
-
* @param {
|
|
1493
|
+
* @param {IdentityParams} [params]
|
|
1329
1494
|
* @returns {{directJid: string|null, lidValue: string|null, fallback: string|null}}
|
|
1330
1495
|
*/
|
|
1331
1496
|
const resolveIdentityCandidates = ({ lid, jid, participantAlt } = {}) => {
|
|
@@ -1430,7 +1595,7 @@ export const queueLidUpdate = (lid, jid, source = 'message') => {
|
|
|
1430
1595
|
|
|
1431
1596
|
/**
|
|
1432
1597
|
* Resolve ID canônico usando apenas cache.
|
|
1433
|
-
* @param {
|
|
1598
|
+
* @param {IdentityParams} [params]
|
|
1434
1599
|
* @returns {string|null}
|
|
1435
1600
|
*/
|
|
1436
1601
|
export const resolveUserIdCached = ({ lid, jid, participantAlt } = {}) => {
|
|
@@ -1444,9 +1609,9 @@ export const resolveUserIdCached = ({ lid, jid, participantAlt } = {}) => {
|
|
|
1444
1609
|
};
|
|
1445
1610
|
|
|
1446
1611
|
/**
|
|
1447
|
-
* Extrai
|
|
1448
|
-
* @param {
|
|
1449
|
-
* @returns {
|
|
1612
|
+
* Extrai informações de identidade do remetente a partir da mensagem.
|
|
1613
|
+
* @param {BaileysMessage} msg
|
|
1614
|
+
* @returns {SenderInfo}
|
|
1450
1615
|
*/
|
|
1451
1616
|
export const extractSenderInfoFromMessage = (msg) => {
|
|
1452
1617
|
const remoteJid = normalizeJid(msg?.key?.remoteJid || '') || null;
|
|
@@ -1555,7 +1720,7 @@ const fetchJidByLid = async (lid) => {
|
|
|
1555
1720
|
|
|
1556
1721
|
/**
|
|
1557
1722
|
* Resolve ID canônico consultando banco se necessário.
|
|
1558
|
-
* @param {
|
|
1723
|
+
* @param {IdentityParams} [params]
|
|
1559
1724
|
* @returns {Promise<string|null>}
|
|
1560
1725
|
*/
|
|
1561
1726
|
export const resolveUserId = async ({ lid, jid, participantAlt } = {}) => {
|
|
@@ -1668,6 +1833,13 @@ export const flushLidQueue = async () => {
|
|
|
1668
1833
|
await lidFlushRunner.run();
|
|
1669
1834
|
};
|
|
1670
1835
|
|
|
1836
|
+
/**
|
|
1837
|
+
* Enfileira atualização de mapa LID/JID e retorna estado simplificado.
|
|
1838
|
+
* @param {string} lid
|
|
1839
|
+
* @param {string|null} jid
|
|
1840
|
+
* @param {string} [source='message']
|
|
1841
|
+
* @returns {Promise<{stored: boolean, reconciled: boolean}>}
|
|
1842
|
+
*/
|
|
1671
1843
|
export const maybeStoreLidMap = async (lid, jid, source = 'message') => {
|
|
1672
1844
|
const result = queueLidUpdate(lid, jid, source);
|
|
1673
1845
|
return { stored: result.queued, reconciled: result.reconciled };
|
|
@@ -288,6 +288,7 @@ export async function getGroupInfoAsync(groupId) {
|
|
|
288
288
|
const participants = parseParticipantsFromDb(data.participants || data.participants_json || null);
|
|
289
289
|
const creation = _normalizeNumberOrNull(data.creation);
|
|
290
290
|
const ephemeralDuration = _normalizeNumberOrNull(data.ephemeral_duration ?? data.ephemeralDuration);
|
|
291
|
+
const linkedParent = _normalizeGroupId(data.linked_parent_jid || data.linkedParent) || null;
|
|
291
292
|
|
|
292
293
|
const group = {
|
|
293
294
|
id: _normalizeGroupId(data.id) || normalizedGroupId,
|
|
@@ -299,6 +300,10 @@ export async function getGroupInfoAsync(groupId) {
|
|
|
299
300
|
restrict: Boolean(data.restrict),
|
|
300
301
|
announce: Boolean(data.announce),
|
|
301
302
|
isCommunity: Boolean(data.is_community ?? data.isCommunity),
|
|
303
|
+
isCommunityAnnounce: Boolean(data.is_community_announce ?? data.isCommunityAnnounce),
|
|
304
|
+
linkedParent,
|
|
305
|
+
memberAddMode: data.member_add_mode === null || data.member_add_mode === undefined ? null : Boolean(data.member_add_mode),
|
|
306
|
+
joinApprovalMode: data.join_approval_mode === null || data.join_approval_mode === undefined ? null : Boolean(data.join_approval_mode),
|
|
302
307
|
addressingMode: data.addressing_mode || data.addressingMode || null,
|
|
303
308
|
ephemeralDuration,
|
|
304
309
|
};
|