@kaikybrofc/omnizap-system 2.2.10 → 2.3.0
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/README.md +20 -18
- package/app/config/adminIdentity.js +1 -3
- package/app/connection/socketController.js +10 -20
- package/app/controllers/messageController.js +7 -28
- package/app/modules/aiModule/catCommand.js +29 -192
- package/app/modules/broadcastModule/noticeCommand.js +28 -97
- package/app/modules/gameModule/diceCommand.js +6 -32
- package/app/modules/playModule/playCommand.js +57 -258
- package/app/modules/quoteModule/quoteCommand.js +2 -4
- package/app/modules/rpgPokemonModule/rpgPokemonRepository.js +1 -13
- package/app/modules/statsModule/noMessageCommand.js +16 -84
- package/app/modules/statsModule/rankingCommand.js +5 -25
- package/app/modules/statsModule/rankingCommon.js +1 -9
- package/app/modules/stickerModule/convertToWebp.js +4 -27
- package/app/modules/stickerModule/stickerCommand.js +13 -24
- package/app/modules/stickerModule/stickerTextCommand.js +13 -25
- package/app/modules/stickerPackModule/autoPackCollectorService.js +16 -7
- package/app/modules/stickerPackModule/domainEventOutboxRepository.js +20 -36
- package/app/modules/stickerPackModule/domainEvents.js +2 -11
- package/app/modules/stickerPackModule/semanticReclassificationEngine.js +13 -50
- package/app/modules/stickerPackModule/semanticReclassificationEngine.test.js +2 -15
- package/app/modules/stickerPackModule/semanticThemeClusterService.js +14 -41
- package/app/modules/stickerPackModule/stickerAssetClassificationRepository.js +25 -95
- package/app/modules/stickerPackModule/stickerAssetRepository.js +12 -31
- package/app/modules/stickerPackModule/stickerAssetReprocessQueueRepository.js +13 -18
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +284 -709
- package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +27 -106
- package/app/modules/stickerPackModule/stickerClassificationService.js +46 -77
- package/app/modules/stickerPackModule/stickerDedicatedTaskWorkerRuntime.js +13 -53
- package/app/modules/stickerPackModule/stickerDomainEventBus.js +10 -16
- package/app/modules/stickerPackModule/stickerDomainEventConsumerRuntime.js +13 -34
- package/app/modules/stickerPackModule/stickerMarketplaceDriftService.js +1 -4
- package/app/modules/stickerPackModule/stickerObjectStorageService.js +26 -26
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +32 -187
- package/app/modules/stickerPackModule/stickerPackInteractionEventRepository.js +6 -15
- package/app/modules/stickerPackModule/stickerPackItemRepository.js +6 -32
- package/app/modules/stickerPackModule/stickerPackMarketplaceService.js +12 -36
- package/app/modules/stickerPackModule/stickerPackMessageService.js +12 -40
- package/app/modules/stickerPackModule/stickerPackRepository.js +23 -66
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRepository.js +9 -21
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRuntime.js +10 -40
- package/app/modules/stickerPackModule/stickerPackService.js +50 -115
- package/app/modules/stickerPackModule/stickerPackServiceRuntime.js +2 -21
- package/app/modules/stickerPackModule/stickerPackUtils.js +13 -3
- package/app/modules/stickerPackModule/stickerStorageService.js +16 -65
- package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +4 -22
- package/app/modules/stickerPackModule/stickerWorkerTaskQueueRepository.js +14 -29
- package/app/modules/systemMetricsModule/pingCommand.js +9 -39
- package/app/modules/tiktokModule/tiktokCommand.js +17 -109
- package/app/modules/userModule/userCommand.js +2 -88
- package/app/observability/metrics.js +5 -16
- package/app/services/captchaService.js +1 -6
- package/app/services/dbWriteQueue.js +3 -18
- package/app/services/featureFlagService.js +2 -8
- package/app/services/newsBroadcastService.js +0 -1
- package/app/services/queueUtils.js +2 -4
- package/app/services/whatsappLoginLinkService.js +7 -9
- package/app/store/premiumUserStore.js +1 -2
- package/app/utils/antiLink/antiLinkModule.js +3 -233
- package/app/utils/logger/loggerModule.js +9 -34
- package/app/utils/systemMetrics/systemMetricsModule.js +1 -4
- package/database/init.js +1 -8
- package/docker-compose.yml +27 -27
- package/docs/seo/omnizap-seo-playbook-br-2026-02-28.md +26 -0
- package/docs/seo/satellite-page-template.md +2 -0
- package/docs/seo/satellite-pages-phase1.json +40 -177
- package/eslint.config.js +2 -15
- package/index.js +8 -36
- package/ml/clip_classifier/README.md +4 -6
- package/observability/alert-rules.yml +12 -12
- package/observability/grafana/provisioning/dashboards/dashboards.yml +1 -1
- package/package.json +6 -3
- package/public/api-docs/index.html +220 -193
- package/public/bot-whatsapp-para-grupo/index.html +291 -261
- package/public/bot-whatsapp-sem-programar/index.html +291 -261
- package/public/comandos/index.html +421 -406
- package/public/como-automatizar-avisos-no-whatsapp/index.html +291 -261
- package/public/como-criar-comandos-whatsapp/index.html +291 -261
- package/public/como-evitar-spam-no-whatsapp/index.html +291 -261
- package/public/como-moderar-grupo-whatsapp/index.html +291 -261
- package/public/como-organizar-comunidade-whatsapp/index.html +291 -261
- package/public/css/github-project-panel.css +13 -8
- package/public/css/stickers-admin.css +25 -9
- package/public/css/styles.css +23 -16
- package/public/index.html +1117 -994
- package/public/js/apps/apiDocsApp.js +17 -167
- package/public/js/apps/createPackApp.js +69 -332
- package/public/js/apps/homeApp.js +94 -74
- package/public/js/apps/loginApp.js +3 -12
- package/public/js/apps/stickersAdminApp.js +190 -181
- package/public/js/apps/stickersApp.js +496 -1397
- package/public/js/catalog.js +11 -74
- package/public/js/github-panel/components/ErrorState.js +1 -8
- package/public/js/github-panel/components/GithubProjectPanel.js +2 -9
- package/public/js/github-panel/components/SkeletonPanel.js +1 -11
- package/public/js/github-panel/components/StatCard.js +1 -7
- package/public/js/github-panel/vendor/react.js +1 -9
- package/public/js/runtime/react-runtime.js +1 -9
- package/public/licenca/index.html +104 -86
- package/public/login/index.html +315 -325
- package/public/melhor-bot-whatsapp-para-grupos/index.html +291 -261
- package/public/stickers/admin/index.html +14 -19
- package/public/stickers/create/index.html +39 -44
- package/public/stickers/index.html +96 -107
- package/public/termos-de-uso/index.html +142 -115
- package/public/user/index.html +347 -350
- package/scripts/cache-bust.mjs +5 -24
- package/scripts/generate-seo-satellite-pages.mjs +10 -13
- package/scripts/run-prettier-all.mjs +25 -0
- package/scripts/sticker-catalog-loadtest.mjs +13 -11
- package/scripts/sticker-worker-task.mjs +1 -4
- package/scripts/sync-readme-snapshot.mjs +3 -2
- package/server/controllers/stickerCatalogController.js +67 -5
- package/server/http/httpServer.js +2 -10
- package/server/routes/stickerCatalog/catalogHandlers/catalogAdminHttp.js +1 -8
- package/server/routes/stickerCatalog/catalogHandlers/catalogAuthHttp.js +1 -9
- package/server/routes/stickerCatalog/catalogHandlers/catalogPublicHttp.js +10 -11
- package/server/routes/stickerCatalog/catalogHandlers/catalogUploadHttp.js +1 -10
- package/server/routes/stickerCatalog/catalogRouter.js +11 -13
|
@@ -14,15 +14,22 @@ const parseEnvBool = (value, fallback) => {
|
|
|
14
14
|
const OBJECT_STORAGE_ENABLED = parseEnvBool(process.env.STICKER_OBJECT_STORAGE_ENABLED, false);
|
|
15
15
|
const OBJECT_STORAGE_UPLOAD_ON_WRITE = parseEnvBool(process.env.STICKER_OBJECT_STORAGE_UPLOAD_ON_WRITE, true);
|
|
16
16
|
const OBJECT_STORAGE_SIGNED_URL_ENABLED = parseEnvBool(process.env.STICKER_OBJECT_STORAGE_SIGNED_URL_ENABLED, true);
|
|
17
|
-
const OBJECT_STORAGE_PROVIDER = String(process.env.STICKER_OBJECT_STORAGE_PROVIDER || 's3')
|
|
17
|
+
const OBJECT_STORAGE_PROVIDER = String(process.env.STICKER_OBJECT_STORAGE_PROVIDER || 's3')
|
|
18
|
+
.trim()
|
|
19
|
+
.toLowerCase();
|
|
18
20
|
const OBJECT_STORAGE_BUCKET = String(process.env.STICKER_OBJECT_STORAGE_BUCKET || '').trim();
|
|
19
21
|
const OBJECT_STORAGE_REGION = String(process.env.STICKER_OBJECT_STORAGE_REGION || 'us-east-1').trim() || 'us-east-1';
|
|
20
22
|
const OBJECT_STORAGE_ENDPOINT = String(process.env.STICKER_OBJECT_STORAGE_ENDPOINT || '').trim();
|
|
21
23
|
const OBJECT_STORAGE_ACCESS_KEY_ID = String(process.env.STICKER_OBJECT_STORAGE_ACCESS_KEY_ID || '').trim();
|
|
22
24
|
const OBJECT_STORAGE_SECRET_ACCESS_KEY = String(process.env.STICKER_OBJECT_STORAGE_SECRET_ACCESS_KEY || '').trim();
|
|
23
25
|
const OBJECT_STORAGE_FORCE_PATH_STYLE = parseEnvBool(process.env.STICKER_OBJECT_STORAGE_FORCE_PATH_STYLE, true);
|
|
24
|
-
const OBJECT_STORAGE_CDN_BASE_URL = String(process.env.STICKER_OBJECT_STORAGE_CDN_BASE_URL || '')
|
|
25
|
-
|
|
26
|
+
const OBJECT_STORAGE_CDN_BASE_URL = String(process.env.STICKER_OBJECT_STORAGE_CDN_BASE_URL || '')
|
|
27
|
+
.trim()
|
|
28
|
+
.replace(/\/+$/, '');
|
|
29
|
+
const OBJECT_STORAGE_KEY_PREFIX =
|
|
30
|
+
String(process.env.STICKER_OBJECT_STORAGE_KEY_PREFIX || 'stickers')
|
|
31
|
+
.trim()
|
|
32
|
+
.replace(/^\/+|\/+$/g, '') || 'stickers';
|
|
26
33
|
|
|
27
34
|
let sdkLoadState = {
|
|
28
35
|
loaded: false,
|
|
@@ -36,7 +43,9 @@ let s3Client = null;
|
|
|
36
43
|
|
|
37
44
|
const safeOwnerToken = (ownerJid) => {
|
|
38
45
|
const normalized = normalizeOwnerJid(ownerJid);
|
|
39
|
-
const token = String(normalized || 'unknown')
|
|
46
|
+
const token = String(normalized || 'unknown')
|
|
47
|
+
.replace(/[^a-zA-Z0-9._-]/g, '_')
|
|
48
|
+
.slice(0, 100);
|
|
40
49
|
return token || 'unknown';
|
|
41
50
|
};
|
|
42
51
|
|
|
@@ -62,7 +71,9 @@ const resolveStickerObjectKey = (asset) => {
|
|
|
62
71
|
const fromStoragePath = parseS3StoragePath(asset?.storage_path);
|
|
63
72
|
if (fromStoragePath?.key) return fromStoragePath.key;
|
|
64
73
|
const ownerToken = safeOwnerToken(asset?.owner_jid || 'unknown');
|
|
65
|
-
const sha256 = String(asset?.sha256 || '')
|
|
74
|
+
const sha256 = String(asset?.sha256 || '')
|
|
75
|
+
.trim()
|
|
76
|
+
.toLowerCase();
|
|
66
77
|
if (!sha256) return '';
|
|
67
78
|
return `${OBJECT_STORAGE_KEY_PREFIX}/${ownerToken}/${sha256}.webp`;
|
|
68
79
|
};
|
|
@@ -70,10 +81,7 @@ const resolveStickerObjectKey = (asset) => {
|
|
|
70
81
|
const loadAwsSdk = async () => {
|
|
71
82
|
if (sdkLoadState.loaded) return sdkLoadState;
|
|
72
83
|
try {
|
|
73
|
-
const [{ S3Client, PutObjectCommand, GetObjectCommand }, { getSignedUrl }] = await Promise.all([
|
|
74
|
-
import('@aws-sdk/client-s3'),
|
|
75
|
-
import('@aws-sdk/s3-request-presigner'),
|
|
76
|
-
]);
|
|
84
|
+
const [{ S3Client, PutObjectCommand, GetObjectCommand }, { getSignedUrl }] = await Promise.all([import('@aws-sdk/client-s3'), import('@aws-sdk/s3-request-presigner')]);
|
|
77
85
|
sdkLoadState = {
|
|
78
86
|
loaded: true,
|
|
79
87
|
warned: false,
|
|
@@ -149,15 +157,9 @@ const streamToBuffer = async (body) => {
|
|
|
149
157
|
return null;
|
|
150
158
|
};
|
|
151
159
|
|
|
152
|
-
export const isStickerObjectStorageEnabled = () =>
|
|
153
|
-
Boolean(OBJECT_STORAGE_ENABLED && OBJECT_STORAGE_PROVIDER === 's3' && OBJECT_STORAGE_BUCKET);
|
|
160
|
+
export const isStickerObjectStorageEnabled = () => Boolean(OBJECT_STORAGE_ENABLED && OBJECT_STORAGE_PROVIDER === 's3' && OBJECT_STORAGE_BUCKET);
|
|
154
161
|
|
|
155
|
-
export const uploadStickerToObjectStorage = async ({
|
|
156
|
-
ownerJid,
|
|
157
|
-
sha256,
|
|
158
|
-
buffer,
|
|
159
|
-
mimetype = 'image/webp',
|
|
160
|
-
} = {}) => {
|
|
162
|
+
export const uploadStickerToObjectStorage = async ({ ownerJid, sha256, buffer, mimetype = 'image/webp' } = {}) => {
|
|
161
163
|
if (!OBJECT_STORAGE_UPLOAD_ON_WRITE || !Buffer.isBuffer(buffer) || !buffer.length) {
|
|
162
164
|
return { uploaded: false, key: null };
|
|
163
165
|
}
|
|
@@ -165,7 +167,9 @@ export const uploadStickerToObjectStorage = async ({
|
|
|
165
167
|
return { uploaded: false, key: null };
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
const key = `${OBJECT_STORAGE_KEY_PREFIX}/${safeOwnerToken(ownerJid)}/${String(sha256 || '')
|
|
170
|
+
const key = `${OBJECT_STORAGE_KEY_PREFIX}/${safeOwnerToken(ownerJid)}/${String(sha256 || '')
|
|
171
|
+
.trim()
|
|
172
|
+
.toLowerCase()}.webp`;
|
|
169
173
|
if (!key || key.endsWith('/.webp')) return { uploaded: false, key: null };
|
|
170
174
|
|
|
171
175
|
try {
|
|
@@ -194,13 +198,7 @@ export const uploadStickerToObjectStorage = async ({
|
|
|
194
198
|
}
|
|
195
199
|
};
|
|
196
200
|
|
|
197
|
-
export const getStickerObjectStorageUrl = async (
|
|
198
|
-
asset,
|
|
199
|
-
{
|
|
200
|
-
secure = true,
|
|
201
|
-
expiresInSeconds = 300,
|
|
202
|
-
} = {},
|
|
203
|
-
) => {
|
|
201
|
+
export const getStickerObjectStorageUrl = async (asset, { secure = true, expiresInSeconds = 300 } = {}) => {
|
|
204
202
|
if (!isStickerObjectStorageEnabled()) return null;
|
|
205
203
|
|
|
206
204
|
const key = resolveStickerObjectKey(asset);
|
|
@@ -279,7 +277,9 @@ export const toStickerStoragePath = ({ localPath, ownerJid, sha256 }) => {
|
|
|
279
277
|
const normalizedLocalPath = path.resolve(String(localPath || ''));
|
|
280
278
|
if (!isStickerObjectStorageEnabled()) return normalizedLocalPath;
|
|
281
279
|
if (!OBJECT_STORAGE_UPLOAD_ON_WRITE) return normalizedLocalPath;
|
|
282
|
-
const key = `${OBJECT_STORAGE_KEY_PREFIX}/${safeOwnerToken(ownerJid)}/${String(sha256 || '')
|
|
280
|
+
const key = `${OBJECT_STORAGE_KEY_PREFIX}/${safeOwnerToken(ownerJid)}/${String(sha256 || '')
|
|
281
|
+
.trim()
|
|
282
|
+
.toLowerCase()}.webp`;
|
|
283
283
|
if (!key || key.endsWith('/.webp')) return normalizedLocalPath;
|
|
284
284
|
return `s3://${OBJECT_STORAGE_BUCKET}/${key}`;
|
|
285
285
|
};
|
|
@@ -3,10 +3,7 @@ import { sendAndStore } from '../../services/messagePersistenceService.js';
|
|
|
3
3
|
import { isUserJid } from '../../config/baileysConfig.js';
|
|
4
4
|
import stickerPackService from './stickerPackServiceRuntime.js';
|
|
5
5
|
import { STICKER_PACK_ERROR_CODES, StickerPackError } from './stickerPackErrors.js';
|
|
6
|
-
import {
|
|
7
|
-
captureIncomingStickerAsset,
|
|
8
|
-
resolveStickerAssetForCommand,
|
|
9
|
-
} from './stickerStorageService.js';
|
|
6
|
+
import { captureIncomingStickerAsset, resolveStickerAssetForCommand } from './stickerStorageService.js';
|
|
10
7
|
import { buildStickerPackMessage, sendStickerPackWithFallback } from './stickerPackMessageService.js';
|
|
11
8
|
import { sanitizeText } from './stickerPackUtils.js';
|
|
12
9
|
|
|
@@ -221,10 +218,7 @@ const buildPackVisualMessage = ({ intro = [], sections = [], footer = [] }) => {
|
|
|
221
218
|
const buildActionMessage = ({ title, explanation = [], details = [], nextSteps = [], footer = [] }) =>
|
|
222
219
|
buildPackVisualMessage({
|
|
223
220
|
intro: [title, ...normalizeMessageLines(explanation)],
|
|
224
|
-
sections: [
|
|
225
|
-
normalizeMessageLines(details).length ? { title: '📌 *DETALHES*', lines: details } : null,
|
|
226
|
-
normalizeMessageLines(nextSteps).length ? { title: '➡️ *PRÓXIMAS AÇÕES*', lines: nextSteps } : null,
|
|
227
|
-
],
|
|
221
|
+
sections: [normalizeMessageLines(details).length ? { title: '📌 *DETALHES*', lines: details } : null, normalizeMessageLines(nextSteps).length ? { title: '➡️ *PRÓXIMAS AÇÕES*', lines: nextSteps } : null],
|
|
228
222
|
footer,
|
|
229
223
|
});
|
|
230
224
|
|
|
@@ -238,18 +232,11 @@ const buildActionMessage = ({ title, explanation = [], details = [], nextSteps =
|
|
|
238
232
|
const formatPackList = (packs, prefix) => {
|
|
239
233
|
if (!packs.length) {
|
|
240
234
|
return buildPackVisualMessage({
|
|
241
|
-
intro: [
|
|
242
|
-
'📭 *Nenhum pack extra encontrado.*',
|
|
243
|
-
'As figurinhas que você cria continuam sendo salvas automaticamente no seu *Pack Principal*.',
|
|
244
|
-
],
|
|
235
|
+
intro: ['📭 *Nenhum pack extra encontrado.*', 'As figurinhas que você cria continuam sendo salvas automaticamente no seu *Pack Principal*.'],
|
|
245
236
|
sections: [
|
|
246
237
|
{
|
|
247
238
|
title: '🆕 *COMECE EM 3 PASSOS*',
|
|
248
|
-
lines: [
|
|
249
|
-
`1) Crie um pack: \`${prefix}pack create meupack\``,
|
|
250
|
-
`2) Responda uma figurinha e adicione: \`${prefix}pack add <pack>\``,
|
|
251
|
-
`3) Veja o resumo: \`${prefix}pack info <pack>\``,
|
|
252
|
-
],
|
|
239
|
+
lines: [`1) Crie um pack: \`${prefix}pack create meupack\``, `2) Responda uma figurinha e adicione: \`${prefix}pack add <pack>\``, `3) Veja o resumo: \`${prefix}pack info <pack>\``],
|
|
253
240
|
},
|
|
254
241
|
],
|
|
255
242
|
footer: ['💡 Dica: crie packs por tema (memes, animes, reactions) para achar tudo mais rápido.'],
|
|
@@ -258,28 +245,16 @@ const formatPackList = (packs, prefix) => {
|
|
|
258
245
|
|
|
259
246
|
const lines = packs.map((pack, index) => {
|
|
260
247
|
const count = Number(pack.sticker_count || 0);
|
|
261
|
-
return [
|
|
262
|
-
`${index + 1}. *${pack.name}*`,
|
|
263
|
-
` 🆔 ID: \`${pack.pack_key}\``,
|
|
264
|
-
` 🧩 Itens: ${count}/${MAX_PACK_ITEMS}`,
|
|
265
|
-
` 👁️ Visibilidade: ${formatVisibilityLabel(pack.visibility)}`,
|
|
266
|
-
].join('\n');
|
|
248
|
+
return [`${index + 1}. *${pack.name}*`, ` 🆔 ID: \`${pack.pack_key}\``, ` 🧩 Itens: ${count}/${MAX_PACK_ITEMS}`, ` 👁️ Visibilidade: ${formatVisibilityLabel(pack.visibility)}`].join('\n');
|
|
267
249
|
});
|
|
268
250
|
|
|
269
251
|
return buildPackVisualMessage({
|
|
270
|
-
intro: [
|
|
271
|
-
`📋 *Packs encontrados: ${packs.length}*`,
|
|
272
|
-
'Você pode usar o *nome* ou o *ID* do pack para ver detalhes, editar ou enviar.',
|
|
273
|
-
],
|
|
252
|
+
intro: [`📋 *Packs encontrados: ${packs.length}*`, 'Você pode usar o *nome* ou o *ID* do pack para ver detalhes, editar ou enviar.'],
|
|
274
253
|
sections: [
|
|
275
254
|
{ title: '📦 *SEUS PACKS*', lines },
|
|
276
255
|
{
|
|
277
256
|
title: '🛠 *ATALHOS*',
|
|
278
|
-
lines: [
|
|
279
|
-
`ℹ️ Detalhes: \`${prefix}pack info <pack>\``,
|
|
280
|
-
`📤 Enviar: \`${prefix}pack send <pack>\``,
|
|
281
|
-
`🆕 Criar novo: \`${prefix}pack create meupack\``,
|
|
282
|
-
],
|
|
257
|
+
lines: [`ℹ️ Detalhes: \`${prefix}pack info <pack>\``, `📤 Enviar: \`${prefix}pack send <pack>\``, `🆕 Criar novo: \`${prefix}pack create meupack\``],
|
|
283
258
|
},
|
|
284
259
|
],
|
|
285
260
|
footer: ['✅ Tudo pronto — escolha um pack e continue gerenciando.'],
|
|
@@ -307,22 +282,11 @@ const formatPackInfo = (pack, prefix) => {
|
|
|
307
282
|
}
|
|
308
283
|
|
|
309
284
|
return buildPackVisualMessage({
|
|
310
|
-
intro: [
|
|
311
|
-
`ℹ️ *Informações do pack: "${pack.name}"*`,
|
|
312
|
-
'Aqui você vê identificação, visibilidade e uma prévia dos itens cadastrados.',
|
|
313
|
-
],
|
|
285
|
+
intro: [`ℹ️ *Informações do pack: "${pack.name}"*`, 'Aqui você vê identificação, visibilidade e uma prévia dos itens cadastrados.'],
|
|
314
286
|
sections: [
|
|
315
287
|
{
|
|
316
288
|
title: '📌 *DADOS DO PACK*',
|
|
317
|
-
lines: [
|
|
318
|
-
`📛 Nome: *${pack.name}*`,
|
|
319
|
-
`🆔 ID: \`${pack.pack_key}\``,
|
|
320
|
-
`👤 Publisher: *${pack.publisher}*`,
|
|
321
|
-
`👁️ Visibilidade: ${formatVisibilityLabel(pack.visibility)}`,
|
|
322
|
-
`🧩 Itens: *${pack.items.length}/${MAX_PACK_ITEMS}*`,
|
|
323
|
-
`🖼️ Capa: *${coverLabel}*`,
|
|
324
|
-
`📝 Descrição: ${pack.description ? `"${pack.description}"` : 'não definida'}`,
|
|
325
|
-
],
|
|
289
|
+
lines: [`📛 Nome: *${pack.name}*`, `🆔 ID: \`${pack.pack_key}\``, `👤 Publisher: *${pack.publisher}*`, `👁️ Visibilidade: ${formatVisibilityLabel(pack.visibility)}`, `🧩 Itens: *${pack.items.length}/${MAX_PACK_ITEMS}*`, `🖼️ Capa: *${coverLabel}*`, `📝 Descrição: ${pack.description ? `"${pack.description}"` : 'não definida'}`],
|
|
326
290
|
},
|
|
327
291
|
{
|
|
328
292
|
title: '🖼️ *PRÉVIA (ATÉ 12 ITENS)*',
|
|
@@ -330,12 +294,7 @@ const formatPackInfo = (pack, prefix) => {
|
|
|
330
294
|
},
|
|
331
295
|
{
|
|
332
296
|
title: '⚙️ *AÇÕES DISPONÍVEIS*',
|
|
333
|
-
lines: [
|
|
334
|
-
`➕ Adicionar: \`${prefix}pack add ${pack.pack_key}\``,
|
|
335
|
-
`🖼 Definir capa: \`${prefix}pack setcover ${pack.pack_key}\``,
|
|
336
|
-
`🔀 Reordenar: \`${prefix}pack reorder ${pack.pack_key} 1 2 3 ...\``,
|
|
337
|
-
`📤 Enviar: \`${prefix}pack send ${pack.pack_key}\``,
|
|
338
|
-
],
|
|
297
|
+
lines: [`➕ Adicionar: \`${prefix}pack add ${pack.pack_key}\``, `🖼 Definir capa: \`${prefix}pack setcover ${pack.pack_key}\``, `🔀 Reordenar: \`${prefix}pack reorder ${pack.pack_key} 1 2 3 ...\``, `📤 Enviar: \`${prefix}pack send ${pack.pack_key}\``],
|
|
339
298
|
},
|
|
340
299
|
],
|
|
341
300
|
footer: ['💡 Se precisar, use o guia completo com `pack` para ver exemplos e comandos extras.'],
|
|
@@ -348,45 +307,7 @@ const formatPackInfo = (pack, prefix) => {
|
|
|
348
307
|
* @param {string} prefix Prefixo de comando.
|
|
349
308
|
* @returns {string} Guia textual.
|
|
350
309
|
*/
|
|
351
|
-
const buildPackHelp = (prefix) =>
|
|
352
|
-
[
|
|
353
|
-
'📦 *PACKS DE FIGURINHAS — GUIA RÁPIDO*',
|
|
354
|
-
'',
|
|
355
|
-
'Toda figurinha que você criar é salva automaticamente no seu *Pack Principal*.',
|
|
356
|
-
'Além disso, você pode criar packs extras para organizar por tema e enviar mais rápido.',
|
|
357
|
-
'',
|
|
358
|
-
PACK_VISUAL_DIVIDER,
|
|
359
|
-
'🧭 *COMANDOS PRINCIPAIS*',
|
|
360
|
-
'',
|
|
361
|
-
'🆕 Criar um pack',
|
|
362
|
-
`\`${prefix}pack create "Meus memes 😂" | publisher="Seu Nome" | desc="Descrição"\``,
|
|
363
|
-
'_Nome livre: espaços e emojis são permitidos._',
|
|
364
|
-
'',
|
|
365
|
-
'📋 Listar packs',
|
|
366
|
-
`\`${prefix}pack list\``,
|
|
367
|
-
'',
|
|
368
|
-
'ℹ️ Ver detalhes do pack',
|
|
369
|
-
`\`${prefix}pack info <pack>\``,
|
|
370
|
-
'',
|
|
371
|
-
'➕ Adicionar figurinha',
|
|
372
|
-
`\`${prefix}pack add <pack>\``,
|
|
373
|
-
'_Dica: responda uma figurinha (ou use a última enviada)._',
|
|
374
|
-
'',
|
|
375
|
-
'🖼 Definir capa',
|
|
376
|
-
`\`${prefix}pack setcover <pack>\``,
|
|
377
|
-
'',
|
|
378
|
-
'📤 Enviar pack no chat',
|
|
379
|
-
`\`${prefix}pack send "<nome do pack>"\``,
|
|
380
|
-
`_Ou use o ID: \`${prefix}pack send <pack_id>\`_`,
|
|
381
|
-
'',
|
|
382
|
-
PACK_VISUAL_DIVIDER,
|
|
383
|
-
'🧰 *COMANDOS EXTRAS*',
|
|
384
|
-
'',
|
|
385
|
-
'`rename` • `setpub` • `setdesc` • `remove` • `reorder` • `clone` • `publish` • `delete`',
|
|
386
|
-
'',
|
|
387
|
-
PACK_VISUAL_DIVIDER,
|
|
388
|
-
'✅ *Pronto!* Se quiser, diga o que você quer fazer (criar, organizar, enviar) que eu te guio.',
|
|
389
|
-
].join('\n');
|
|
310
|
+
const buildPackHelp = (prefix) => ['📦 *PACKS DE FIGURINHAS — GUIA RÁPIDO*', '', 'Toda figurinha que você criar é salva automaticamente no seu *Pack Principal*.', 'Além disso, você pode criar packs extras para organizar por tema e enviar mais rápido.', '', PACK_VISUAL_DIVIDER, '🧭 *COMANDOS PRINCIPAIS*', '', '🆕 Criar um pack', `\`${prefix}pack create "Meus memes 😂" | publisher="Seu Nome" | desc="Descrição"\``, '_Nome livre: espaços e emojis são permitidos._', '', '📋 Listar packs', `\`${prefix}pack list\``, '', 'ℹ️ Ver detalhes do pack', `\`${prefix}pack info <pack>\``, '', '➕ Adicionar figurinha', `\`${prefix}pack add <pack>\``, '_Dica: responda uma figurinha (ou use a última enviada)._', '', '🖼 Definir capa', `\`${prefix}pack setcover <pack>\``, '', '📤 Enviar pack no chat', `\`${prefix}pack send "<nome do pack>"\``, `_Ou use o ID: \`${prefix}pack send <pack_id>\`_`, '', PACK_VISUAL_DIVIDER, '🧰 *COMANDOS EXTRAS*', '', '`rename` • `setpub` • `setdesc` • `remove` • `reorder` • `clone` • `publish` • `delete`', '', PACK_VISUAL_DIVIDER, '✅ *Pronto!* Se quiser, diga o que você quer fazer (criar, organizar, enviar) que eu te guio.'].join('\n');
|
|
390
311
|
|
|
391
312
|
/**
|
|
392
313
|
* Template visual de erro orientado a resolução.
|
|
@@ -430,41 +351,28 @@ const formatErrorMessage = (error, commandPrefix) => {
|
|
|
430
351
|
return buildErrorMessage({
|
|
431
352
|
title: '🔎 *Pack não encontrado.*',
|
|
432
353
|
explanation: ['Não localizei um pack com esse nome ou ID.'],
|
|
433
|
-
steps: [
|
|
434
|
-
`Veja a lista com \`${commandPrefix}pack list\`.`,
|
|
435
|
-
'Copie o ID exatamente como aparece.',
|
|
436
|
-
`Depois tente novamente (ex.: \`${commandPrefix}pack info <pack>\`).`,
|
|
437
|
-
],
|
|
354
|
+
steps: [`Veja a lista com \`${commandPrefix}pack list\`.`, 'Copie o ID exatamente como aparece.', `Depois tente novamente (ex.: \`${commandPrefix}pack info <pack>\`).`],
|
|
438
355
|
commandPrefix,
|
|
439
356
|
});
|
|
440
357
|
case STICKER_PACK_ERROR_CODES.DUPLICATE_STICKER:
|
|
441
358
|
return buildErrorMessage({
|
|
442
359
|
title: '⚠️ *Essa figurinha já está no pack.*',
|
|
443
360
|
explanation: ['Para manter o pack organizado, não adiciono itens duplicados.'],
|
|
444
|
-
steps: [
|
|
445
|
-
`Veja os itens com \`${commandPrefix}pack info <pack>\`.`,
|
|
446
|
-
'Se quiser reorganizar, use `reorder`.',
|
|
447
|
-
],
|
|
361
|
+
steps: [`Veja os itens com \`${commandPrefix}pack info <pack>\`.`, 'Se quiser reorganizar, use `reorder`.'],
|
|
448
362
|
commandPrefix,
|
|
449
363
|
});
|
|
450
364
|
case STICKER_PACK_ERROR_CODES.PACK_LIMIT_REACHED:
|
|
451
365
|
return buildErrorMessage({
|
|
452
366
|
title: '⚠️ *Limite de figurinhas atingido.*',
|
|
453
367
|
explanation: [error.message || 'Este pack já está no limite e não aceita novos itens no momento.'],
|
|
454
|
-
steps: [
|
|
455
|
-
`Crie outro pack: \`${commandPrefix}pack create novopack\`.`,
|
|
456
|
-
'Depois continue adicionando as próximas figurinhas no novo pack.',
|
|
457
|
-
],
|
|
368
|
+
steps: [`Crie outro pack: \`${commandPrefix}pack create novopack\`.`, 'Depois continue adicionando as próximas figurinhas no novo pack.'],
|
|
458
369
|
commandPrefix,
|
|
459
370
|
});
|
|
460
371
|
case STICKER_PACK_ERROR_CODES.STICKER_NOT_FOUND:
|
|
461
372
|
return buildErrorMessage({
|
|
462
373
|
title: '🧩 *Não encontrei uma figurinha válida para usar.*',
|
|
463
374
|
explanation: ['Para esse comando, você precisa responder uma figurinha ou ter uma figurinha recente no contexto.'],
|
|
464
|
-
steps: [
|
|
465
|
-
'Responda diretamente a figurinha que você quer usar.',
|
|
466
|
-
'Ou envie uma figurinha e execute o comando novamente.',
|
|
467
|
-
],
|
|
375
|
+
steps: ['Responda diretamente a figurinha que você quer usar.', 'Ou envie uma figurinha e execute o comando novamente.'],
|
|
468
376
|
commandPrefix,
|
|
469
377
|
});
|
|
470
378
|
case STICKER_PACK_ERROR_CODES.INVALID_INPUT:
|
|
@@ -621,16 +529,7 @@ const resolveStickerFromCommandContext = async ({ messageInfo, ownerJid, include
|
|
|
621
529
|
* }} params Contexto da requisição.
|
|
622
530
|
* @returns {Promise<void>}
|
|
623
531
|
*/
|
|
624
|
-
export async function handlePackCommand({
|
|
625
|
-
sock,
|
|
626
|
-
remoteJid,
|
|
627
|
-
messageInfo,
|
|
628
|
-
expirationMessage,
|
|
629
|
-
senderJid,
|
|
630
|
-
senderName,
|
|
631
|
-
text,
|
|
632
|
-
commandPrefix,
|
|
633
|
-
}) {
|
|
532
|
+
export async function handlePackCommand({ sock, remoteJid, messageInfo, expirationMessage, senderJid, senderName, text, commandPrefix }) {
|
|
634
533
|
const ownerJid = senderJid;
|
|
635
534
|
const rate = checkRateLimit(ownerJid);
|
|
636
535
|
|
|
@@ -682,16 +581,8 @@ export async function handlePackCommand({
|
|
|
682
581
|
text: buildActionMessage({
|
|
683
582
|
title: '✅ *Pack criado!*',
|
|
684
583
|
explanation: ['Seu pack já está disponível e pronto para receber figurinhas.'],
|
|
685
|
-
details: [
|
|
686
|
-
|
|
687
|
-
`🆔 ID: \`${created.pack_key}\``,
|
|
688
|
-
`👤 Publisher: *${created.publisher}*`,
|
|
689
|
-
`👁️ Visibilidade: ${formatVisibilityLabel(created.visibility)}`,
|
|
690
|
-
],
|
|
691
|
-
nextSteps: [
|
|
692
|
-
`Responda uma figurinha e use: \`${commandPrefix}pack add ${created.pack_key}\`.`,
|
|
693
|
-
`Para conferir: \`${commandPrefix}pack info ${created.pack_key}\`.`,
|
|
694
|
-
],
|
|
584
|
+
details: [`📛 Nome: *${created.name}*`, `🆔 ID: \`${created.pack_key}\``, `👤 Publisher: *${created.publisher}*`, `👁️ Visibilidade: ${formatVisibilityLabel(created.visibility)}`],
|
|
585
|
+
nextSteps: [`Responda uma figurinha e use: \`${commandPrefix}pack add ${created.pack_key}\`.`, `Para conferir: \`${commandPrefix}pack info ${created.pack_key}\`.`],
|
|
695
586
|
footer: ['💡 Dica: use packs por tema para organizar e enviar mais rápido.'],
|
|
696
587
|
}),
|
|
697
588
|
});
|
|
@@ -759,9 +650,7 @@ export async function handlePackCommand({
|
|
|
759
650
|
title: '👤 *Publisher atualizado!*',
|
|
760
651
|
explanation: ['O publisher deste pack foi ajustado e já aparece nas informações.'],
|
|
761
652
|
details: [`📦 Pack: *${updated.name}*`, `👤 Publisher: *${updated.publisher}*`, `🆔 ID: \`${updated.pack_key}\``],
|
|
762
|
-
nextSteps: [
|
|
763
|
-
`Se quiser, ajuste a descrição: \`${commandPrefix}pack setdesc ${updated.pack_key} "Nova descrição"\`.`,
|
|
764
|
-
],
|
|
653
|
+
nextSteps: [`Se quiser, ajuste a descrição: \`${commandPrefix}pack setdesc ${updated.pack_key} "Nova descrição"\`.`],
|
|
765
654
|
}),
|
|
766
655
|
});
|
|
767
656
|
return;
|
|
@@ -780,10 +669,7 @@ export async function handlePackCommand({
|
|
|
780
669
|
text: buildActionMessage({
|
|
781
670
|
title: '📝 *Descrição atualizada!*',
|
|
782
671
|
explanation: ['A descrição ajuda a identificar o tema do pack.'],
|
|
783
|
-
details: [
|
|
784
|
-
`📦 Pack: *${updated.name}*`,
|
|
785
|
-
description ? `📝 Descrição: "${updated.description}"` : '🧹 Descrição removida.',
|
|
786
|
-
],
|
|
672
|
+
details: [`📦 Pack: *${updated.name}*`, description ? `📝 Descrição: "${updated.description}"` : '🧹 Descrição removida.'],
|
|
787
673
|
nextSteps: [`Ver como ficou: \`${commandPrefix}pack info ${updated.pack_key}\`.`],
|
|
788
674
|
}),
|
|
789
675
|
});
|
|
@@ -795,10 +681,7 @@ export async function handlePackCommand({
|
|
|
795
681
|
const asset = await resolveStickerFromCommandContext({ messageInfo, ownerJid });
|
|
796
682
|
|
|
797
683
|
if (!asset) {
|
|
798
|
-
throw new StickerPackError(
|
|
799
|
-
STICKER_PACK_ERROR_CODES.STICKER_NOT_FOUND,
|
|
800
|
-
'Não encontrei uma figurinha para definir como capa.',
|
|
801
|
-
);
|
|
684
|
+
throw new StickerPackError(STICKER_PACK_ERROR_CODES.STICKER_NOT_FOUND, 'Não encontrei uma figurinha para definir como capa.');
|
|
802
685
|
}
|
|
803
686
|
|
|
804
687
|
const updated = await stickerPackService.setPackCover({
|
|
@@ -829,10 +712,7 @@ export async function handlePackCommand({
|
|
|
829
712
|
|
|
830
713
|
const asset = await resolveStickerFromCommandContext({ messageInfo, ownerJid });
|
|
831
714
|
if (!asset) {
|
|
832
|
-
throw new StickerPackError(
|
|
833
|
-
STICKER_PACK_ERROR_CODES.STICKER_NOT_FOUND,
|
|
834
|
-
'Não encontrei uma figurinha para adicionar.',
|
|
835
|
-
);
|
|
715
|
+
throw new StickerPackError(STICKER_PACK_ERROR_CODES.STICKER_NOT_FOUND, 'Não encontrei uma figurinha para adicionar.');
|
|
836
716
|
}
|
|
837
717
|
|
|
838
718
|
const updated = await stickerPackService.addStickerToPack({
|
|
@@ -851,15 +731,8 @@ export async function handlePackCommand({
|
|
|
851
731
|
text: buildActionMessage({
|
|
852
732
|
title: '➕ *Figurinha adicionada!*',
|
|
853
733
|
explanation: ['Item adicionado com sucesso ao pack selecionado.'],
|
|
854
|
-
details: [
|
|
855
|
-
|
|
856
|
-
`🧩 Itens: *${updated.items.length}/${MAX_PACK_ITEMS}*`,
|
|
857
|
-
`🆔 ID: \`${updated.pack_key}\``,
|
|
858
|
-
],
|
|
859
|
-
nextSteps: [
|
|
860
|
-
`Definir como capa: responda a figurinha e use \`${commandPrefix}pack setcover ${updated.pack_key}\`.`,
|
|
861
|
-
`Ver lista completa: \`${commandPrefix}pack info ${updated.pack_key}\`.`,
|
|
862
|
-
],
|
|
734
|
+
details: [`📦 Pack: *${updated.name}*`, `🧩 Itens: *${updated.items.length}/${MAX_PACK_ITEMS}*`, `🆔 ID: \`${updated.pack_key}\``],
|
|
735
|
+
nextSteps: [`Definir como capa: responda a figurinha e use \`${commandPrefix}pack setcover ${updated.pack_key}\`.`, `Ver lista completa: \`${commandPrefix}pack info ${updated.pack_key}\`.`],
|
|
863
736
|
}),
|
|
864
737
|
});
|
|
865
738
|
return;
|
|
@@ -883,11 +756,7 @@ export async function handlePackCommand({
|
|
|
883
756
|
text: buildActionMessage({
|
|
884
757
|
title: '🗑️ *Figurinha removida!*',
|
|
885
758
|
explanation: ['Remoção concluída e o pack foi reordenado automaticamente.'],
|
|
886
|
-
details: [
|
|
887
|
-
`📦 Pack: *${result.pack.name}*`,
|
|
888
|
-
`🔢 Item removido: figurinha #${result.removed.position}`,
|
|
889
|
-
`🧩 Itens: *${result.pack.items.length}/${MAX_PACK_ITEMS}*`,
|
|
890
|
-
],
|
|
759
|
+
details: [`📦 Pack: *${result.pack.name}*`, `🔢 Item removido: figurinha #${result.removed.position}`, `🧩 Itens: *${result.pack.items.length}/${MAX_PACK_ITEMS}*`],
|
|
891
760
|
nextSteps: [`Conferir: \`${commandPrefix}pack info ${result.pack.pack_key}\`.`],
|
|
892
761
|
}),
|
|
893
762
|
});
|
|
@@ -942,10 +811,7 @@ export async function handlePackCommand({
|
|
|
942
811
|
title: '🧬 *Clone criado!*',
|
|
943
812
|
explanation: ['O pack foi duplicado com as mesmas figurinhas e configurações.'],
|
|
944
813
|
details: [`📦 Novo pack: *${cloned.name}*`, `🆔 ID: \`${cloned.pack_key}\``],
|
|
945
|
-
nextSteps: [
|
|
946
|
-
`Renomear: \`${commandPrefix}pack rename ${cloned.pack_key} novonome\`.`,
|
|
947
|
-
`Enviar: \`${commandPrefix}pack send ${cloned.pack_key}\`.`,
|
|
948
|
-
],
|
|
814
|
+
nextSteps: [`Renomear: \`${commandPrefix}pack rename ${cloned.pack_key} novonome\`.`, `Enviar: \`${commandPrefix}pack send ${cloned.pack_key}\`.`],
|
|
949
815
|
}),
|
|
950
816
|
});
|
|
951
817
|
return;
|
|
@@ -988,11 +854,7 @@ export async function handlePackCommand({
|
|
|
988
854
|
text: buildActionMessage({
|
|
989
855
|
title: '🌐 *Visibilidade atualizada!*',
|
|
990
856
|
explanation: ['A configuração de privacidade foi aplicada ao pack.'],
|
|
991
|
-
details: [
|
|
992
|
-
`📦 Pack: *${updated.name}*`,
|
|
993
|
-
`👁️ Visibilidade: ${formatVisibilityLabel(updated.visibility)}`,
|
|
994
|
-
`🆔 ID: \`${updated.pack_key}\``,
|
|
995
|
-
],
|
|
857
|
+
details: [`📦 Pack: *${updated.name}*`, `👁️ Visibilidade: ${formatVisibilityLabel(updated.visibility)}`, `🆔 ID: \`${updated.pack_key}\``],
|
|
996
858
|
nextSteps: [`Compartilhar/enviar: \`${commandPrefix}pack send ${updated.pack_key}\`.`],
|
|
997
859
|
}),
|
|
998
860
|
});
|
|
@@ -1020,15 +882,8 @@ export async function handlePackCommand({
|
|
|
1020
882
|
text: buildActionMessage({
|
|
1021
883
|
title: '📤 *Pack enviado!*',
|
|
1022
884
|
explanation: ['Enviei no formato nativo (melhor experiência e compatibilidade).'],
|
|
1023
|
-
details: [
|
|
1024
|
-
|
|
1025
|
-
`🆔 ID: \`${packDetails.pack_key}\``,
|
|
1026
|
-
`🧩 Enviadas: *${sendResult.sentCount} figurinha(s)*`,
|
|
1027
|
-
],
|
|
1028
|
-
nextSteps: [
|
|
1029
|
-
`Ver detalhes: \`${commandPrefix}pack info ${packDetails.pack_key}\`.`,
|
|
1030
|
-
`Editar: \`${commandPrefix}pack add ${packDetails.pack_key}\` ou \`${commandPrefix}pack remove ${packDetails.pack_key} <item>\`.`,
|
|
1031
|
-
],
|
|
885
|
+
details: [`📦 Pack: *${packDetails.name}*`, `🆔 ID: \`${packDetails.pack_key}\``, `🧩 Enviadas: *${sendResult.sentCount} figurinha(s)*`],
|
|
886
|
+
nextSteps: [`Ver detalhes: \`${commandPrefix}pack info ${packDetails.pack_key}\`.`, `Editar: \`${commandPrefix}pack add ${packDetails.pack_key}\` ou \`${commandPrefix}pack remove ${packDetails.pack_key} <item>\`.`],
|
|
1032
887
|
}),
|
|
1033
888
|
});
|
|
1034
889
|
} else {
|
|
@@ -1039,19 +894,9 @@ export async function handlePackCommand({
|
|
|
1039
894
|
expirationMessage,
|
|
1040
895
|
text: buildActionMessage({
|
|
1041
896
|
title: 'ℹ️ *Pack enviado em modo compatível.*',
|
|
1042
|
-
explanation: [
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
],
|
|
1046
|
-
details: [
|
|
1047
|
-
`📦 Pack: *${packDetails.name}*`,
|
|
1048
|
-
`🧩 Progresso: *${sendResult.sentCount}/${sendResult.total}*`,
|
|
1049
|
-
sendResult.nativeError ? `🛠 Detalhe técnico: ${sendResult.nativeError}` : null,
|
|
1050
|
-
],
|
|
1051
|
-
nextSteps: [
|
|
1052
|
-
`Você pode continuar gerenciando: \`${commandPrefix}pack info ${packDetails.pack_key}\`.`,
|
|
1053
|
-
`Para tentar novamente no formato nativo: \`${commandPrefix}pack send ${packDetails.pack_key}\` mais tarde.`,
|
|
1054
|
-
],
|
|
897
|
+
explanation: [`O cliente não aceitou o formato nativo para *${packDetails.name}*.`, 'Enviei em modo compatível (prévia + figurinhas individuais).'],
|
|
898
|
+
details: [`📦 Pack: *${packDetails.name}*`, `🧩 Progresso: *${sendResult.sentCount}/${sendResult.total}*`, sendResult.nativeError ? `🛠 Detalhe técnico: ${sendResult.nativeError}` : null],
|
|
899
|
+
nextSteps: [`Você pode continuar gerenciando: \`${commandPrefix}pack info ${packDetails.pack_key}\`.`, `Para tentar novamente no formato nativo: \`${commandPrefix}pack send ${packDetails.pack_key}\` mais tarde.`],
|
|
1055
900
|
}),
|
|
1056
901
|
});
|
|
1057
902
|
}
|
|
@@ -7,7 +7,9 @@ const clamp = (value, fallback, min, max) => {
|
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
const normalizeInteraction = (value) => {
|
|
10
|
-
const normalized = String(value || '')
|
|
10
|
+
const normalized = String(value || '')
|
|
11
|
+
.trim()
|
|
12
|
+
.toLowerCase();
|
|
11
13
|
if (['open', 'like', 'dislike'].includes(normalized)) return normalized;
|
|
12
14
|
return null;
|
|
13
15
|
};
|
|
@@ -20,10 +22,7 @@ const sanitizeKey = (value, maxLength = 120) => {
|
|
|
20
22
|
return normalized || null;
|
|
21
23
|
};
|
|
22
24
|
|
|
23
|
-
export async function createStickerPackInteractionEvent(
|
|
24
|
-
{ packId, interaction, actorKey = null, sessionKey = null, source = null },
|
|
25
|
-
connection = null,
|
|
26
|
-
) {
|
|
25
|
+
export async function createStickerPackInteractionEvent({ packId, interaction, actorKey = null, sessionKey = null, source = null }, connection = null) {
|
|
27
26
|
const normalizedInteraction = normalizeInteraction(interaction);
|
|
28
27
|
if (!packId || !normalizedInteraction) return false;
|
|
29
28
|
|
|
@@ -37,11 +36,7 @@ export async function createStickerPackInteractionEvent(
|
|
|
37
36
|
return true;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
export async function listStickerPackInteractionStatsByPackIds(
|
|
41
|
-
packIds,
|
|
42
|
-
{ horizonHours = 24, baselineDays = 7 } = {},
|
|
43
|
-
connection = null,
|
|
44
|
-
) {
|
|
39
|
+
export async function listStickerPackInteractionStatsByPackIds(packIds, { horizonHours = 24, baselineDays = 7 } = {}, connection = null) {
|
|
45
40
|
const ids = Array.from(new Set((Array.isArray(packIds) ? packIds : []).filter(Boolean)));
|
|
46
41
|
if (!ids.length) return new Map();
|
|
47
42
|
|
|
@@ -80,11 +75,7 @@ export async function listStickerPackInteractionStatsByPackIds(
|
|
|
80
75
|
return byPackId;
|
|
81
76
|
}
|
|
82
77
|
|
|
83
|
-
export async function listViewerRecentPackIds(
|
|
84
|
-
viewerKey,
|
|
85
|
-
{ days = 30, limit = 120 } = {},
|
|
86
|
-
connection = null,
|
|
87
|
-
) {
|
|
78
|
+
export async function listViewerRecentPackIds(viewerKey, { days = 30, limit = 120 } = {}, connection = null) {
|
|
88
79
|
const normalizedViewer = sanitizeKey(viewerKey);
|
|
89
80
|
if (!normalizedViewer) return [];
|
|
90
81
|
|
|
@@ -55,8 +55,7 @@ const normalizeItemRow = (row) => {
|
|
|
55
55
|
is_animated: row.asset_is_animated === 1 || row.asset_is_animated === true,
|
|
56
56
|
width: row.asset_width !== null && row.asset_width !== undefined ? Number(row.asset_width) : null,
|
|
57
57
|
height: row.asset_height !== null && row.asset_height !== undefined ? Number(row.asset_height) : null,
|
|
58
|
-
size_bytes:
|
|
59
|
-
row.asset_size_bytes !== null && row.asset_size_bytes !== undefined ? Number(row.asset_size_bytes) : 0,
|
|
58
|
+
size_bytes: row.asset_size_bytes !== null && row.asset_size_bytes !== undefined ? Number(row.asset_size_bytes) : 0,
|
|
60
59
|
storage_path: row.asset_storage_path,
|
|
61
60
|
created_at: row.asset_created_at,
|
|
62
61
|
}
|
|
@@ -181,11 +180,7 @@ export async function getStickerPackItemByPosition(packId, position, connection
|
|
|
181
180
|
* @returns {Promise<number>} Total de itens.
|
|
182
181
|
*/
|
|
183
182
|
export async function countStickerPackItems(packId, connection = null) {
|
|
184
|
-
const rows = await executeQuery(
|
|
185
|
-
`SELECT COUNT(*) AS total FROM ${TABLES.STICKER_PACK_ITEM} WHERE pack_id = ?`,
|
|
186
|
-
[packId],
|
|
187
|
-
connection,
|
|
188
|
-
);
|
|
183
|
+
const rows = await executeQuery(`SELECT COUNT(*) AS total FROM ${TABLES.STICKER_PACK_ITEM} WHERE pack_id = ?`, [packId], connection);
|
|
189
184
|
|
|
190
185
|
return Number(rows?.[0]?.total || 0);
|
|
191
186
|
}
|
|
@@ -198,11 +193,7 @@ export async function countStickerPackItems(packId, connection = null) {
|
|
|
198
193
|
* @returns {Promise<number>} Total de referências em packs.
|
|
199
194
|
*/
|
|
200
195
|
export async function countStickerPackItemRefsByStickerId(stickerId, connection = null) {
|
|
201
|
-
const rows = await executeQuery(
|
|
202
|
-
`SELECT COUNT(*) AS total FROM ${TABLES.STICKER_PACK_ITEM} WHERE sticker_id = ?`,
|
|
203
|
-
[stickerId],
|
|
204
|
-
connection,
|
|
205
|
-
);
|
|
196
|
+
const rows = await executeQuery(`SELECT COUNT(*) AS total FROM ${TABLES.STICKER_PACK_ITEM} WHERE sticker_id = ?`, [stickerId], connection);
|
|
206
197
|
|
|
207
198
|
return Number(rows?.[0]?.total || 0);
|
|
208
199
|
}
|
|
@@ -233,11 +224,7 @@ export async function listPackIdsByStickerId(stickerId, connection = null) {
|
|
|
233
224
|
* @returns {Promise<number>} Maior posição encontrada.
|
|
234
225
|
*/
|
|
235
226
|
export async function getMaxStickerPackPosition(packId, connection = null) {
|
|
236
|
-
const rows = await executeQuery(
|
|
237
|
-
`SELECT MAX(position) AS max_position FROM ${TABLES.STICKER_PACK_ITEM} WHERE pack_id = ?`,
|
|
238
|
-
[packId],
|
|
239
|
-
connection,
|
|
240
|
-
);
|
|
227
|
+
const rows = await executeQuery(`SELECT MAX(position) AS max_position FROM ${TABLES.STICKER_PACK_ITEM} WHERE pack_id = ?`, [packId], connection);
|
|
241
228
|
|
|
242
229
|
const maxValue = rows?.[0]?.max_position;
|
|
243
230
|
return maxValue !== null && maxValue !== undefined ? Number(maxValue) : 0;
|
|
@@ -255,14 +242,7 @@ export async function createStickerPackItem(item, connection = null) {
|
|
|
255
242
|
`INSERT INTO ${TABLES.STICKER_PACK_ITEM}
|
|
256
243
|
(id, pack_id, sticker_id, position, emojis, accessibility_label)
|
|
257
244
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
258
|
-
[
|
|
259
|
-
item.id,
|
|
260
|
-
item.pack_id,
|
|
261
|
-
item.sticker_id,
|
|
262
|
-
item.position,
|
|
263
|
-
item.emojis ? JSON.stringify(item.emojis) : JSON.stringify([]),
|
|
264
|
-
item.accessibility_label ?? null,
|
|
265
|
-
],
|
|
245
|
+
[item.id, item.pack_id, item.sticker_id, item.position, item.emojis ? JSON.stringify(item.emojis) : JSON.stringify([]), item.accessibility_label ?? null],
|
|
266
246
|
connection,
|
|
267
247
|
);
|
|
268
248
|
|
|
@@ -445,13 +425,7 @@ export async function cloneStickerPackItems(sourcePackId, targetPackId, connecti
|
|
|
445
425
|
`INSERT INTO ${TABLES.STICKER_PACK_ITEM}
|
|
446
426
|
(id, pack_id, sticker_id, position, emojis, accessibility_label)
|
|
447
427
|
VALUES (UUID(), ?, ?, ?, ?, ?)`,
|
|
448
|
-
[
|
|
449
|
-
targetPackId,
|
|
450
|
-
item.sticker_id,
|
|
451
|
-
item.position,
|
|
452
|
-
item.emojis ? JSON.stringify(item.emojis) : JSON.stringify([]),
|
|
453
|
-
item.accessibility_label ?? null,
|
|
454
|
-
],
|
|
428
|
+
[targetPackId, item.sticker_id, item.position, item.emojis ? JSON.stringify(item.emojis) : JSON.stringify([]), item.accessibility_label ?? null],
|
|
455
429
|
connection,
|
|
456
430
|
);
|
|
457
431
|
}
|