@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.d.cts CHANGED
@@ -524,6 +524,42 @@ declare const messages: drizzle_orm_pg_core.PgTableWithColumns<{
524
524
  identity: undefined;
525
525
  generated: undefined;
526
526
  }, {}, {}>;
527
+ moderationFlagged: drizzle_orm_pg_core.PgColumn<{
528
+ name: "moderation_flagged";
529
+ tableName: "messages";
530
+ dataType: "boolean";
531
+ columnType: "PgBoolean";
532
+ data: boolean;
533
+ driverParam: boolean;
534
+ notNull: false;
535
+ hasDefault: false;
536
+ isPrimaryKey: false;
537
+ isAutoincrement: false;
538
+ hasRuntimeDefault: false;
539
+ enumValues: undefined;
540
+ baseColumn: never;
541
+ identity: undefined;
542
+ generated: undefined;
543
+ }, {}, {}>;
544
+ moderationTerms: drizzle_orm_pg_core.PgColumn<{
545
+ name: "moderation_terms";
546
+ tableName: "messages";
547
+ dataType: "json";
548
+ columnType: "PgJsonb";
549
+ data: string[];
550
+ driverParam: unknown;
551
+ notNull: false;
552
+ hasDefault: false;
553
+ isPrimaryKey: false;
554
+ isAutoincrement: false;
555
+ hasRuntimeDefault: false;
556
+ enumValues: undefined;
557
+ baseColumn: never;
558
+ identity: undefined;
559
+ generated: undefined;
560
+ }, {}, {
561
+ $type: string[];
562
+ }>;
527
563
  createdAt: drizzle_orm_pg_core.PgColumn<{
528
564
  name: "created_at";
529
565
  tableName: "messages";
@@ -960,6 +996,8 @@ declare class SessionRepository {
960
996
  waMessageId: string | null;
961
997
  status: string | null;
962
998
  readAt: Date | null;
999
+ moderationFlagged: boolean | null;
1000
+ moderationTerms: string[] | null;
963
1001
  createdAt: Date;
964
1002
  }[];
965
1003
  } | null>;
@@ -1007,6 +1045,9 @@ interface InsertMessageParams {
1007
1045
  payload?: Record<string, unknown> | null;
1008
1046
  waMessageId?: string | null;
1009
1047
  status?: MessageStatus | null;
1048
+ /** `undefined` deixa a coluna nula: não avaliado, distinto de avaliado e limpo. */
1049
+ moderationFlagged?: boolean | null;
1050
+ moderationTerms?: string[] | null;
1010
1051
  }
