@adatechnology/meta-whatsapp-module 0.2.0-rc.7 → 0.2.0-rc.9
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/dist/index.cjs +35 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -2
- package/dist/index.d.ts +59 -2
- package/dist/index.js +35 -5
- package/dist/index.js.map +1 -1
- package/dist/migrations/0005_message_moderation.sql +3 -0
- package/dist/migrations/meta/_journal.json +8 -1
- package/dist/testing/index.cjs +72 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +34 -0
- package/dist/testing/index.d.ts +34 -0
- package/dist/testing/index.js +40 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +15 -3
package/dist/index.cjs
CHANGED
|
@@ -162,6 +162,12 @@ var messages = metaWhatsAppSchema.table("messages", {
|
|
|
162
162
|
readAt: (0, import_pg_core.timestamp)("read_at", {
|
|
163
163
|
withTimezone: true
|
|
164
164
|
}),
|
|
165
|
+
// Moderação de conteúdo. `null` significa NÃO AVALIADO (moderação desligada, ou mensagem
|
|
166
|
+
// anterior ao recurso) — diferente de `false`, que é avaliado e limpo. Colunas em vez de chave
|
|
167
|
+
// dentro de `payload` porque "listar o que foi sinalizado" é consulta de operação, e índice
|
|
168
|
+
// parcial sobre boolean resolve isso sem cavar jsonb.
|
|
169
|
+
moderationFlagged: (0, import_pg_core.boolean)("moderation_flagged"),
|
|
170
|
+
moderationTerms: (0, import_pg_core.jsonb)("moderation_terms").$type(),
|
|
165
171
|
createdAt: (0, import_pg_core.timestamp)("created_at", {
|
|
166
172
|
withTimezone: true
|
|
167
173
|
}).notNull().defaultNow()
|
|
@@ -173,7 +179,10 @@ var messages = metaWhatsAppSchema.table("messages", {
|
|
|
173
179
|
// paralelo, então as duas passariam pela checagem e inseririam duplicado. Parcial porque
|
|
174
180
|
// mensagens outbound ainda sem waMessageId (envio em curso) são legitimamente NULL, e NULLs
|
|
175
181
|
// não podem competir entre si por unicidade.
|
|
176
|
-
(0, import_pg_core.uniqueIndex)("idx_messages_company_wa_message_id").on(table.companyId, table.waMessageId).where(import_drizzle_orm.sql`${table.waMessageId} is not null`)
|
|
182
|
+
(0, import_pg_core.uniqueIndex)("idx_messages_company_wa_message_id").on(table.companyId, table.waMessageId).where(import_drizzle_orm.sql`${table.waMessageId} is not null`),
|
|
183
|
+
// Parcial: só as sinalizadas entram, então o índice fica do tamanho do problema e não do
|
|
184
|
+
// tamanho do transcript.
|
|
185
|
+
(0, import_pg_core.index)("idx_messages_moderation_flagged").on(table.companyId, table.createdAt).where(import_drizzle_orm.sql`${table.moderationFlagged}`)
|
|
177
186
|
]);
|
|
178
187
|
var flowGraphs = metaWhatsAppSchema.table("flow_graphs", {
|
|
179
188
|
id: (0, import_pg_core.uuid)("id").primaryKey().defaultRandom(),
|
|
@@ -427,7 +436,9 @@ var MessageRepository = class {
|
|
|
427
436
|
content: params.content ?? null,
|
|
428
437
|
payload: params.payload ?? null,
|
|
429
438
|
waMessageId: params.waMessageId ?? null,
|
|
430
|
-
status: params.status ?? null
|
|
439
|
+
status: params.status ?? null,
|
|
440
|
+
moderationFlagged: params.moderationFlagged ?? null,
|
|
441
|
+
moderationTerms: params.moderationTerms ?? null
|
|
431
442
|
};
|
|
432
443
|
const [created] = await this.db.insert(messages).values(values).onConflictDoNothing().returning();
|
|
433
444
|
return created;
|
|
@@ -643,16 +654,19 @@ var LogMessageUseCase = class {
|
|
|
643
654
|
sessionRepository;
|
|
644
655
|
messageRepository;
|
|
645
656
|
realtime;
|
|
646
|
-
|
|
657
|
+
moderator;
|
|
658
|
+
constructor(sessionRepository, messageRepository, realtime, moderator) {
|
|
647
659
|
this.sessionRepository = sessionRepository;
|
|
648
660
|
this.messageRepository = messageRepository;
|
|
649
661
|
this.realtime = realtime;
|
|
662
|
+
this.moderator = moderator;
|
|
650
663
|
}
|
|
651
664
|
async execute(params) {
|
|
652
665
|
const session = await this.sessionRepository.getOrCreate(params.companyId, params.whatsappNumber, params.startState);
|
|
653
666
|
const saved = await this.messageRepository.insertMessage({
|
|
654
667
|
...params,
|
|
655
|
-
sessionId: session.id
|
|
668
|
+
sessionId: session.id,
|
|
669
|
+
...this.moderationOf(params)
|
|
656
670
|
});
|
|
657
671
|
if (!saved) return void 0;
|
|
658
672
|
if (params.direction === "inbound") {
|
|
@@ -665,6 +679,20 @@ var LogMessageUseCase = class {
|
|
|
665
679
|
this.realtime?.emit("global", "data-changed", {});
|
|
666
680
|
return saved;
|
|
667
681
|
}
|
|
682
|
+
// Só o que o cliente escreveu: marcar o que o próprio atendente ou o bot enviou não sinaliza
|
|
683
|
+
// abuso, apenas sujaria o transcript com etiqueta na resposta de quem atende.
|
|
684
|
+
moderationOf(params) {
|
|
685
|
+
if (!this.moderator || params.direction !== "inbound") return {};
|
|
686
|
+
const text2 = params.content?.trim();
|
|
687
|
+
if (!text2) return {};
|
|
688
|
+
const verdict = this.moderator.inspect(text2);
|
|
689
|
+
return {
|
|
690
|
+
moderationFlagged: verdict.isOffensive,
|
|
691
|
+
moderationTerms: verdict.isOffensive ? [
|
|
692
|
+
...verdict.matchedTerms
|
|
693
|
+
] : null
|
|
694
|
+
};
|
|
695
|
+
}
|
|
668
696
|
};
|
|
669
697
|
|
|
670
698
|
// src/use-cases/SendMessage.use-case.ts
|
|
@@ -1206,6 +1234,8 @@ function toSessionContract(row) {
|
|
|
1206
1234
|
companyId: row.companyId,
|
|
1207
1235
|
whatsappNumber: row.whatsappNumber,
|
|
1208
1236
|
currentState: row.currentState,
|
|
1237
|
+
flowKey: row.flowKey,
|
|
1238
|
+
currentNodeId: row.currentNodeId,
|
|
1209
1239
|
context: row.context,
|
|
1210
1240
|
mode: row.mode,
|
|
1211
1241
|
assignedUserId: row.assignedUserId,
|
|
@@ -1416,7 +1446,7 @@ function createMetaWhatsAppModule(params) {
|
|
|
1416
1446
|
const messageRepository = new MessageRepository(db);
|
|
1417
1447
|
const settingsRepository = new SettingsRepository(db);
|
|
1418
1448
|
const flowGraphRepository = new FlowGraphRepository(db);
|
|
1419
|
-
const logMessage = new LogMessageUseCase(sessionRepository, messageRepository, providers.realtime);
|
|
1449
|
+
const logMessage = new LogMessageUseCase(sessionRepository, messageRepository, providers.realtime, providers.moderator);
|
|
1420
1450
|
const sendMessage = new SendMessageUseCase(channel, sessionRepository, logMessage, providers.objectStorage);
|
|
1421
1451
|
const receiveWebhook = new ReceiveWebhookUseCase({
|
|
1422
1452
|
appSecret: config.appSecret,
|