@adatechnology/meta-whatsapp-module 0.2.0-rc.16 → 0.2.0-rc.18
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 +495 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +514 -34
- package/dist/index.d.ts +514 -34
- package/dist/index.js +472 -9
- package/dist/index.js.map +1 -1
- package/dist/migrations/0008_message_transcription.sql +5 -0
- package/dist/migrations/0009_settings_transcription_policy.sql +2 -0
- package/dist/migrations/meta/_journal.json +14 -0
- package/dist/testing/index.cjs +150 -0
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +42 -2
- package/dist/testing/index.d.ts +42 -2
- package/dist/testing/index.js +147 -1
- package/dist/testing/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
2
2
|
import { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
3
3
|
import * as _adatechnology_meta_whatsapp_contracts from '@adatechnology/meta-whatsapp-contracts';
|
|
4
|
-
import { SessionState, SessionMode, ConversationSummary,
|
|
4
|
+
import { TranscriptionMode, SessionState, SessionMode, ConversationSummary, MessageDirection, MessageSender, MessageStatus, CacheInterface, FlowGraphData, FlowGraphSummary, LiveFlowPosition, WhatsAppSettings, RealtimeNotifierInterface, ChannelAdapterInterface, ObjectStorageInterface, FlowActionKind, FlowActionHandler, ConversationSession, MetaWhatsAppHooks, SubjectResolverInterface, CatalogPort } from '@adatechnology/meta-whatsapp-contracts';
|
|
5
|
+
export { PREVIEW_MEDIA_ID_PREFIX, TranscriptionMode, resolvePreviewUploadId, toPreviewMediaId } from '@adatechnology/meta-whatsapp-contracts';
|
|
5
6
|
import { WhatsAppMessageProvider } from '@adatechnology/meta-whatsapp-provider';
|
|
6
7
|
|
|
7
8
|
type MetaWhatsAppDatabase = PgDatabase<PgQueryResultHKT, any, any>;
|
|
@@ -10,6 +11,72 @@ type DrizzleMigrateFunction = (db: never, config: {
|
|
|
10
11
|
migrationsTable?: string;
|
|
11
12
|
}) => Promise<void>;
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Vocabulário de transcrição de áudio do módulo.
|
|
16
|
+
*
|
|
17
|
+
* Fica em arquivo próprio porque o schema e os dois use-cases (ingestão automática e sob demanda)
|
|
18
|
+
* precisam dos mesmos tipos, e pendurá-los em qualquer um dos três faria os outros dois importarem
|
|
19
|
+
* de dentro de uma camada que não é a deles.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
declare const TRANSCRIPTION_STATUS: {
|
|
23
|
+
/** Falhou de forma retriável (cota, rede, 5xx) — vai sair quando alguém tentar de novo. */
|
|
24
|
+
readonly PENDING: "pending";
|
|
25
|
+
/** Processado. Texto vazio aqui é áudio em silêncio, e NÃO deve ser reprocessado. */
|
|
26
|
+
readonly DONE: "done";
|
|
27
|
+
/** Falha definitiva do engine (credencial, áudio corrompido, arquivo grande demais). */
|
|
28
|
+
readonly FAILED: "failed";
|
|
29
|
+
/** Nenhum engine da cadeia aceita o formato. Retentar não conserta codec. */
|
|
30
|
+
readonly UNSUPPORTED: "unsupported";
|
|
31
|
+
};
|
|
32
|
+
type TranscriptionStatus = (typeof TRANSCRIPTION_STATUS)[keyof typeof TRANSCRIPTION_STATUS];
|
|
33
|
+
/**
|
|
34
|
+
* Quando transcrever.
|
|
35
|
+
*
|
|
36
|
+
* `auto` transcreve durante a ingestão da mídia, onde o buffer do áudio JÁ está em memória — não
|
|
37
|
+
* custa um segundo download do storage. `onDemand` só transcreve quando o atendente pede, o que
|
|
38
|
+
* troca latência na interface por não gastar cota com áudio que ninguém vai ler.
|
|
39
|
+
*
|
|
40
|
+
* O tipo vem do contrato (o painel escolhe, a API transporta, o módulo obedece) e `satisfies`
|
|
41
|
+
* garante em tempo de compilação que estes valores continuam sendo exatamente os de lá — sem isso,
|
|
42
|
+
* um modo novo no contrato passaria despercebido aqui.
|
|
43
|
+
*/
|
|
44
|
+
declare const TRANSCRIPTION_MODE: {
|
|
45
|
+
readonly AUTO: "auto";
|
|
46
|
+
readonly ON_DEMAND: "onDemand";
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* O contrato mínimo de `@adatechnology/audio-transcription-provider`, declarado aqui em vez de
|
|
51
|
+
* importado — mesma decisão do `MessageModerator` em `LogMessage.use-case.ts`.
|
|
52
|
+
*
|
|
53
|
+
* Assim o módulo não ganha dependência de pacote por um recurso opcional, e transcrição não fica
|
|
54
|
+
* amarrada a WhatsApp: o que atravessa esta fronteira é um buffer de áudio e um mime.
|
|
55
|
+
*/
|
|
56
|
+
type AudioTranscriber = {
|
|
57
|
+
readonly name: string;
|
|
58
|
+
transcribe: (input: {
|
|
59
|
+
buffer: Buffer;
|
|
60
|
+
mimeType: string;
|
|
61
|
+
languageHint?: string;
|
|
62
|
+
}) => Promise<{
|
|
63
|
+
text: string;
|
|
64
|
+
language?: string;
|
|
65
|
+
durationSeconds?: number;
|
|
66
|
+
engine: string;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Recorte do erro do provider que o módulo precisa ler para escolher entre `'pending'` e
|
|
71
|
+
* `'failed'`. Estrutural, não `instanceof`: o provider é opcional e pode nem estar instalado, e um
|
|
72
|
+
* `instanceof` contra classe ausente não compila.
|
|
73
|
+
*/
|
|
74
|
+
declare function isRetriableTranscriptionError(error: unknown): boolean;
|
|
75
|
+
declare function isUnsupportedTranscriptionError(error: unknown): boolean;
|
|
76
|
+
declare function transcriptionRetryAfterSeconds(error: unknown): number | undefined;
|
|
77
|
+
/** Mime de áudio? Só áudio é transcrito — vídeo, imagem e documento passam sem tocar no engine. */
|
|
78
|
+
declare function isAudioMimeType(mimeType: string | undefined | null): boolean;
|
|
79
|
+
|
|
13
80
|
declare const metaWhatsAppSchema: drizzle_orm_pg_core.PgSchema<"meta_whatsapp">;
|
|
14
81
|
declare const sessions: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
15
82
|
name: "sessions";
|
|
@@ -560,6 +627,81 @@ declare const messages: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
560
627
|
}, {}, {
|
|
561
628
|
$type: string[];
|
|
562
629
|
}>;
|
|
630
|
+
transcriptionStatus: drizzle_orm_pg_core.PgColumn<{
|
|
631
|
+
name: "transcription_status";
|
|
632
|
+
tableName: "messages";
|
|
633
|
+
dataType: "string";
|
|
634
|
+
columnType: "PgVarchar";
|
|
635
|
+
data: TranscriptionStatus;
|
|
636
|
+
driverParam: string;
|
|
637
|
+
notNull: false;
|
|
638
|
+
hasDefault: false;
|
|
639
|
+
isPrimaryKey: false;
|
|
640
|
+
isAutoincrement: false;
|
|
641
|
+
hasRuntimeDefault: false;
|
|
642
|
+
enumValues: [string, ...string[]];
|
|
643
|
+
baseColumn: never;
|
|
644
|
+
identity: undefined;
|
|
645
|
+
generated: undefined;
|
|
646
|
+
}, {}, {
|
|
647
|
+
length: 16;
|
|
648
|
+
$type: TranscriptionStatus;
|
|
649
|
+
}>;
|
|
650
|
+
transcriptionText: drizzle_orm_pg_core.PgColumn<{
|
|
651
|
+
name: "transcription_text";
|
|
652
|
+
tableName: "messages";
|
|
653
|
+
dataType: "string";
|
|
654
|
+
columnType: "PgText";
|
|
655
|
+
data: string;
|
|
656
|
+
driverParam: string;
|
|
657
|
+
notNull: false;
|
|
658
|
+
hasDefault: false;
|
|
659
|
+
isPrimaryKey: false;
|
|
660
|
+
isAutoincrement: false;
|
|
661
|
+
hasRuntimeDefault: false;
|
|
662
|
+
enumValues: [string, ...string[]];
|
|
663
|
+
baseColumn: never;
|
|
664
|
+
identity: undefined;
|
|
665
|
+
generated: undefined;
|
|
666
|
+
}, {}, {}>;
|
|
667
|
+
transcriptionLanguage: drizzle_orm_pg_core.PgColumn<{
|
|
668
|
+
name: "transcription_language";
|
|
669
|
+
tableName: "messages";
|
|
670
|
+
dataType: "string";
|
|
671
|
+
columnType: "PgVarchar";
|
|
672
|
+
data: string;
|
|
673
|
+
driverParam: string;
|
|
674
|
+
notNull: false;
|
|
675
|
+
hasDefault: false;
|
|
676
|
+
isPrimaryKey: false;
|
|
677
|
+
isAutoincrement: false;
|
|
678
|
+
hasRuntimeDefault: false;
|
|
679
|
+
enumValues: [string, ...string[]];
|
|
680
|
+
baseColumn: never;
|
|
681
|
+
identity: undefined;
|
|
682
|
+
generated: undefined;
|
|
683
|
+
}, {}, {
|
|
684
|
+
length: 32;
|
|
685
|
+
}>;
|
|
686
|
+
transcriptionEngine: drizzle_orm_pg_core.PgColumn<{
|
|
687
|
+
name: "transcription_engine";
|
|
688
|
+
tableName: "messages";
|
|
689
|
+
dataType: "string";
|
|
690
|
+
columnType: "PgVarchar";
|
|
691
|
+
data: string;
|
|
692
|
+
driverParam: string;
|
|
693
|
+
notNull: false;
|
|
694
|
+
hasDefault: false;
|
|
695
|
+
isPrimaryKey: false;
|
|
696
|
+
isAutoincrement: false;
|
|
697
|
+
hasRuntimeDefault: false;
|
|
698
|
+
enumValues: [string, ...string[]];
|
|
699
|
+
baseColumn: never;
|
|
700
|
+
identity: undefined;
|
|
701
|
+
generated: undefined;
|
|
702
|
+
}, {}, {
|
|
703
|
+
length: 32;
|
|
704
|
+
}>;
|
|
563
705
|
createdAt: drizzle_orm_pg_core.PgColumn<{
|
|
564
706
|
name: "created_at";
|
|
565
707
|
tableName: "messages";
|
|
@@ -1363,6 +1505,43 @@ declare const settings: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1363
1505
|
identity: undefined;
|
|
1364
1506
|
generated: undefined;
|
|
1365
1507
|
}, {}, {}>;
|
|
1508
|
+
transcriptionEnabled: drizzle_orm_pg_core.PgColumn<{
|
|
1509
|
+
name: "transcription_enabled";
|
|
1510
|
+
tableName: "settings";
|
|
1511
|
+
dataType: "boolean";
|
|
1512
|
+
columnType: "PgBoolean";
|
|
1513
|
+
data: boolean;
|
|
1514
|
+
driverParam: boolean;
|
|
1515
|
+
notNull: false;
|
|
1516
|
+
hasDefault: false;
|
|
1517
|
+
isPrimaryKey: false;
|
|
1518
|
+
isAutoincrement: false;
|
|
1519
|
+
hasRuntimeDefault: false;
|
|
1520
|
+
enumValues: undefined;
|
|
1521
|
+
baseColumn: never;
|
|
1522
|
+
identity: undefined;
|
|
1523
|
+
generated: undefined;
|
|
1524
|
+
}, {}, {}>;
|
|
1525
|
+
transcriptionMode: drizzle_orm_pg_core.PgColumn<{
|
|
1526
|
+
name: "transcription_mode";
|
|
1527
|
+
tableName: "settings";
|
|
1528
|
+
dataType: "string";
|
|
1529
|
+
columnType: "PgVarchar";
|
|
1530
|
+
data: TranscriptionMode;
|
|
1531
|
+
driverParam: string;
|
|
1532
|
+
notNull: false;
|
|
1533
|
+
hasDefault: false;
|
|
1534
|
+
isPrimaryKey: false;
|
|
1535
|
+
isAutoincrement: false;
|
|
1536
|
+
hasRuntimeDefault: false;
|
|
1537
|
+
enumValues: [string, ...string[]];
|
|
1538
|
+
baseColumn: never;
|
|
1539
|
+
identity: undefined;
|
|
1540
|
+
generated: undefined;
|
|
1541
|
+
}, {}, {
|
|
1542
|
+
length: 16;
|
|
1543
|
+
$type: TranscriptionMode;
|
|
1544
|
+
}>;
|
|
1366
1545
|
createdAt: drizzle_orm_pg_core.PgColumn<{
|
|
1367
1546
|
name: "created_at";
|
|
1368
1547
|
tableName: "settings";
|
|
@@ -1479,11 +1658,83 @@ declare class SessionRepository {
|
|
|
1479
1658
|
readAt: Date | null;
|
|
1480
1659
|
moderationFlagged: boolean | null;
|
|
1481
1660
|
moderationTerms: string[] | null;
|
|
1661
|
+
transcriptionStatus: TranscriptionStatus | null;
|
|
1662
|
+
transcriptionText: string | null;
|
|
1663
|
+
transcriptionLanguage: string | null;
|
|
1664
|
+
transcriptionEngine: string | null;
|
|
1482
1665
|
createdAt: Date;
|
|
1483
1666
|
}[];
|
|
1484
1667
|
} | null>;
|
|
1485
1668
|
}
|
|
1486
1669
|
|
|
1670
|
+
interface InsertMessageParams {
|
|
1671
|
+
companyId: string;
|
|
1672
|
+
sessionId: string;
|
|
1673
|
+
whatsappNumber: string;
|
|
1674
|
+
direction: MessageDirection;
|
|
1675
|
+
sender: MessageSender;
|
|
1676
|
+
agentUserId?: string | null;
|
|
1677
|
+
type: string;
|
|
1678
|
+
content?: string | null;
|
|
1679
|
+
payload?: Record<string, unknown> | null;
|
|
1680
|
+
waMessageId?: string | null;
|
|
1681
|
+
status?: MessageStatus | null;
|
|
1682
|
+
/** `undefined` deixa a coluna nula: não avaliado, distinto de avaliado e limpo. */
|
|
1683
|
+
moderationFlagged?: boolean | null;
|
|
1684
|
+
moderationTerms?: string[] | null;
|
|
1685
|
+
}
|
|
1686
|
+
interface ListMessagesParams$1 {
|
|
1687
|
+
companyId: string;
|
|
1688
|
+
sessionId: string;
|
|
1689
|
+
limit?: number;
|
|
1690
|
+
before?: string;
|
|
1691
|
+
}
|
|
1692
|
+
interface SaveTranscriptionByWaMessageIdParams extends Omit<SaveTranscriptionParams, 'messageId'> {
|
|
1693
|
+
/**
|
|
1694
|
+
* Id da mensagem na Meta. É o único que quem processa o webhook conhece — o id do módulo só
|
|
1695
|
+
* existe depois da gravação, e obrigar o host a descobri-lo faria cada um escrever a própria
|
|
1696
|
+
* consulta por `wa_message_id`.
|
|
1697
|
+
*/
|
|
1698
|
+
waMessageId: string;
|
|
1699
|
+
}
|
|
1700
|
+
interface SaveTranscriptionParams {
|
|
1701
|
+
companyId: string;
|
|
1702
|
+
messageId: string;
|
|
1703
|
+
status: TranscriptionStatus;
|
|
1704
|
+
/** Ausente em `pending`/`failed`/`unsupported`; vazio em `done` é silêncio já processado. */
|
|
1705
|
+
text?: string | null;
|
|
1706
|
+
language?: string | null;
|
|
1707
|
+
engine?: string | null;
|
|
1708
|
+
}
|
|
1709
|
+
declare class MessageRepository {
|
|
1710
|
+
private readonly db;
|
|
1711
|
+
constructor(db: MetaWhatsAppDatabase);
|
|
1712
|
+
insertMessage(params: InsertMessageParams): Promise<MessageRow | undefined>;
|
|
1713
|
+
updateMessageStatus(companyId: string, waMessageId: string, status: MessageStatus): Promise<MessageRow | undefined>;
|
|
1714
|
+
/**
|
|
1715
|
+
* Grava a transcrição endereçando pelo id da Meta, para quem só tem esse.
|
|
1716
|
+
*
|
|
1717
|
+
* Serve ao caso em que a transcrição acontece no próprio webhook — o grafo precisa do texto para
|
|
1718
|
+
* responder ao cliente, e jogar fora o que ele já pagou para transcrever significaria transcrever
|
|
1719
|
+
* o mesmo áudio uma segunda vez só para o painel ver.
|
|
1720
|
+
*
|
|
1721
|
+
* Devolve `undefined` quando não achou a mensagem: entrega duplicada e mensagem apagada são
|
|
1722
|
+
* corridas normais, não erro.
|
|
1723
|
+
*/
|
|
1724
|
+
saveTranscriptionByWaMessageId(params: SaveTranscriptionByWaMessageIdParams): Promise<MessageRow | undefined>;
|
|
1725
|
+
findById(companyId: string, messageId: string): Promise<MessageRow | undefined>;
|
|
1726
|
+
/**
|
|
1727
|
+
* Grava o resultado da transcrição. Devolve `undefined` quando a mensagem não existe (apagada
|
|
1728
|
+
* entre o enfileiramento e a execução do job) — não é erro, é corrida normal.
|
|
1729
|
+
*
|
|
1730
|
+
* `text`/`language`/`engine` só são tocados quando informados: uma retentativa que volta a falhar
|
|
1731
|
+
* atualiza o status sem apagar a transcrição parcial de uma tentativa anterior que tenha vindo de
|
|
1732
|
+
* outro engine da cadeia.
|
|
1733
|
+
*/
|
|
1734
|
+
saveTranscription(params: SaveTranscriptionParams): Promise<MessageRow | undefined>;
|
|
1735
|
+
listByConversation(params: ListMessagesParams$1): Promise<MessageRow[]>;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1487
1738
|
declare const DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS = 300;
|
|
1488
1739
|
/**
|
|
1489
1740
|
* Cache de leitura dos grafos de fluxo, com invalidação na publicação.
|
|
@@ -1538,36 +1789,6 @@ declare class SettingsRepository {
|
|
|
1538
1789
|
resolveTemplateVariables(companyId: string, context: Record<string, unknown>): Promise<string[]>;
|
|
1539
1790
|
}
|
|
1540
1791
|
|
|
1541
|
-
interface InsertMessageParams {
|
|
1542
|
-
companyId: string;
|
|
1543
|
-
sessionId: string;
|
|
1544
|
-
whatsappNumber: string;
|
|
1545
|
-
direction: MessageDirection;
|
|
1546
|
-
sender: MessageSender;
|
|
1547
|
-
agentUserId?: string | null;
|
|
1548
|
-
type: string;
|
|
1549
|
-
content?: string | null;
|
|
1550
|
-
payload?: Record<string, unknown> | null;
|
|
1551
|
-
waMessageId?: string | null;
|
|
1552
|
-
status?: MessageStatus | null;
|
|
1553
|
-
/** `undefined` deixa a coluna nula: não avaliado, distinto de avaliado e limpo. */
|
|
1554
|
-
moderationFlagged?: boolean | null;
|
|
1555
|
-
moderationTerms?: string[] | null;
|
|
1556
|
-
}
|
|
1557
|
-
interface ListMessagesParams$1 {
|
|
1558
|
-
companyId: string;
|
|
1559
|
-
sessionId: string;
|
|
1560
|
-
limit?: number;
|
|
1561
|
-
before?: string;
|
|
1562
|
-
}
|
|
1563
|
-
declare class MessageRepository {
|
|
1564
|
-
private readonly db;
|
|
1565
|
-
constructor(db: MetaWhatsAppDatabase);
|
|
1566
|
-
insertMessage(params: InsertMessageParams): Promise<MessageRow | undefined>;
|
|
1567
|
-
updateMessageStatus(companyId: string, waMessageId: string, status: MessageStatus): Promise<MessageRow | undefined>;
|
|
1568
|
-
listByConversation(params: ListMessagesParams$1): Promise<MessageRow[]>;
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
1792
|
type LogMessageParams = Omit<InsertMessageParams, 'sessionId'> & {
|
|
1572
1793
|
startState: SessionState;
|
|
1573
1794
|
};
|
|
@@ -2133,6 +2354,39 @@ declare class ReceiveWebhookUseCase {
|
|
|
2133
2354
|
private handleStatus;
|
|
2134
2355
|
}
|
|
2135
2356
|
|
|
2357
|
+
/**
|
|
2358
|
+
* Política efetiva de transcrição de uma empresa.
|
|
2359
|
+
*
|
|
2360
|
+
* A separação que este arquivo existe para manter: **ambiente decide se é POSSÍVEL, settings decide
|
|
2361
|
+
* se é para FAZER.** A capacidade (engine, chave, storage que sabe reler) é injetada pelo host e é
|
|
2362
|
+
* por deploy — chave de API não vai para tabela de configuração de tenant. Já "transcrever ou não" e
|
|
2363
|
+
* "automático ou sob demanda" são decisão de operação de cada empresa, e pedir deploy para mudar
|
|
2364
|
+
* isso é o que transforma um interruptor em ticket.
|
|
2365
|
+
*/
|
|
2366
|
+
type TranscriptionPolicy = {
|
|
2367
|
+
readonly isEnabled: boolean;
|
|
2368
|
+
readonly mode: TranscriptionMode;
|
|
2369
|
+
};
|
|
2370
|
+
type TranscriptionPolicyDefaults = {
|
|
2371
|
+
/** O que vale quando o painel não decidiu. Tipicamente vem do ambiente do host. */
|
|
2372
|
+
readonly isEnabled: boolean;
|
|
2373
|
+
readonly mode: TranscriptionMode;
|
|
2374
|
+
};
|
|
2375
|
+
type ResolveTranscriptionPolicyDependencies = {
|
|
2376
|
+
readonly settingsRepository: SettingsRepository;
|
|
2377
|
+
readonly defaults: TranscriptionPolicyDefaults;
|
|
2378
|
+
};
|
|
2379
|
+
/**
|
|
2380
|
+
* Resolve a política por empresa, com o padrão do host como base.
|
|
2381
|
+
*
|
|
2382
|
+
* Uma consulta a `settings` por áudio transcrito. Não é cacheado de propósito: é uma leitura por
|
|
2383
|
+
* chave primária, acontece uma vez por nota de voz (não por mensagem), e cachear introduziria a
|
|
2384
|
+
* pergunta "por quanto tempo o operador continua vendo o interruptor antigo depois de mexer nele" —
|
|
2385
|
+
* custo real, para economizar um índice único.
|
|
2386
|
+
*/
|
|
2387
|
+
declare function createTranscriptionPolicyResolver(dependencies: ResolveTranscriptionPolicyDependencies): (companyId: string) => Promise<TranscriptionPolicy>;
|
|
2388
|
+
type TranscriptionPolicyResolver = ReturnType<typeof createTranscriptionPolicyResolver>;
|
|
2389
|
+
|
|
2136
2390
|
type IngestInboundMediaParams = {
|
|
2137
2391
|
companyId: string;
|
|
2138
2392
|
messageId: string;
|
|
@@ -2143,14 +2397,52 @@ type IngestInboundMediaParams = {
|
|
|
2143
2397
|
type IngestInboundMediaResult = {
|
|
2144
2398
|
uploadId: string;
|
|
2145
2399
|
alreadyIngested: boolean;
|
|
2400
|
+
/**
|
|
2401
|
+
* Só presente quando a transcrição automática rodou nesta execução. Ausente é o normal: mídia que
|
|
2402
|
+
* não é áudio, transcrição desligada, modo sob demanda, ou mídia já ingerida antes.
|
|
2403
|
+
*/
|
|
2404
|
+
transcription?: {
|
|
2405
|
+
status: TranscriptionStatus;
|
|
2406
|
+
};
|
|
2407
|
+
};
|
|
2408
|
+
/**
|
|
2409
|
+
* Transcrição durante a ingestão — o modo `auto`.
|
|
2410
|
+
*
|
|
2411
|
+
* Entra aqui, e não em use-case separado, por um motivo só: neste ponto o buffer do áudio ACABOU de
|
|
2412
|
+
* ser baixado e está em memória. Transcrever fora daqui custaria um segundo download do storage por
|
|
2413
|
+
* áudio, e o `TranscribeAudioUseCase` existe justamente para esse caso (sob demanda e retomada).
|
|
2414
|
+
*/
|
|
2415
|
+
type IngestTranscriptionOptions = {
|
|
2416
|
+
transcriber: AudioTranscriber;
|
|
2417
|
+
messageRepository: MessageRepository;
|
|
2418
|
+
/**
|
|
2419
|
+
* Política POR EMPRESA, resolvida a cada áudio. Não é um `mode` fixo porque o interruptor mora nas
|
|
2420
|
+
* configurações da empresa: um valor capturado na construção do use-case congelaria a escolha até
|
|
2421
|
+
* o próximo deploy, e o worker é um processo longo — o operador mexeria no painel e nada mudaria.
|
|
2422
|
+
*/
|
|
2423
|
+
resolvePolicy: TranscriptionPolicyResolver;
|
|
2424
|
+
languageHint?: string;
|
|
2425
|
+
hooks?: Pick<MetaWhatsAppHooks, 'onTranscriptionDeferred'>;
|
|
2146
2426
|
};
|
|
2147
2427
|
declare class IngestInboundMediaUseCase {
|
|
2148
2428
|
private readonly db;
|
|
2149
2429
|
private readonly channel;
|
|
2150
2430
|
private readonly objectStorage;
|
|
2151
2431
|
private readonly documentRepository?;
|
|
2152
|
-
|
|
2432
|
+
private readonly transcription?;
|
|
2433
|
+
constructor(db: MetaWhatsAppDatabase, channel: ChannelAdapterInterface, objectStorage: ObjectStorageInterface, documentRepository?: DocumentRepository | undefined, transcription?: IngestTranscriptionOptions | undefined);
|
|
2153
2434
|
execute(params: IngestInboundMediaParams): Promise<IngestInboundMediaResult>;
|
|
2435
|
+
/**
|
|
2436
|
+
* Transcreve o áudio recém-baixado, quando o modo é `auto`.
|
|
2437
|
+
*
|
|
2438
|
+
* **Nunca propaga erro.** Neste ponto o binário já está no storage e já entrou na biblioteca da
|
|
2439
|
+
* conversa: deixar uma falha de transcrição subir marcaria a ingestão inteira como falha, e o
|
|
2440
|
+
* retry do host baixaria de novo da Meta um arquivo que está salvo — gastando banda para reproduzir
|
|
2441
|
+
* um efeito que já aconteceu. O status fica gravado na mensagem e o `onTranscriptionDeferred`
|
|
2442
|
+
* avisa quem sabe reenfileirar.
|
|
2443
|
+
*/
|
|
2444
|
+
private transcribeIfAuto;
|
|
2445
|
+
private recordTranscriptionFailure;
|
|
2154
2446
|
}
|
|
2155
2447
|
declare function extractMediaDescriptor(message: MessageRow): {
|
|
2156
2448
|
sourceMediaId: string;
|
|
@@ -2158,6 +2450,105 @@ declare function extractMediaDescriptor(message: MessageRow): {
|
|
|
2158
2450
|
filename?: string;
|
|
2159
2451
|
} | undefined;
|
|
2160
2452
|
|
|
2453
|
+
/**
|
|
2454
|
+
* Storage com leitura garantida. `getObject` é opcional no contrato, então quem monta este use-case
|
|
2455
|
+
* precisa provar que o método existe — sem os bytes não há o que transcrever, e um use-case que
|
|
2456
|
+
* sempre falha é pior do que a ausência ser visível no tipo.
|
|
2457
|
+
*/
|
|
2458
|
+
type ReadableObjectStorage = ObjectStorageInterface & {
|
|
2459
|
+
getObject: NonNullable<ObjectStorageInterface['getObject']>;
|
|
2460
|
+
};
|
|
2461
|
+
type TranscribeAudioParams = {
|
|
2462
|
+
companyId: string;
|
|
2463
|
+
messageId: string;
|
|
2464
|
+
/**
|
|
2465
|
+
* Refaz mesmo com transcrição já salva. Serve ao "transcrever de novo" depois de trocar de engine
|
|
2466
|
+
* — sem isto, um resultado ruim do engine antigo ficaria congelado para sempre.
|
|
2467
|
+
*/
|
|
2468
|
+
force?: boolean;
|
|
2469
|
+
};
|
|
2470
|
+
type TranscribeAudioResult = {
|
|
2471
|
+
status: TranscriptionStatus;
|
|
2472
|
+
text: string | null;
|
|
2473
|
+
language: string | null;
|
|
2474
|
+
engine: string | null;
|
|
2475
|
+
/** `true` quando devolveu o que já estava salvo, sem gastar cota. */
|
|
2476
|
+
alreadyTranscribed: boolean;
|
|
2477
|
+
};
|
|
2478
|
+
type TranscribeAudioDependencies = {
|
|
2479
|
+
messageRepository: MessageRepository;
|
|
2480
|
+
objectStorage: ReadableObjectStorage;
|
|
2481
|
+
transcriber: AudioTranscriber;
|
|
2482
|
+
/**
|
|
2483
|
+
* Política por empresa. Ausente, a transcrição sob demanda não consulta configuração nenhuma e
|
|
2484
|
+
* atende sempre — que é o comportamento de quem controla o liga/desliga só por ambiente.
|
|
2485
|
+
*/
|
|
2486
|
+
resolvePolicy?: TranscriptionPolicyResolver;
|
|
2487
|
+
/** ISO 639-1 do produto. Informar corta a detecção do Whisper e evita pt-BR curto virar espanhol. */
|
|
2488
|
+
languageHint?: string;
|
|
2489
|
+
hooks?: Pick<MetaWhatsAppHooks, 'onTranscriptionDeferred'>;
|
|
2490
|
+
};
|
|
2491
|
+
/**
|
|
2492
|
+
* Transcreve o áudio de UMA mensagem já persistida e ingerida.
|
|
2493
|
+
*
|
|
2494
|
+
* Serve aos dois modos: é o que o painel chama no botão "transcrever" (`onDemand`) e é o que o host
|
|
2495
|
+
* chama ao retomar um `pending` reenfileirado. O modo `auto` não passa por aqui — ele transcreve
|
|
2496
|
+
* dentro da ingestão, onde o buffer já está em memória e não custa um segundo download.
|
|
2497
|
+
*
|
|
2498
|
+
* Idempotente por `transcription_status`: chamar de novo num `'done'` devolve o que está salvo em
|
|
2499
|
+
* vez de gastar cota transcrevendo o mesmo áudio.
|
|
2500
|
+
*/
|
|
2501
|
+
declare class TranscribeAudioUseCase {
|
|
2502
|
+
private readonly dependencies;
|
|
2503
|
+
constructor(dependencies: TranscribeAudioDependencies);
|
|
2504
|
+
execute(params: TranscribeAudioParams): Promise<TranscribeAudioResult>;
|
|
2505
|
+
private transcribeBuffer;
|
|
2506
|
+
/**
|
|
2507
|
+
* Carimba o motivo antes de propagar. O status é o que impede os dois desperdícios simétricos:
|
|
2508
|
+
* reprocessar para sempre um codec impossível, e desistir de um áudio que só esbarrou na cota.
|
|
2509
|
+
*/
|
|
2510
|
+
private persistFailure;
|
|
2511
|
+
}
|
|
2512
|
+
declare function resolveFailureStatus(error: unknown): TranscriptionStatus;
|
|
2513
|
+
|
|
2514
|
+
/**
|
|
2515
|
+
* Guarda um arquivo gravado no simulador e devolve o id que o webhook vai referenciar.
|
|
2516
|
+
*
|
|
2517
|
+
* Existe como use-case para o host só precisar da ROTA: receber o corpo, chamar isto, devolver o
|
|
2518
|
+
* `mediaId`. A parte que erra — onde gravar, com que chave, como marcar o id para o adaptador
|
|
2519
|
+
* reconhecer depois — fica aqui, num lugar só, e não em cada produto.
|
|
2520
|
+
*
|
|
2521
|
+
* O SDK para exatamente na porta do HTTP: registrar endpoint é do host, e um pacote que abrisse rota
|
|
2522
|
+
* no servidor de quem o instala decidiria caminho, autenticação e versionamento no lugar dele.
|
|
2523
|
+
*/
|
|
2524
|
+
type StorePreviewMediaParams = {
|
|
2525
|
+
companyId: string;
|
|
2526
|
+
/** Bytes do arquivo. Quem converte de base64 é a rota — o use-case não conhece transporte. */
|
|
2527
|
+
buffer: Buffer;
|
|
2528
|
+
mimeType: string;
|
|
2529
|
+
filename?: string;
|
|
2530
|
+
};
|
|
2531
|
+
type StorePreviewMediaResult = {
|
|
2532
|
+
/** Já com o prefixo: é isto que o simulador manda no webhook. */
|
|
2533
|
+
mediaId: string;
|
|
2534
|
+
uploadId: string;
|
|
2535
|
+
};
|
|
2536
|
+
declare class StorePreviewMediaUseCase {
|
|
2537
|
+
private readonly objectStorage;
|
|
2538
|
+
/**
|
|
2539
|
+
* Fonte do sufixo único da chave. Injetada porque o módulo não escolhe gerador de id — e porque
|
|
2540
|
+
* um teste precisa de chave previsível.
|
|
2541
|
+
*/
|
|
2542
|
+
private readonly generateKeySuffix;
|
|
2543
|
+
constructor(objectStorage: ObjectStorageInterface,
|
|
2544
|
+
/**
|
|
2545
|
+
* Fonte do sufixo único da chave. Injetada porque o módulo não escolhe gerador de id — e porque
|
|
2546
|
+
* um teste precisa de chave previsível.
|
|
2547
|
+
*/
|
|
2548
|
+
generateKeySuffix: () => string);
|
|
2549
|
+
execute(params: StorePreviewMediaParams): Promise<StorePreviewMediaResult>;
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2161
2552
|
interface MetaWhatsAppModuleConfig {
|
|
2162
2553
|
phoneNumberId: string;
|
|
2163
2554
|
accessToken: string;
|
|
@@ -2172,6 +2563,41 @@ interface MetaWhatsAppModuleFeatures {
|
|
|
2172
2563
|
flowGraphCache?: boolean | {
|
|
2173
2564
|
ttlSeconds?: number;
|
|
2174
2565
|
};
|
|
2566
|
+
/**
|
|
2567
|
+
* Aceita mídia do simulador de conversa — o que faz o microfone aparecer no preview do cliente.
|
|
2568
|
+
*
|
|
2569
|
+
* **Desligado por omissão, e a decisão é consciente.** Ligado, o canal passa a aceitar id que não
|
|
2570
|
+
* veio da Meta: `preview-upload:<chave>` faz o servidor ler aquele objeto do storage. Em ambiente
|
|
2571
|
+
* de simulação isso é o recurso; em produção é leitura arbitrária do bucket por webhook forjado.
|
|
2572
|
+
*
|
|
2573
|
+
* Exige `providers.objectStorage` com `getObject` — sem os bytes não há o que devolver, e o flag é
|
|
2574
|
+
* ignorado em vez de produzir um canal que falha na primeira nota de voz.
|
|
2575
|
+
*/
|
|
2576
|
+
previewMedia?: boolean;
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* Transcrição de áudio. Ausente = desligada, e as colunas ficam nulas ("não avaliado").
|
|
2580
|
+
*
|
|
2581
|
+
* `mode` é a decisão de produto que este objeto existe para carregar: `auto` transcreve toda nota de
|
|
2582
|
+
* voz recebida, na ingestão, onde o buffer já está em memória; `onDemand` só transcreve quando o
|
|
2583
|
+
* atendente pede, gastando cota apenas com áudio que alguém vai ler de fato.
|
|
2584
|
+
*/
|
|
2585
|
+
interface MetaWhatsAppTranscriptionConfig {
|
|
2586
|
+
transcriber: AudioTranscriber;
|
|
2587
|
+
/**
|
|
2588
|
+
* PADRÃO, não decisão final: vale para as empresas que não mexeram no interruptor do painel. As
|
|
2589
|
+
* configurações por empresa (`settings.transcriptionMode`) têm precedência.
|
|
2590
|
+
*
|
|
2591
|
+
* Padrão `onDemand` — o modo que não gasta cota sem alguém pedir.
|
|
2592
|
+
*/
|
|
2593
|
+
mode?: TranscriptionMode;
|
|
2594
|
+
/**
|
|
2595
|
+
* PADRÃO de ligado/desligado para empresas sem escolha registrada. `true` — injetar o transcritor
|
|
2596
|
+
* já é a declaração de que o host quer o recurso; quem controla por empresa usa o painel.
|
|
2597
|
+
*/
|
|
2598
|
+
isEnabledByDefault?: boolean;
|
|
2599
|
+
/** ISO 639-1 do produto (ex.: `'pt'`). Corta a detecção de idioma do engine. */
|
|
2600
|
+
languageHint?: string;
|
|
2175
2601
|
}
|
|
2176
2602
|
interface MetaWhatsAppModuleProviders {
|
|
2177
2603
|
objectStorage?: ObjectStorageInterface;
|
|
@@ -2180,6 +2606,11 @@ interface MetaWhatsAppModuleProviders {
|
|
|
2180
2606
|
subjectResolver?: SubjectResolverInterface;
|
|
2181
2607
|
catalog?: CatalogPort;
|
|
2182
2608
|
moderator?: MessageModerator;
|
|
2609
|
+
/**
|
|
2610
|
+
* Converte nota de voz em texto. Exige `objectStorage` com `getObject` para o modo sob demanda —
|
|
2611
|
+
* transcrever um áudio já salvo significa ler os bytes de volta.
|
|
2612
|
+
*/
|
|
2613
|
+
transcription?: MetaWhatsAppTranscriptionConfig;
|
|
2183
2614
|
}
|
|
2184
2615
|
interface CreateMetaWhatsAppModuleParams {
|
|
2185
2616
|
db: MetaWhatsAppDatabase;
|
|
@@ -2205,10 +2636,26 @@ declare function createMetaWhatsAppModule(params: CreateMetaWhatsAppModuleParams
|
|
|
2205
2636
|
delete: DeleteConversationUseCase;
|
|
2206
2637
|
purgeExpiredDocuments: PurgeExpiredDocumentsUseCase;
|
|
2207
2638
|
export: ExportConversationUseCase;
|
|
2639
|
+
transcribeAudio: TranscribeAudioUseCase | undefined;
|
|
2208
2640
|
repository: SessionRepository;
|
|
2641
|
+
messageRepository: MessageRepository;
|
|
2209
2642
|
documentRepository: DocumentRepository;
|
|
2210
2643
|
};
|
|
2644
|
+
/**
|
|
2645
|
+
* `undefined` = o host não injetou transcritor, e nenhuma configuração de empresa muda isso: a
|
|
2646
|
+
* capacidade não existe. Presente, `resolvePolicy` responde o que vale para uma empresa —
|
|
2647
|
+
* é o que a rota de configurações usa para dizer ao painel se desenha o interruptor.
|
|
2648
|
+
*/
|
|
2649
|
+
transcription: {
|
|
2650
|
+
defaultMode: TranscriptionMode;
|
|
2651
|
+
resolvePolicy: (companyId: string) => Promise<TranscriptionPolicy>;
|
|
2652
|
+
} | undefined;
|
|
2211
2653
|
settings: SettingsRepository;
|
|
2654
|
+
/**
|
|
2655
|
+
* `undefined` quando o recurso não está ligado (ou falta storage legível). O host consulta a
|
|
2656
|
+
* ausência para não registrar a rota de upload — e o preview, sem a rota, esconde o microfone.
|
|
2657
|
+
*/
|
|
2658
|
+
previewMedia: StorePreviewMediaUseCase | undefined;
|
|
2212
2659
|
webhook: {
|
|
2213
2660
|
receive: ReceiveWebhookUseCase;
|
|
2214
2661
|
verifyChallenge: (query: {
|
|
@@ -2233,9 +2680,36 @@ declare function createMetaWhatsAppModule(params: CreateMetaWhatsAppModuleParams
|
|
|
2233
2680
|
};
|
|
2234
2681
|
type MetaWhatsAppModule = ReturnType<typeof createMetaWhatsAppModule>;
|
|
2235
2682
|
|
|
2683
|
+
/**
|
|
2684
|
+
* Leitura de mídia do simulador de conversa.
|
|
2685
|
+
*
|
|
2686
|
+
* **Atrás de flag de propósito, e não ligado por omissão.** Aceitar id que não veio da Meta é
|
|
2687
|
+
* exatamente o que um webhook forjado exploraria: bastaria mandar `preview-upload:<chave>` para
|
|
2688
|
+
* fazer o servidor ler um objeto arbitrário do storage e devolvê-lo. Num ambiente de simulação isso
|
|
2689
|
+
* é o recurso; em produção é leitura arbitrária. Quem liga assume, e a decisão fica visível no
|
|
2690
|
+
* lugar onde o módulo é montado.
|
|
2691
|
+
*/
|
|
2692
|
+
type PreviewMediaSupport = {
|
|
2693
|
+
readonly isEnabled: boolean;
|
|
2694
|
+
readonly objectStorage: ObjectStorageInterface & {
|
|
2695
|
+
getObject: NonNullable<ObjectStorageInterface['getObject']>;
|
|
2696
|
+
};
|
|
2697
|
+
/** Mime a devolver, já que o storage guarda bytes e não o tipo. Padrão `audio/ogg`. */
|
|
2698
|
+
readonly defaultMimeType?: string;
|
|
2699
|
+
};
|
|
2236
2700
|
declare class WhatsAppChannelAdapter implements ChannelAdapterInterface {
|
|
2237
2701
|
private readonly messages;
|
|
2238
|
-
|
|
2702
|
+
/**
|
|
2703
|
+
* Ausente, o adaptador se comporta como sempre: todo id vai para a Graph API. É o que garante
|
|
2704
|
+
* que atualizar o pacote não abre nada em quem não pediu.
|
|
2705
|
+
*/
|
|
2706
|
+
private readonly previewMedia?;
|
|
2707
|
+
constructor(messages: WhatsAppMessageProvider,
|
|
2708
|
+
/**
|
|
2709
|
+
* Ausente, o adaptador se comporta como sempre: todo id vai para a Graph API. É o que garante
|
|
2710
|
+
* que atualizar o pacote não abre nada em quem não pediu.
|
|
2711
|
+
*/
|
|
2712
|
+
previewMedia?: PreviewMediaSupport | undefined);
|
|
2239
2713
|
private translateErrors;
|
|
2240
2714
|
sendText(to: string, body: string): Promise<{
|
|
2241
2715
|
externalMessageId: string | null;
|
|
@@ -2268,6 +2742,12 @@ declare class WhatsAppChannelAdapter implements ChannelAdapterInterface {
|
|
|
2268
2742
|
}): Promise<{
|
|
2269
2743
|
externalMessageId: string | null;
|
|
2270
2744
|
}>;
|
|
2745
|
+
/**
|
|
2746
|
+
* Busca o binário da mídia — da Meta, ou do storage quando o id é do simulador.
|
|
2747
|
+
*
|
|
2748
|
+
* O desvio acontece ANTES de qualquer chamada de rede: id do simulador não existe na Meta, e
|
|
2749
|
+
* tentar buscá-lo lá renderia um 404 confuso em vez do áudio que o operador acabou de gravar.
|
|
2750
|
+
*/
|
|
2271
2751
|
fetchMediaAsBase64(mediaId: string): Promise<{
|
|
2272
2752
|
data: string;
|
|
2273
2753
|
mimeType: string;
|
|
@@ -2349,4 +2829,4 @@ type CreateSendMediaActionParams = {
|
|
|
2349
2829
|
*/
|
|
2350
2830
|
declare function createSendMediaAction(params: CreateSendMediaActionParams): FlowActionHandler;
|
|
2351
2831
|
|
|
2352
|
-
export { type AttachFlowMediaParams, type CompanyDocumentView, type CompanyDocumentsPage, type ConversationDocumentView, type ConversationDocumentsPage, type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, type CreateSendMediaActionParams, DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS, type DeleteConversationParams, type DeleteConversationResult, DeleteConversationUseCase, DeleteFlowGraphUseCase, DocumentRepository, type DocumentRow, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphCache, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowMediaLocation, FlowMediaRepository, type FlowMediaRow, type FlowMediaTranscriptLogger, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type InsertMessageParams, InvalidFlowGraphError, type LinkDocumentParams, type ListCompanyDocumentsParams, ListCompanyDocumentsUseCase, type ListConversationDocumentsParams, ListConversationDocumentsUseCase, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, type ListDocumentsParams, type ListDocumentsResult, 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 NewDocumentRow, type NewFlowGraphRow, type NewFlowMediaRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type PurgeExpiredDocumentsParams, type PurgeExpiredDocumentsResult, PurgeExpiredDocumentsUseCase, 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, type UpdateFlowMediaParams, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, createSendMediaAction, documents, extractMediaDescriptor, flowGraphs, flowMedia, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, runMetaWhatsAppMigrations, sessions, settings, verifyWebhookChallenge, verifyWebhookSignature };
|
|
2832
|
+
export { type AttachFlowMediaParams, type AudioTranscriber, type CompanyDocumentView, type CompanyDocumentsPage, type ConversationDocumentView, type ConversationDocumentsPage, type CreateFlowGraphParams, CreateFlowGraphUseCase, type CreateMetaWhatsAppModuleParams, type CreateSendMediaActionParams, DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS, type DeleteConversationParams, type DeleteConversationResult, DeleteConversationUseCase, DeleteFlowGraphUseCase, DocumentRepository, type DocumentRow, type DrizzleMigrateFunction, type ExportConversationParams, type ExportConversationResult, ExportConversationUseCase, FlowGraphCache, FlowGraphRepository, type FlowGraphRow, FlowInterpreter, type FlowMediaLocation, FlowMediaRepository, type FlowMediaRow, type FlowMediaTranscriptLogger, type FlowRunResult, type FlowStepInput, type FlowStepResult, GetFlowGraphUseCase, GetLiveFlowPositionsUseCase, type IngestInboundMediaParams, type IngestInboundMediaResult, IngestInboundMediaUseCase, type IngestTranscriptionOptions, type InsertMessageParams, InvalidFlowGraphError, type LinkDocumentParams, type ListCompanyDocumentsParams, ListCompanyDocumentsUseCase, type ListConversationDocumentsParams, ListConversationDocumentsUseCase, type ListConversationsFilters, type ListConversationsParams, ListConversationsUseCase, type ListDocumentsParams, type ListDocumentsResult, 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 MetaWhatsAppTranscriptionConfig, type NewDocumentRow, type NewFlowGraphRow, type NewFlowMediaRow, type NewMessageRow, type NewSessionRow, type NewSettingsRow, type NonceStoreInterface, OptimisticLockError, type PreviewMediaSupport, type PurgeExpiredDocumentsParams, type PurgeExpiredDocumentsResult, PurgeExpiredDocumentsUseCase, type RealtimeRelay, type ReceiveWebhookParams, type ReceiveWebhookResult, ReceiveWebhookUseCase, type ReleaseConversationParams, ReleaseConversationUseCase, type ListMessagesParams$1 as RepositoryListMessagesParams, type ResolveTranscriptionPolicyDependencies, type RunMetaWhatsAppMigrationsParams, type SaveFlowGraphParams, SaveFlowGraphUseCase, type SaveTranscriptionByWaMessageIdParams, type SaveTranscriptionParams, type SendMediaParams, SendMessageUseCase, type SendTemplateParams, type SendTextParams, SessionRepository, type SessionRow, SettingsRepository, type SettingsRow, SseHub, type SseListener, type StorePreviewMediaParams, type StorePreviewMediaResult, StorePreviewMediaUseCase, TRANSCRIPTION_MODE, TRANSCRIPTION_STATUS, type TakeoverConversationParams, TakeoverConversationUseCase, type TicketStoreInterface, type TranscribeAudioDependencies, type TranscribeAudioParams, type TranscribeAudioResult, TranscribeAudioUseCase, type TranscriptionPolicy, type TranscriptionPolicyDefaults, type TranscriptionPolicyResolver, type TranscriptionStatus, type UpdateFlowMediaParams, WEBHOOK_NONCE_TTL_SECONDS, WhatsAppChannelAdapter, claimWebhookDelivery, createMetaWhatsAppModule, createSendMediaAction, createTranscriptionPolicyResolver, documents, extractMediaDescriptor, flowGraphs, flowMedia, isAudioMimeType, isRetriableTranscriptionError, isUnsupportedTranscriptionError, issueSseTicket, messages, metaWhatsAppMigrationsFolder, metaWhatsAppSchema, redeemSseTicket, resolveFailureStatus, runMetaWhatsAppMigrations, sessions, settings, transcriptionRetryAfterSeconds, verifyWebhookChallenge, verifyWebhookSignature };
|