1011
1052
  interface ListMessagesParams$1 {
1012
1053
  companyId: string;
@@ -1025,12 +1066,27 @@ declare class MessageRepository {
1025
1066
  type LogMessageParams = Omit<InsertMessageParams, 'sessionId'> & {
1026
1067
  startState: SessionState;
1027
1068
  };
1069
+ /**
1070
+ * O contrato mínimo de `@adatechnology/text-moderation`, declarado aqui em vez de importado.
1071
+ *
1072
+ * Assim o módulo não ganha dependência de pacote para um recurso opcional, e — mais importante —
1073
+ * moderação não fica amarrada a WhatsApp: o que atravessa esta fronteira é texto, e qualquer canal
1074
+ * que passe a escrever no transcript por este use case herda a marcação sem tocar nada aqui.
1075
+ */
1076
+ type MessageModerator = {
1077
+ inspect: (text: string) => {
1078
+ isOffensive: boolean;
1079
+ matchedTerms: readonly string[];
1080
+ };
1081
+ };
1028
1082
  declare class LogMessageUseCase {
1029
1083
  private readonly sessionRepository;
1030
1084
  private readonly messageRepository;
1031
1085
  private readonly realtime?;
1032
- constructor(sessionRepository: SessionRepository, messageRepository: MessageRepository, realtime?: RealtimeNotifierInterface | undefined);
1086
+ private readonly moderator?;
1087
+ constructor(sessionRepository: SessionRepository, messageRepository: MessageRepository, realtime?: RealtimeNotifierInterface | undefined, moderator?: MessageModerator | undefined);
1033
1088
  execute(params: LogMessageParams): Promise<MessageRow | undefined>;
1089
+ private moderationOf;
1034
1090
  }
1035
1091
 
1036
1092
  type SendTextParams = {
@@ -1330,6 +1386,7 @@ interface MetaWhatsAppModuleProviders {
1330
1386
  realtime?: RealtimeNotifierInterface;
1331
1387
  subjectResolver?: SubjectResolverInterface;
1332
1388
  catalog?: CatalogPort;
1389
+ moderator?: MessageModerator;
1333
1390
  }
1334
1391
  interface CreateMetaWhatsAppModuleParams {
1335
1392
  db: MetaWhatsAppDatabase;
@@ -1455,4 +1512,4 @@ declare function redeemSseTicket(store: TicketStoreInterface, ticket: string): P
1455
1512
  whatsappNumber: string;
1456
1513
  } | null>;
1457
1514
 
1458
- export { type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, DeleteFlowGraphUseCase, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewFlowGraphRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, extractMediaDescriptor, flowGraphs, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
1515
+ export { type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, DeleteFlowGraphUseCase, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, type MessageModerator, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewFlowGraphRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, extractMediaDescriptor, flowGraphs, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
package/dist/index.d.ts CHANGED
@@ -524,6 +524,42 @@ declare const messages: drizzle_orm_pg_core.PgTableWithColumns<{
524
524
  identity: undefined;
525
525
  generated: undefined;
526
526
  }, {}, {}>;
527
+ moderationFlagged: drizzle_orm_pg_core.PgColumn<{
528
+ name: "moderation_flagged";
529
+ tableName: "messages";
530
+ dataType: "boolean";
531
+ columnType: "PgBoolean";
532
+ data: boolean;
533
+ driverParam: boolean;
534
+ notNull: false;
535
+ hasDefault: false;
536
+ isPrimaryKey: false;
537
+ isAutoincrement: false;
538
+ hasRuntimeDefault: false;
539
+ enumValues: undefined;
540
+ baseColumn: never;
541
+ identity: undefined;
542
+ generated: undefined;
543
+ }, {}, {}>;
544
+ moderationTerms: drizzle_orm_pg_core.PgColumn<{
545
+ name: "moderation_terms";
546
+ tableName: "messages";
547
+ dataType: "json";
548
+ columnType: "PgJsonb";
549
+ data: string[];
550
+ driverParam: unknown;
551
+ notNull: false;
552
+ hasDefault: false;
553
+ isPrimaryKey: false;
554
+ isAutoincrement: false;
555
+ hasRuntimeDefault: false;
556
+ enumValues: undefined;
557
+ baseColumn: never;
558
+ identity: undefined;
559
+ generated: undefined;
560
+ }, {}, {
561
+ $type: string[];
562
+ }>;
527
563
  createdAt: drizzle_orm_pg_core.PgColumn<{
528
564
  name: "created_at";
529
565
  tableName: "messages";
@@ -960,6 +996,8 @@ declare class SessionRepository {
960
996
  waMessageId: string | null;
961
997
  status: string | null;
962
998
  readAt: Date | null;
999
+ moderationFlagged: boolean | null;
1000
+ moderationTerms: string[] | null;
963
1001
  createdAt: Date;
964
1002
  }[];
965
1003
  } | null>;
@@ -1007,6 +1045,9 @@ interface InsertMessageParams {
1007
1045
  payload?: Record<string, unknown> | null;
1008
1046
  waMessageId?: string | null;
1009
1047
  status?: MessageStatus | null;
1048
+ /** `undefined` deixa a coluna nula: não avaliado, distinto de avaliado e limpo. */
1049
+ moderationFlagged?: boolean | null;
1050
+ moderationTerms?: string[] | null;
1010
1051
  }
1011
1052
  interface ListMessagesParams$1 {
1012
1053
  companyId: string;
@@ -1025,12 +1066,27 @@ declare class MessageRepository {
1025
1066
  type LogMessageParams = Omit<InsertMessageParams, 'sessionId'> & {
1026
1067
  startState: SessionState;
1027
1068
  };
1069
+ /**
1070
+ * O contrato mínimo de `@adatechnology/text-moderation`, declarado aqui em vez de importado.
1071
+ *
1072
+ * Assim o módulo não ganha dependência de pacote para um recurso opcional, e — mais importante —
1073
+ * moderação não fica amarrada a WhatsApp: o que atravessa esta fronteira é texto, e qualquer canal
1074
+ * que passe a escrever no transcript por este use case herda a marcação sem tocar nada aqui.
1075
+ */
1076
+ type MessageModerator = {
1077
+ inspect: (text: string) => {
1078
+ isOffensive: boolean;
1079
+ matchedTerms: readonly string[];
1080
+ };
1081
+ };
1028
1082
  declare class LogMessageUseCase {
1029
1083
  private readonly sessionRepository;
1030
1084
  private readonly messageRepository;
1031
1085
  private readonly realtime?;
1032
- constructor(sessionRepository: SessionRepository, messageRepository: MessageRepository, realtime?: RealtimeNotifierInterface | undefined);
1086
+ private readonly moderator?;
1087
+ constructor(sessionRepository: SessionRepository, messageRepository: MessageRepository, realtime?: RealtimeNotifierInterface | undefined, moderator?: MessageModerator | undefined);
1033
1088
  execute(params: LogMessageParams): Promise<MessageRow | undefined>;
1089
+ private moderationOf;
1034
1090
  }
1035
1091
 
1036
1092
  type SendTextParams = {
@@ -1330,6 +1386,7 @@ interface MetaWhatsAppModuleProviders {
1330
1386
  realtime?: RealtimeNotifierInterface;
1331
1387
  subjectResolver?: SubjectResolverInterface;
1332
1388
  catalog?: CatalogPort;
1389
+ moderator?: MessageModerator;
1333
1390
  }
1334
1391
  interface CreateMetaWhatsAppModuleParams {
1335
1392
  db: MetaWhatsAppDatabase;
@@ -1455,4 +1512,4 @@ declare function redeemSseTicket(store: TicketStoreInterface, ticket: string): P
1455
1512
  whatsappNumber: string;
1456
1513
  } | null>;
1457
1514
 
1458
- export { type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, DeleteFlowGraphUseCase, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewFlowGraphRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, extractMediaDescriptor, flowGraphs, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
1515
+ export { type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, DeleteFlowGraphUseCase, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, ListFlowGraphsUseCase, type ListMessagesParams, ListMessagesUseCase, type LogMessageParams, LogMessageUseCase, META_WHATSAPP_MIGRATIONS_TABLE, type MessageModerator, MessageRepository, type MessageRow, type MetaWhatsAppDatabase, type MetaWhatsAppModule, type MetaWhatsAppModuleConfig, type MetaWhatsAppModuleFeatures, type MetaWhatsAppModuleProviders, type NewFlowGraphRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, extractMediaDescriptor, flowGraphs, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
package/dist/index.js CHANGED
@@ -106,6 +106,12 @@ var messages = metaWhatsAppSchema.table("messages", {
106
106
  readAt: timestamp("read_at", {
107
107
  withTimezone: true
108
108
  }),
109
+ // Moderação de conteúdo. `null` significa NÃO AVALIADO (moderação desligada, ou mensagem
110
+ // anterior ao recurso) — diferente de `false`, que é avaliado e limpo. Colunas em vez de chave
111
+ // dentro de `payload` porque "listar o que foi sinalizado" é consulta de operação, e índice
112
+ // parcial sobre boolean resolve isso sem cavar jsonb.
113
+ moderationFlagged: boolean("moderation_flagged"),
114
+ moderationTerms: jsonb("moderation_terms").$type(),
109
115
  createdAt: timestamp("created_at", {
110
116
  withTimezone: true
111
117
  }).notNull().defaultNow()
@@ -117,7 +123,10 @@ var messages = metaWhatsAppSchema.table("messages", {
117
123
  // paralelo, então as duas passariam pela checagem e inseririam duplicado. Parcial porque
118
124
  // mensagens outbound ainda sem waMessageId (envio em curso) são legitimamente NULL, e NULLs
119
125
  // não podem competir entre si por unicidade.
120
- uniqueIndex("idx_messages_company_wa_message_id").on(table.companyId, table.waMessageId).where(sql`${table.waMessageId} is not null`)
126
+ uniqueIndex("idx_messages_company_wa_message_id").on(table.companyId, table.waMessageId).where(sql`${table.waMessageId} is not null`),
127
+ // Parcial: só as sinalizadas entram, então o índice fica do tamanho do problema e não do
128
+ // tamanho do transcript.
129
+ index("idx_messages_moderation_flagged").on(table.companyId, table.createdAt).where(sql`${table.moderationFlagged}`)
121
130
  ]);
122
131
  var flowGraphs = metaWhatsAppSchema.table("flow_graphs", {
123
132
  id: uuid("id").primaryKey().defaultRandom(),
@@ -371,7 +380,9 @@ var MessageRepository = class {
371
380
  content: params.content ?? null,
372
381
  payload: params.payload ?? null,
373
382
  waMessageId: params.waMessageId ?? null,
374
- status: params.status ?? null
383
+ status: params.status ?? null,
384
+ moderationFlagged: params.moderationFlagged ?? null,
385
+ moderationTerms: params.moderationTerms ?? null
375
386
  };
376
387
  const [created] = await this.db.insert(messages).values(values).onConflictDoNothing().returning();
377
388
  return created;
@@ -587,16 +598,19 @@ var LogMessageUseCase = class {
587
598
  sessionRepository;
588
599
  messageRepository;
589
600
  realtime;
590
- constructor(sessionRepository, messageRepository, realtime) {
601
+ moderator;
602
+ constructor(sessionRepository, messageRepository, realtime, moderator) {
591
603
  this.sessionRepository = sessionRepository;
592
604
  this.messageRepository = messageRepository;
593
605
  this.realtime = realtime;
606
+ this.moderator = moderator;
594
607
  }
595
608
  async execute(params) {
596
609
  const session = await this.sessionRepository.getOrCreate(params.companyId, params.whatsappNumber, params.startState);
597
610
  const saved = await this.messageRepository.insertMessage({
598
611
  ...params,
599
- sessionId: session.id
612
+ sessionId: session.id,
613
+ ...this.moderationOf(params)
600
614
  });
601
615
  if (!saved) return void 0;
602
616
  if (params.direction === "inbound") {
@@ -609,6 +623,20 @@ var LogMessageUseCase = class {
609
623
  this.realtime?.emit("global", "data-changed", {});
610
624
  return saved;
611
625
  }
626
+ // Só o que o cliente escreveu: marcar o que o próprio atendente ou o bot enviou não sinaliza
627
+ // abuso, apenas sujaria o transcript com etiqueta na resposta de quem atende.
628
+ moderationOf(params) {
629
+ if (!this.moderator || params.direction !== "inbound") return {};
630
+ const text2 = params.content?.trim();
631
+ if (!text2) return {};
632
+ const verdict = this.moderator.inspect(text2);
633
+ return {
634
+ moderationFlagged: verdict.isOffensive,
635
+ moderationTerms: verdict.isOffensive ? [
636
+ ...verdict.matchedTerms
637
+ ] : null
638
+ };
639
+ }
612
640
  };
613
641
 
614
642
  // src/use-cases/SendMessage.use-case.ts
@@ -1150,6 +1178,8 @@ function toSessionContract(row) {
1150
1178
  companyId: row.companyId,
1151
1179
  whatsappNumber: row.whatsappNumber,
1152
1180
  currentState: row.currentState,
1181
+ flowKey: row.flowKey,
1182
+ currentNodeId: row.currentNodeId,
1153
1183
  context: row.context,
1154
1184
  mode: row.mode,
1155
1185
  assignedUserId: row.assignedUserId,
@@ -1360,7 +1390,7 @@ function createMetaWhatsAppModule(params) {
1360
1390
  const messageRepository = new MessageRepository(db);
1361
1391
  const settingsRepository = new SettingsRepository(db);
1362
1392
  const flowGraphRepository = new FlowGraphRepository(db);
1363
- const logMessage = new LogMessageUseCase(sessionRepository, messageRepository, providers.realtime);
1393
+ const logMessage = new LogMessageUseCase(sessionRepository, messageRepository, providers.realtime, providers.moderator);
1364
1394
  const sendMessage = new SendMessageUseCase(channel, sessionRepository, logMessage, providers.objectStorage);
1365
1395
  const receiveWebhook = new ReceiveWebhookUseCase({
1366
1396
  appSecret: config.appSecret,