@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
|
@@ -7,7 +7,7 @@ Este arquivo e destinado a agentes de IA para gerar respostas no contexto dos co
|
|
|
7
7
|
- arquivo_base: `app/modules/aiModule/commandConfig.json`
|
|
8
8
|
- schema_version: `2.0.0`
|
|
9
9
|
- module_enabled: `true`
|
|
10
|
-
- generated_at: `2026-03-
|
|
10
|
+
- generated_at: `2026-03-17T04:04:14.195Z`
|
|
11
11
|
|
|
12
12
|
## Escopo do Modulo
|
|
13
13
|
|
|
@@ -77,7 +77,7 @@ Este arquivo e destinado a agentes de IA para gerar respostas no contexto dos co
|
|
|
77
77
|
- enabled: true
|
|
78
78
|
- categoria: ia
|
|
79
79
|
- descricao: Perguntas para IA com suporte opcional a resposta em audio.
|
|
80
|
-
- permissao_necessaria: usuario
|
|
80
|
+
- permissao_necessaria: usuario premium
|
|
81
81
|
- version: 1.0.0
|
|
82
82
|
- stability: stable
|
|
83
83
|
- deprecated: nao
|
|
@@ -116,8 +116,8 @@ Este arquivo e destinado a agentes de IA para gerar respostas no contexto dos co
|
|
|
116
116
|
- janela_ms: null
|
|
117
117
|
- escopo: sem_rate_limit_explicito
|
|
118
118
|
- acesso:
|
|
119
|
-
- somente_premium:
|
|
120
|
-
- planos_permitidos:
|
|
119
|
+
- somente_premium: sim
|
|
120
|
+
- planos_permitidos: premium
|
|
121
121
|
- limite_uso_por_plano:
|
|
122
122
|
- comum: max=8, janela_ms=300000, escopo=usuario
|
|
123
123
|
- premium: max=40, janela_ms=300000, escopo=usuario
|
|
@@ -142,22 +142,29 @@ Este arquivo e destinado a agentes de IA para gerar respostas no contexto dos co
|
|
|
142
142
|
- erro_uso: Formato de uso inválido. Consulte metodos_de_uso.
|
|
143
143
|
- erro_permissao: Permissão insuficiente para executar este comando.
|
|
144
144
|
- mensagens_sistema:
|
|
145
|
-
- premium*only: ⭐ \
|
|
145
|
+
- premium*only: ⭐ \_Recurso Premium*
|
|
146
146
|
|
|
147
|
-
Este comando é exclusivo para usuários
|
|
148
|
-
|
|
147
|
+
Este comando é exclusivo para usuários Premium.
|
|
148
|
+
Para liberar o acesso, fale com o admin do sistema no privado.
|
|
149
|
+
|
|
150
|
+
- openai*nao_configurada: ⚠️ \_IA indisponível no momento*
|
|
151
|
+
|
|
152
|
+
Este recurso está em manutenção.
|
|
153
|
+
Se precisar de ajuda, fale com o admin do sistema no privado.
|
|
149
154
|
|
|
150
|
-
-
|
|
155
|
+
- imagem_muito_grande: ⚠️ A imagem está muito grande para análise (limite {{limite_mb}} MB). Envie uma imagem menor.
|
|
156
|
+
- imagem_download_falhou: ⚠️ Não consegui ler sua imagem agora. Reenvie a imagem.
|
|
157
|
+
Se o erro continuar, fale com o admin do sistema no privado.
|
|
158
|
+
- resposta_vazia: ⚠️ Não consegui montar uma resposta agora. Tente novamente em instantes.
|
|
159
|
+
- audio_muito_longo: ⚠️ A resposta ficou grande para áudio. Vou te enviar em texto.
|
|
160
|
+
- audio_falhou: ⚠️ Não consegui gerar o áudio agora. Vou te responder em texto.
|
|
161
|
+
- erro*openai: ❌ \_Não consegui responder agora*
|
|
151
162
|
|
|
152
|
-
|
|
163
|
+
Tente novamente em instantes.
|
|
164
|
+
Se o erro continuar, fale com o admin do sistema no privado.
|
|
153
165
|
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
- resposta_vazia: ⚠️ Não consegui gerar uma resposta agora. Tente novamente.
|
|
157
|
-
- audio_muito_longo: ⚠️ A resposta ficou longa demais para áudio. Enviando em texto.
|
|
158
|
-
- audio_falhou: ⚠️ Não consegui gerar o áudio agora. Enviando texto.
|
|
159
|
-
- erro*openai: ❌ \_Erro ao falar com a IA*
|
|
160
|
-
Tente novamente em alguns instantes.
|
|
166
|
+
- usage*header: 🤖 \_Comando CAT*
|
|
167
|
+
- resposta_prefixo_texto: 🐈⬛
|
|
161
168
|
- limites_operacionais:
|
|
162
169
|
- (nao informado)
|
|
163
170
|
- opcoes:
|
|
@@ -209,8 +216,8 @@ Defina a variável _OPENAI_API_KEY_ no `.env` para usar o comando _cat_.
|
|
|
209
216
|
- rate_limit.max: null
|
|
210
217
|
- rate_limit.janela_ms: null
|
|
211
218
|
- rate_limit.escopo: sem_rate_limit_explicito
|
|
212
|
-
- access.somente_premium:
|
|
213
|
-
- access.planos_permitidos:
|
|
219
|
+
- access.somente_premium: true
|
|
220
|
+
- access.planos_permitidos: premium
|
|
214
221
|
- plan_limits.comum.max: 8
|
|
215
222
|
- plan_limits.comum.janela_ms: 300000
|
|
216
223
|
- plan_limits.comum.escopo: usuario
|
|
@@ -234,7 +241,7 @@ Defina a variável _OPENAI_API_KEY_ no `.env` para usar o comando _cat_.
|
|
|
234
241
|
- enabled: true
|
|
235
242
|
- categoria: ia
|
|
236
243
|
- descricao: Gera/edita imagem com IA por prompt.
|
|
237
|
-
- permissao_necessaria: usuario
|
|
244
|
+
- permissao_necessaria: usuario premium
|
|
238
245
|
- version: 1.0.0
|
|
239
246
|
- stability: stable
|
|
240
247
|
- deprecated: nao
|
|
@@ -302,25 +309,33 @@ Defina a variável _OPENAI_API_KEY_ no `.env` para usar o comando _cat_.
|
|
|
302
309
|
- erro_uso: Formato de uso inválido. Consulte metodos_de_uso.
|
|
303
310
|
- erro_permissao: Permissão insuficiente para executar este comando.
|
|
304
311
|
- mensagens_sistema:
|
|
305
|
-
- premium*only: ⭐ \
|
|
312
|
+
- premium*only: ⭐ \_Recurso Premium*
|
|
306
313
|
|
|
307
|
-
Este comando é exclusivo para usuários
|
|
308
|
-
|
|
314
|
+
Este comando é exclusivo para usuários Premium.
|
|
315
|
+
Para liberar o acesso, fale com o admin do sistema no privado.
|
|
309
316
|
|
|
310
|
-
- openai*nao_configurada: ⚠️ \
|
|
317
|
+
- openai*nao_configurada: ⚠️ \_Gerador de imagem indisponível*
|
|
311
318
|
|
|
312
|
-
|
|
319
|
+
Este recurso está em manutenção.
|
|
320
|
+
Se precisar de ajuda, fale com o admin do sistema no privado.
|
|
313
321
|
|
|
314
|
-
- imagem_muito_grande: ⚠️ A imagem
|
|
315
|
-
- imagem_download_falhou: ⚠️ Não consegui
|
|
316
|
-
|
|
322
|
+
- imagem_muito_grande: ⚠️ A imagem está muito grande para edição (limite {{limite_mb}} MB). Envie uma imagem menor.
|
|
323
|
+
- imagem_download_falhou: ⚠️ Não consegui ler sua imagem agora. Reenvie a imagem.
|
|
324
|
+
Se o erro continuar, fale com o admin do sistema no privado.
|
|
325
|
+
- opcoes_invalidas: ⚠️ Algumas opções do comando estão inválidas.
|
|
317
326
|
Detalhes: {{detalhes}}
|
|
318
327
|
|
|
319
328
|
Use _{{prefix}}catimg_ sem opções para ver o formato correto.
|
|
320
329
|
|
|
321
|
-
- resposta_vazia: ⚠️ Não consegui gerar a imagem agora. Tente novamente.
|
|
322
|
-
- erro*openai: ❌ \
|
|
323
|
-
|
|
330
|
+
- resposta_vazia: ⚠️ Não consegui gerar a imagem agora. Tente novamente em instantes.
|
|
331
|
+
- erro*openai: ❌ \_Não consegui gerar sua imagem agora*
|
|
332
|
+
|
|
333
|
+
Tente novamente em instantes.
|
|
334
|
+
Se o erro continuar, fale com o admin do sistema no privado.
|
|
335
|
+
|
|
336
|
+
- usage*header: 🖼️ \_Imagem IA*
|
|
337
|
+
- resposta_prefixo_texto_imagem: 🖼️
|
|
338
|
+
- imagem_caption_sucesso: 🖼️ Imagem gerada.
|
|
324
339
|
- limites_operacionais:
|
|
325
340
|
- (nao informado)
|
|
326
341
|
- opcoes:
|
|
@@ -489,6 +504,7 @@ Fale com o administrador para liberar o acesso.
|
|
|
489
504
|
- prompt_muito_longo: ⚠️ Prompt muito longo. Limite: {{max_chars}} caracteres.
|
|
490
505
|
- prompt_reset_sucesso: ✅ Prompt da IA restaurado para o padrão.
|
|
491
506
|
- prompt_update_sucesso: ✅ Prompt da IA atualizado para você.
|
|
507
|
+
- usage*header: 🧠 \_Prompt da IA*
|
|
492
508
|
- limites_operacionais:
|
|
493
509
|
- prompt_max_chars: 2000
|
|
494
510
|
- opcoes:
|
|
@@ -505,6 +521,7 @@ Fale com o administrador para liberar o acesso.
|
|
|
505
521
|
- set_status_reset.type: configuration_window
|
|
506
522
|
- set_status_reset.allowed_actions: set, status, reset
|
|
507
523
|
- set_status_reset.action_argument: valor
|
|
524
|
+
- parse.reset_aliases: reset, default, padrao, padrão
|
|
508
525
|
- observabilidade:
|
|
509
526
|
- event_name: command.executed
|
|
510
527
|
- analytics_event: whatsapp_command_catprompt
|
|
@@ -114,6 +114,7 @@ export const getAiCommandOptionConfig = (command) => {
|
|
|
114
114
|
parse: {
|
|
115
115
|
audio_flags: Array.isArray(parse.audio_flags) ? parse.audio_flags.map((item) => String(item || '')).filter(Boolean) : [],
|
|
116
116
|
text_flags: Array.isArray(parse.text_flags) ? parse.text_flags.map((item) => String(item || '')).filter(Boolean) : [],
|
|
117
|
+
reset_aliases: Array.isArray(parse.reset_aliases) ? parse.reset_aliases.map((item) => String(item || '')).filter(Boolean) : [],
|
|
117
118
|
image_detail_aliases: normalizeMapKeys(parse.image_detail_aliases || {}),
|
|
118
119
|
},
|
|
119
120
|
geracao_imagem: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { now as __timeNow, nowIso as __timeNowIso, toUnixMs as __timeNowMs } from '#time';
|
|
1
2
|
import OpenAI from 'openai';
|
|
2
3
|
import NodeCache from 'node-cache';
|
|
3
4
|
import fs from 'node:fs/promises';
|
|
@@ -34,14 +35,18 @@ const DEFAULT_COMMAND_PREFIX = process.env.COMMAND_PREFIX || '/';
|
|
|
34
35
|
const OWNER_JID = getAdminJid();
|
|
35
36
|
|
|
36
37
|
const SESSION_TTL_SECONDS = Number.parseInt(process.env.OPENAI_SESSION_TTL_SECONDS || '21600', 10);
|
|
38
|
+
const ADMIN_ALERT_DEDUPE_WINDOW_MS_RAW = Number.parseInt(process.env.AI_ADMIN_ALERT_DEDUPE_WINDOW_MS || '120000', 10);
|
|
37
39
|
const sessionCache = new NodeCache({
|
|
38
40
|
stdTTL: SESSION_TTL_SECONDS,
|
|
39
41
|
checkperiod: Math.max(60, Math.floor(SESSION_TTL_SECONDS / 4)),
|
|
40
42
|
});
|
|
43
|
+
const ADMIN_ALERT_DEDUPE_WINDOW_MS = Number.isFinite(ADMIN_ALERT_DEDUPE_WINDOW_MS_RAW) && ADMIN_ALERT_DEDUPE_WINDOW_MS_RAW > 0 ? ADMIN_ALERT_DEDUPE_WINDOW_MS_RAW : 120000;
|
|
44
|
+
const adminAlertDedupCache = new Map();
|
|
41
45
|
let cachedClient = null;
|
|
42
46
|
|
|
43
47
|
const AUDIO_FLAG_ALIASES = new Set(['--audio', '--voz', '--voice', '--tts', '-a']);
|
|
44
48
|
const TEXT_FLAG_ALIASES = new Set(['--texto', '--text', '--txt']);
|
|
49
|
+
const CATPROMPT_RESET_ALIASES = new Set(['reset', 'default', 'padrao', 'padrão']);
|
|
45
50
|
const IMAGE_DETAIL_ALIASES = new Map([
|
|
46
51
|
['low', 'low'],
|
|
47
52
|
['high', 'high'],
|
|
@@ -151,6 +156,10 @@ const resolveAiMessages = (commandName) => {
|
|
|
151
156
|
const mergeMessage = (key, fallback) => String(commandMessages?.[key] || '').trim() || String(fallback || '').trim();
|
|
152
157
|
|
|
153
158
|
return {
|
|
159
|
+
usageHeader: mergeMessage('usage_header', '🤖 *Comando*'),
|
|
160
|
+
textResponsePrefix: mergeMessage('resposta_prefixo_texto', ''),
|
|
161
|
+
imageTextResponsePrefix: mergeMessage('resposta_prefixo_texto_imagem', '🖼️ '),
|
|
162
|
+
imageSuccessCaption: mergeMessage('imagem_caption_sucesso', '🖼️ Imagem gerada.'),
|
|
154
163
|
premiumOnly: mergeMessage('premium_only', ['⭐ *Comando Premium*', '', 'Este comando é exclusivo para usuários premium.', 'Fale com o administrador para liberar o acesso.'].join('\n')),
|
|
155
164
|
openAiNotConfigured: mergeMessage('openai_nao_configurada', ['⚠️ *OpenAI não configurada*', '', `Defina a variável *OPENAI_API_KEY* no \`.env\` para usar o comando *${commandName}*.`].join('\n')),
|
|
156
165
|
imageTooLarge: mergeMessage('imagem_muito_grande', '⚠️ A imagem enviada ultrapassa o limite de {{limite_mb}} MB. Envie uma imagem menor.'),
|
|
@@ -231,6 +240,11 @@ const resolveCatPromptMaxChars = () => {
|
|
|
231
240
|
return value;
|
|
232
241
|
};
|
|
233
242
|
|
|
243
|
+
const resolveCatPromptResetAliases = () => {
|
|
244
|
+
const config = getAiCommandOptionConfig('catprompt');
|
|
245
|
+
return toSet(config?.parse?.reset_aliases, [...CATPROMPT_RESET_ALIASES]);
|
|
246
|
+
};
|
|
247
|
+
|
|
234
248
|
const getClient = () => {
|
|
235
249
|
if (cachedClient) return cachedClient;
|
|
236
250
|
cachedClient = new OpenAI({
|
|
@@ -309,12 +323,13 @@ const callOpenAI = async (operationFactory, label, timeoutMs) => {
|
|
|
309
323
|
};
|
|
310
324
|
|
|
311
325
|
const sendUsage = async (sock, remoteJid, messageInfo, expirationMessage, commandPrefix = DEFAULT_COMMAND_PREFIX) => {
|
|
326
|
+
const commandMessages = resolveAiMessages('cat');
|
|
312
327
|
const usageText =
|
|
313
328
|
getAiUsageText('cat', {
|
|
314
329
|
commandPrefix,
|
|
315
|
-
header:
|
|
330
|
+
header: commandMessages.usageHeader,
|
|
316
331
|
variant: 'default',
|
|
317
|
-
}) ||
|
|
332
|
+
}) || `${commandMessages.usageHeader}\n*${commandPrefix}cat*`;
|
|
318
333
|
|
|
319
334
|
await sendAndStore(sock, remoteJid, { text: usageText }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
320
335
|
};
|
|
@@ -363,24 +378,75 @@ const sendPremiumOnly = async (sock, remoteJid, messageInfo, expirationMessage,
|
|
|
363
378
|
await sendAndStore(sock, remoteJid, { text: messages.premiumOnly }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
364
379
|
};
|
|
365
380
|
|
|
381
|
+
const shouldSendAdminAlert = ({ commandName = '', stage = '', remoteJid = '', senderJid = '', errorMessage = '' } = {}) => {
|
|
382
|
+
const dedupeKey = `${normalizeText(commandName)}|${normalizeText(stage)}|${normalizeText(remoteJid)}|${normalizeText(senderJid)}|${normalizeText(errorMessage)}`;
|
|
383
|
+
const nowMs = __timeNowMs();
|
|
384
|
+
const lastSentAt = adminAlertDedupCache.get(dedupeKey);
|
|
385
|
+
if (Number.isFinite(lastSentAt) && nowMs - lastSentAt < ADMIN_ALERT_DEDUPE_WINDOW_MS) {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
adminAlertDedupCache.set(dedupeKey, nowMs);
|
|
390
|
+
for (const [key, ts] of adminAlertDedupCache.entries()) {
|
|
391
|
+
if (!Number.isFinite(ts) || nowMs - ts > ADMIN_ALERT_DEDUPE_WINDOW_MS) {
|
|
392
|
+
adminAlertDedupCache.delete(key);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return true;
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const notifyAdminAiError = async (sock, { commandName = 'cat', stage = 'unknown', remoteJid = '', senderJid = '', messageInfo = null, error = null } = {}) => {
|
|
399
|
+
try {
|
|
400
|
+
const adminJid = normalizeJid((await resolveAdminJid().catch(() => null)) || OWNER_JID || '');
|
|
401
|
+
if (!adminJid) return;
|
|
402
|
+
|
|
403
|
+
const normalizedRemote = normalizeJid(remoteJid || '') || String(remoteJid || '').trim() || 'desconhecido';
|
|
404
|
+
const normalizedSender = normalizeJid(senderJid || '') || String(senderJid || '').trim() || 'desconhecido';
|
|
405
|
+
const errorMessage = String(error?.message || error || 'erro desconhecido').trim() || 'erro desconhecido';
|
|
406
|
+
const errorStatus = error?.status || error?.statusCode || error?.response?.status || null;
|
|
407
|
+
const messageId = messageInfo?.key?.id || 'sem_id';
|
|
408
|
+
const shouldSend = shouldSendAdminAlert({
|
|
409
|
+
commandName,
|
|
410
|
+
stage,
|
|
411
|
+
remoteJid: normalizedRemote,
|
|
412
|
+
senderJid: normalizedSender,
|
|
413
|
+
errorMessage,
|
|
414
|
+
});
|
|
415
|
+
if (!shouldSend) return;
|
|
416
|
+
|
|
417
|
+
const statusLine = errorStatus ? `\n- Status: ${errorStatus}` : '';
|
|
418
|
+
await sendAndStore(sock, adminJid, {
|
|
419
|
+
text: `🚨 *Alerta IA*\n\n- Comando: ${commandName}\n- Etapa: ${stage}\n- Chat: ${normalizedRemote}\n- Usuário: ${normalizedSender}\n- MsgID: ${messageId}${statusLine}\n- Erro: ${errorMessage}\n- Horário (UTC): ${__timeNowIso()}`,
|
|
420
|
+
});
|
|
421
|
+
} catch (notifyError) {
|
|
422
|
+
logger.warn('notifyAdminAiError: falha ao notificar admin no privado.', {
|
|
423
|
+
error: notifyError?.message || String(notifyError),
|
|
424
|
+
commandName,
|
|
425
|
+
stage,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
|
|
366
430
|
const sendPromptUsage = async (sock, remoteJid, messageInfo, expirationMessage, commandPrefix = DEFAULT_COMMAND_PREFIX) => {
|
|
431
|
+
const commandMessages = resolveAiMessages('catprompt');
|
|
367
432
|
const usageText =
|
|
368
433
|
getAiUsageText('catprompt', {
|
|
369
434
|
commandPrefix,
|
|
370
|
-
header:
|
|
435
|
+
header: commandMessages.usageHeader,
|
|
371
436
|
variant: 'default',
|
|
372
|
-
}) ||
|
|
437
|
+
}) || `${commandMessages.usageHeader}\n*${commandPrefix}catprompt*`;
|
|
373
438
|
|
|
374
439
|
await sendAndStore(sock, remoteJid, { text: usageText }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
375
440
|
};
|
|
376
441
|
|
|
377
442
|
const sendImageUsage = async (sock, remoteJid, messageInfo, expirationMessage, commandPrefix = DEFAULT_COMMAND_PREFIX) => {
|
|
443
|
+
const commandMessages = resolveAiMessages('catimg');
|
|
378
444
|
const usageText =
|
|
379
445
|
getAiUsageText('catimg', {
|
|
380
446
|
commandPrefix,
|
|
381
|
-
header:
|
|
447
|
+
header: commandMessages.usageHeader,
|
|
382
448
|
variant: 'default',
|
|
383
|
-
}) ||
|
|
449
|
+
}) || `${commandMessages.usageHeader}\n*${commandPrefix}catimg*`;
|
|
384
450
|
|
|
385
451
|
await sendAndStore(sock, remoteJid, { text: usageText }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
386
452
|
};
|
|
@@ -664,21 +730,29 @@ export async function handleCatCommand({ sock, remoteJid, messageInfo, expiratio
|
|
|
664
730
|
const commandMessages = resolveAiMessages(commandName);
|
|
665
731
|
const { prompt: rawPrompt, wantsAudio, imageDetail } = parseCatOptions(text || '', resolveCatParseOptions());
|
|
666
732
|
|
|
733
|
+
if (isAiCommandPremiumOnly(commandName)) {
|
|
734
|
+
if (!(await isPremiumAllowed(senderJid))) {
|
|
735
|
+
await sendPremiumOnly(sock, remoteJid, messageInfo, expirationMessage, { commandName });
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
667
740
|
if (!process.env.OPENAI_API_KEY) {
|
|
668
741
|
logger.warn('handleCatCommand: OPENAI_API_KEY não configurada.');
|
|
669
742
|
await sendAndStore(sock, remoteJid, { text: commandMessages.openAiNotConfigured }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
743
|
+
await notifyAdminAiError(sock, {
|
|
744
|
+
commandName,
|
|
745
|
+
stage: 'openai_api_key_missing',
|
|
746
|
+
remoteJid,
|
|
747
|
+
senderJid,
|
|
748
|
+
messageInfo,
|
|
749
|
+
error: new Error('OPENAI_API_KEY não configurada para comando cat'),
|
|
750
|
+
});
|
|
670
751
|
return;
|
|
671
752
|
}
|
|
672
753
|
|
|
673
754
|
await reactToMessage(sock, remoteJid, messageInfo);
|
|
674
755
|
|
|
675
|
-
if (isAiCommandPremiumOnly(commandName)) {
|
|
676
|
-
if (!(await isPremiumAllowed(senderJid))) {
|
|
677
|
-
await sendPremiumOnly(sock, remoteJid, messageInfo, expirationMessage, { commandName });
|
|
678
|
-
return;
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
756
|
const imageMedia = findImageMedia(messageInfo);
|
|
683
757
|
const imageResult = await buildImageDataUrl(imageMedia, senderJid);
|
|
684
758
|
if (imageResult.error === 'too_large') {
|
|
@@ -742,7 +816,7 @@ export async function handleCatCommand({ sock, remoteJid, messageInfo, expiratio
|
|
|
742
816
|
|
|
743
817
|
sessionCache.set(sessionKey, {
|
|
744
818
|
previousResponseId: response.id,
|
|
745
|
-
updatedAt:
|
|
819
|
+
updatedAt: __timeNowMs(),
|
|
746
820
|
});
|
|
747
821
|
|
|
748
822
|
if (!outputText) {
|
|
@@ -781,11 +855,20 @@ export async function handleCatCommand({ sock, remoteJid, messageInfo, expiratio
|
|
|
781
855
|
} catch (audioError) {
|
|
782
856
|
logger.error('handleCatCommand: erro ao gerar audio.', audioError);
|
|
783
857
|
await sendAndStore(sock, remoteJid, { text: commandMessages.audioFailedFallback }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
858
|
+
await notifyAdminAiError(sock, {
|
|
859
|
+
commandName,
|
|
860
|
+
stage: 'audio_speech_create',
|
|
861
|
+
remoteJid,
|
|
862
|
+
senderJid,
|
|
863
|
+
messageInfo,
|
|
864
|
+
error: audioError,
|
|
865
|
+
});
|
|
784
866
|
}
|
|
785
867
|
}
|
|
786
868
|
}
|
|
787
869
|
|
|
788
|
-
|
|
870
|
+
const responsePrefix = commandMessages.textResponsePrefix;
|
|
871
|
+
await sendAndStore(sock, remoteJid, { text: `${responsePrefix}${outputText}` }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
789
872
|
} catch (error) {
|
|
790
873
|
logger.error('handleCatCommand: erro ao chamar OpenAI.', error);
|
|
791
874
|
await sendAndStore(
|
|
@@ -796,6 +879,14 @@ export async function handleCatCommand({ sock, remoteJid, messageInfo, expiratio
|
|
|
796
879
|
},
|
|
797
880
|
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
798
881
|
);
|
|
882
|
+
await notifyAdminAiError(sock, {
|
|
883
|
+
commandName,
|
|
884
|
+
stage: 'responses_create',
|
|
885
|
+
remoteJid,
|
|
886
|
+
senderJid,
|
|
887
|
+
messageInfo,
|
|
888
|
+
error,
|
|
889
|
+
});
|
|
799
890
|
}
|
|
800
891
|
}
|
|
801
892
|
|
|
@@ -804,21 +895,29 @@ export async function handleCatImageCommand({ sock, remoteJid, messageInfo, expi
|
|
|
804
895
|
const commandMessages = resolveAiMessages(commandName);
|
|
805
896
|
const { prompt, toolOptions, errors } = parseImageGenOptions(text || '', resolveCatImageGenerationOptions());
|
|
806
897
|
|
|
898
|
+
if (isAiCommandPremiumOnly(commandName)) {
|
|
899
|
+
if (!(await isPremiumAllowed(senderJid))) {
|
|
900
|
+
await sendPremiumOnly(sock, remoteJid, messageInfo, expirationMessage, { commandName });
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
807
905
|
if (!process.env.OPENAI_API_KEY) {
|
|
808
906
|
logger.warn('handleCatImageCommand: OPENAI_API_KEY não configurada.');
|
|
809
907
|
await sendAndStore(sock, remoteJid, { text: commandMessages.openAiNotConfigured }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
908
|
+
await notifyAdminAiError(sock, {
|
|
909
|
+
commandName,
|
|
910
|
+
stage: 'openai_api_key_missing',
|
|
911
|
+
remoteJid,
|
|
912
|
+
senderJid,
|
|
913
|
+
messageInfo,
|
|
914
|
+
error: new Error('OPENAI_API_KEY não configurada para comando catimg'),
|
|
915
|
+
});
|
|
810
916
|
return;
|
|
811
917
|
}
|
|
812
918
|
|
|
813
919
|
await reactToMessage(sock, remoteJid, messageInfo);
|
|
814
920
|
|
|
815
|
-
if (isAiCommandPremiumOnly(commandName)) {
|
|
816
|
-
if (!(await isPremiumAllowed(senderJid))) {
|
|
817
|
-
await sendPremiumOnly(sock, remoteJid, messageInfo, expirationMessage, { commandName });
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
|
|
822
921
|
const imageMedia = findImageMedia(messageInfo);
|
|
823
922
|
const imageResult = await buildImageDataUrl(imageMedia, senderJid);
|
|
824
923
|
if (imageResult.error === 'too_large') {
|
|
@@ -893,7 +992,7 @@ export async function handleCatImageCommand({ sock, remoteJid, messageInfo, expi
|
|
|
893
992
|
|
|
894
993
|
sessionCache.set(sessionKey, {
|
|
895
994
|
previousResponseId: response.id,
|
|
896
|
-
updatedAt:
|
|
995
|
+
updatedAt: __timeNowMs(),
|
|
897
996
|
});
|
|
898
997
|
|
|
899
998
|
const imageOutputs = Array.isArray(response.output) ? response.output.filter((output) => output.type === 'image_generation_call' && output.result) : [];
|
|
@@ -901,7 +1000,7 @@ export async function handleCatImageCommand({ sock, remoteJid, messageInfo, expi
|
|
|
901
1000
|
|
|
902
1001
|
if (!imageBase64) {
|
|
903
1002
|
if (outputText) {
|
|
904
|
-
await sendAndStore(sock, remoteJid, { text:
|
|
1003
|
+
await sendAndStore(sock, remoteJid, { text: `${commandMessages.imageTextResponsePrefix}${outputText}` }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
905
1004
|
return;
|
|
906
1005
|
}
|
|
907
1006
|
|
|
@@ -917,7 +1016,7 @@ export async function handleCatImageCommand({ sock, remoteJid, messageInfo, expi
|
|
|
917
1016
|
};
|
|
918
1017
|
const mimetype = mimeByFormat[outputFormat] || 'image/png';
|
|
919
1018
|
const imageBuffer = Buffer.from(imageBase64, 'base64');
|
|
920
|
-
const caption = outputText ?
|
|
1019
|
+
const caption = outputText ? `${commandMessages.imageTextResponsePrefix}${outputText}` : commandMessages.imageSuccessCaption;
|
|
921
1020
|
|
|
922
1021
|
await sendAndStore(sock, remoteJid, { image: imageBuffer, caption, mimetype }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
923
1022
|
} catch (error) {
|
|
@@ -930,6 +1029,14 @@ export async function handleCatImageCommand({ sock, remoteJid, messageInfo, expi
|
|
|
930
1029
|
},
|
|
931
1030
|
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
932
1031
|
);
|
|
1032
|
+
await notifyAdminAiError(sock, {
|
|
1033
|
+
commandName,
|
|
1034
|
+
stage: 'responses_create_image',
|
|
1035
|
+
remoteJid,
|
|
1036
|
+
senderJid,
|
|
1037
|
+
messageInfo,
|
|
1038
|
+
error,
|
|
1039
|
+
});
|
|
933
1040
|
}
|
|
934
1041
|
}
|
|
935
1042
|
|
|
@@ -937,6 +1044,7 @@ export async function handleCatPromptCommand({ sock, remoteJid, messageInfo, exp
|
|
|
937
1044
|
const commandName = 'catprompt';
|
|
938
1045
|
const commandMessages = resolveAiMessages(commandName);
|
|
939
1046
|
const promptMaxChars = resolveCatPromptMaxChars();
|
|
1047
|
+
const promptResetAliases = resolveCatPromptResetAliases();
|
|
940
1048
|
const promptText = text?.trim();
|
|
941
1049
|
if (!promptText) {
|
|
942
1050
|
await sendPromptUsage(sock, remoteJid, messageInfo, expirationMessage, commandPrefix);
|
|
@@ -950,8 +1058,8 @@ export async function handleCatPromptCommand({ sock, remoteJid, messageInfo, exp
|
|
|
950
1058
|
}
|
|
951
1059
|
}
|
|
952
1060
|
|
|
953
|
-
const lower = promptText
|
|
954
|
-
if (lower
|
|
1061
|
+
const lower = normalizeText(promptText);
|
|
1062
|
+
if (promptResetAliases.has(lower)) {
|
|
955
1063
|
await aiPromptStore.clearPrompt(senderJid);
|
|
956
1064
|
await sendAndStore(sock, remoteJid, { text: commandMessages.promptResetSuccess }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
957
1065
|
return;
|