@usebridger/transport-baileys 0.2.0 → 0.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 +27 -0
- package/dist/index.d.mts +7 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +120 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @usebridger/transport-baileys
|
|
2
|
+
|
|
3
|
+
Transport do [Bridger](https://www.npmjs.com/package/@usebridger/core) para o WhatsApp, sobre o
|
|
4
|
+
[Baileys](https://github.com/WhiskeySockets/Baileys).
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install @usebridger/transport-baileys
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { createBot } from '@usebridger/core';
|
|
12
|
+
import { sqlite } from '@usebridger/storage-sqlite';
|
|
13
|
+
import { baileys } from '@usebridger/transport-baileys';
|
|
14
|
+
|
|
15
|
+
const bot = createBot({
|
|
16
|
+
transport: baileys(), // pareia por QR, que chega aos plugins no evento connection.qr
|
|
17
|
+
storage: sqlite({ path: 'data/bot.sqlite' }), // guarda as credenciais da sessão
|
|
18
|
+
plugins: [],
|
|
19
|
+
});
|
|
20
|
+
await bot.start();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Requer Node 24 ou mais novo.
|
|
24
|
+
|
|
25
|
+
- [Documentação](https://github.com/murillous/usebridger/blob/main/packages/transport-baileys/docs/README.md)
|
|
26
|
+
|
|
27
|
+
Licença [Apache-2.0](https://github.com/murillous/usebridger/blob/main/LICENSE).
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WAVersion } from "baileys";
|
|
2
2
|
import { Transport, TransportDeps } from "@usebridger/core/adapter";
|
|
3
|
-
import "@usebridger/core";
|
|
3
|
+
import { LogLevel } from "@usebridger/core";
|
|
4
4
|
//#region src/transport.d.ts
|
|
5
5
|
/** Como parear uma sessão sem credenciais: escaneando o QR ou digitando um código no aparelho. */
|
|
6
6
|
type BaileysPairing = "qr" | {
|
|
@@ -20,6 +20,12 @@ export interface BaileysOptions {
|
|
|
20
20
|
* conexão e, se a busca falhar, usa a que vem com o Baileys.
|
|
21
21
|
*/
|
|
22
22
|
readonly version?: WAVersion;
|
|
23
|
+
/**
|
|
24
|
+
* Nível mínimo das linhas do próprio Baileys (sincronização, pre-keys, protocolo), em inglês.
|
|
25
|
+
* Padrão: `'warn'`; o estado da conexão o bot já loga em PT. Use `'debug'` para investigar o
|
|
26
|
+
* Baileys. Vale o mais alto entre este e o nível do bot.
|
|
27
|
+
*/
|
|
28
|
+
readonly logLevel?: LogLevel;
|
|
23
29
|
}
|
|
24
30
|
export declare function baileys(options?: BaileysOptions): (deps: TransportDeps) => Transport;
|
|
25
31
|
//#endregion
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/transport.ts","../src/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/transport.ts","../src/index.ts"],"mappings":";;;;;KAqEY;WAAmC;;;;iBC1D9B;;;;;;WAMN,UAAU;;;;;WAKV,UAAU;;;;;;WAMV,WAAW;;wBAGN,QAAQ,UAAS,kBAAuB,MAAM,kBAAkB"}
|
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,53 @@ import { Readable } from "node:stream";
|
|
|
3
3
|
import { TypedEmitter, createMessage } from "@usebridger/core/adapter";
|
|
4
4
|
import { UnsupportedError } from "@usebridger/core";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
|
+
//#region src/logger.ts
|
|
7
|
+
const RANK = {
|
|
8
|
+
trace: 10,
|
|
9
|
+
debug: 20,
|
|
10
|
+
info: 30,
|
|
11
|
+
warn: 40,
|
|
12
|
+
error: 50,
|
|
13
|
+
fatal: 60,
|
|
14
|
+
silent: Number.POSITIVE_INFINITY
|
|
15
|
+
};
|
|
16
|
+
/** Valida níveis vindos de fora do sistema de tipos (opção em JS). */
|
|
17
|
+
function isLogLevel(value) {
|
|
18
|
+
return typeof value === "string" && Object.hasOwn(RANK, value);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* `floor` é o nível mínimo das linhas do Baileys, além do nível do bot: vale o mais alto dos
|
|
22
|
+
* dois. Sem ele, só o do bot.
|
|
23
|
+
*/
|
|
24
|
+
function toBaileysLogger(log, floor = "trace") {
|
|
25
|
+
/** O mais alto entre o nível do bot e o piso. */
|
|
26
|
+
const effective = () => RANK[log.level] >= RANK[floor] ? log.level : floor;
|
|
27
|
+
const write = (method) => {
|
|
28
|
+
const rank = RANK[method];
|
|
29
|
+
return (obj, msg) => {
|
|
30
|
+
if (rank < RANK[floor]) return;
|
|
31
|
+
if (typeof obj === "string") log[method](obj);
|
|
32
|
+
else log[method](msg ?? "", toFields(obj));
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
get level() {
|
|
37
|
+
return effective();
|
|
38
|
+
},
|
|
39
|
+
child: (bindings) => toBaileysLogger(log.child(bindings), floor),
|
|
40
|
+
trace: write("trace"),
|
|
41
|
+
debug: write("debug"),
|
|
42
|
+
info: write("info"),
|
|
43
|
+
warn: write("warn"),
|
|
44
|
+
error: write("error")
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function toFields(obj) {
|
|
48
|
+
if (obj instanceof Error) return { err: obj };
|
|
49
|
+
if (typeof obj === "object" && obj !== null) return obj;
|
|
50
|
+
return obj === void 0 ? void 0 : { value: obj };
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
6
53
|
//#region src/auth-state.ts
|
|
7
54
|
/**
|
|
8
55
|
* Monta o auth state de uma tentativa de conexão. As chaves passam por um cache em memória
|
|
@@ -68,6 +115,68 @@ function fromJson(value) {
|
|
|
68
115
|
return JSON.parse(JSON.stringify(value), BufferJSON.reviver);
|
|
69
116
|
}
|
|
70
117
|
//#endregion
|
|
118
|
+
//#region src/console.ts
|
|
119
|
+
const METHODS = [
|
|
120
|
+
"log",
|
|
121
|
+
"info",
|
|
122
|
+
"warn",
|
|
123
|
+
"error",
|
|
124
|
+
"debug"
|
|
125
|
+
];
|
|
126
|
+
/** Arquivo do pacote `libsignal` (no pnpm: `.pnpm/libsignal@x/node_modules/libsignal/src/...`). */
|
|
127
|
+
const LIBSIGNAL_FRAME = /[\\/]node_modules[\\/]libsignal[\\/]/;
|
|
128
|
+
const active = [];
|
|
129
|
+
const installed = /* @__PURE__ */ new Map();
|
|
130
|
+
/** Liga o desvio para `logger`; devolve a função que o desliga (idempotente). */
|
|
131
|
+
function routeLibsignalConsole(logger) {
|
|
132
|
+
if (active.length === 0) install();
|
|
133
|
+
active.push(logger);
|
|
134
|
+
let released = false;
|
|
135
|
+
return () => {
|
|
136
|
+
if (released) return;
|
|
137
|
+
released = true;
|
|
138
|
+
active.splice(active.indexOf(logger), 1);
|
|
139
|
+
if (active.length === 0) uninstall();
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function install() {
|
|
143
|
+
for (const method of METHODS) {
|
|
144
|
+
const original = console[method];
|
|
145
|
+
const wrapper = (...args) => {
|
|
146
|
+
const target = active.at(-1);
|
|
147
|
+
if (target === void 0 || !calledFromLibsignal(wrapper)) {
|
|
148
|
+
original.apply(console, args);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
write(target, method, args);
|
|
152
|
+
};
|
|
153
|
+
installed.set(method, {
|
|
154
|
+
original,
|
|
155
|
+
wrapper
|
|
156
|
+
});
|
|
157
|
+
console[method] = wrapper;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function uninstall() {
|
|
161
|
+
for (const [method, { original, wrapper }] of installed) if (console[method] === wrapper) console[method] = original;
|
|
162
|
+
installed.clear();
|
|
163
|
+
}
|
|
164
|
+
/** O chamador direto de `wrapper` é um arquivo do libsignal. */
|
|
165
|
+
function calledFromLibsignal(wrapper) {
|
|
166
|
+
const limit = Error.stackTraceLimit;
|
|
167
|
+
Error.stackTraceLimit = 1;
|
|
168
|
+
const holder = {};
|
|
169
|
+
Error.captureStackTrace(holder, wrapper);
|
|
170
|
+
Error.stackTraceLimit = limit;
|
|
171
|
+
return LIBSIGNAL_FRAME.test(holder.stack ?? "");
|
|
172
|
+
}
|
|
173
|
+
function write(logger, method, args) {
|
|
174
|
+
const text = args.filter((arg) => typeof arg === "string").join(" ");
|
|
175
|
+
const fields = { source: "libsignal" };
|
|
176
|
+
if (method === "error") logger.warn(fields, text);
|
|
177
|
+
else logger.debug(fields, text);
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
71
180
|
//#region src/disconnect-reason.ts
|
|
72
181
|
function toDisconnectReason(error, { pairing }) {
|
|
73
182
|
switch (statusCode(error)) {
|
|
@@ -568,30 +677,6 @@ function wrap(marker, inner) {
|
|
|
568
677
|
return `${lead}${marker}${core}${marker}${trail}`;
|
|
569
678
|
}
|
|
570
679
|
//#endregion
|
|
571
|
-
//#region src/logger.ts
|
|
572
|
-
function toBaileysLogger(log) {
|
|
573
|
-
const write = (method) => (obj, msg) => {
|
|
574
|
-
if (typeof obj === "string") log[method](obj);
|
|
575
|
-
else log[method](msg ?? "", toFields(obj));
|
|
576
|
-
};
|
|
577
|
-
return {
|
|
578
|
-
get level() {
|
|
579
|
-
return log.level;
|
|
580
|
-
},
|
|
581
|
-
child: (bindings) => toBaileysLogger(log.child(bindings)),
|
|
582
|
-
trace: write("trace"),
|
|
583
|
-
debug: write("debug"),
|
|
584
|
-
info: write("info"),
|
|
585
|
-
warn: write("warn"),
|
|
586
|
-
error: write("error")
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
function toFields(obj) {
|
|
590
|
-
if (obj instanceof Error) return { err: obj };
|
|
591
|
-
if (typeof obj === "object" && obj !== null) return obj;
|
|
592
|
-
return obj === void 0 ? void 0 : { value: obj };
|
|
593
|
-
}
|
|
594
|
-
//#endregion
|
|
595
680
|
//#region src/outgoing.ts
|
|
596
681
|
/**
|
|
597
682
|
* Conteúdo do `sendMessage`, com as menções que o Baileys põe no `contextInfo` de qualquer tipo.
|
|
@@ -840,6 +925,9 @@ var BaileysTransport = class {
|
|
|
840
925
|
]);
|
|
841
926
|
#pairing;
|
|
842
927
|
#driver;
|
|
928
|
+
#logLevel;
|
|
929
|
+
/** Desliga o desvio do `console` do libsignal; presente enquanto há socket. */
|
|
930
|
+
#releaseConsole;
|
|
843
931
|
#deps;
|
|
844
932
|
#events;
|
|
845
933
|
#socket = null;
|
|
@@ -858,6 +946,7 @@ var BaileysTransport = class {
|
|
|
858
946
|
constructor(options, deps) {
|
|
859
947
|
this.#pairing = options.pairing;
|
|
860
948
|
this.#driver = options.driver;
|
|
949
|
+
this.#logLevel = options.logLevel;
|
|
861
950
|
this.#deps = deps;
|
|
862
951
|
this.#events = new TypedEmitter((error, event) => this.#log.error("handler de evento do transport falhou", {
|
|
863
952
|
err: error,
|
|
@@ -889,7 +978,7 @@ var BaileysTransport = class {
|
|
|
889
978
|
const attempt = ++this.#attempt;
|
|
890
979
|
this.#endSocket();
|
|
891
980
|
const version = await this.#driver.version();
|
|
892
|
-
const logger = toBaileysLogger(this.#log.child({ lib: "baileys" }));
|
|
981
|
+
const logger = toBaileysLogger(this.#log.child({ lib: "baileys" }), this.#logLevel);
|
|
893
982
|
const { state, saveCreds } = await loadAuthState(this.#deps.auth, logger);
|
|
894
983
|
if (attempt !== this.#attempt) return;
|
|
895
984
|
this.#groups.clear();
|
|
@@ -900,6 +989,7 @@ var BaileysTransport = class {
|
|
|
900
989
|
cachedGroupMetadata: (jid) => this.#cachedGroup(jid)
|
|
901
990
|
});
|
|
902
991
|
this.#socket = socket;
|
|
992
|
+
this.#releaseConsole = routeLibsignalConsole(logger);
|
|
903
993
|
const current = () => this.#socket === socket;
|
|
904
994
|
let saving = Promise.resolve();
|
|
905
995
|
let pairing = false;
|
|
@@ -1031,6 +1121,8 @@ var BaileysTransport = class {
|
|
|
1031
1121
|
const socket = this.#socket;
|
|
1032
1122
|
if (socket === null) return;
|
|
1033
1123
|
this.#socket = null;
|
|
1124
|
+
this.#releaseConsole?.();
|
|
1125
|
+
this.#releaseConsole = void 0;
|
|
1034
1126
|
socket.end(void 0).catch((error) => {
|
|
1035
1127
|
this.#log.warn("falha ao encerrar o socket do Baileys", { err: error });
|
|
1036
1128
|
});
|
|
@@ -1153,8 +1245,11 @@ function toContact(user) {
|
|
|
1153
1245
|
function baileys(options = {}) {
|
|
1154
1246
|
const pairing = options.pairing ?? "qr";
|
|
1155
1247
|
if (pairing !== "qr" && !/^\d{8,15}$/.test(pairing.phone)) throw new TypeError(`baileys: pairing.phone deve ter só dígitos, com DDI (ex.: 5511999999999); recebido "${pairing.phone}"`);
|
|
1248
|
+
const logLevel = options.logLevel ?? "warn";
|
|
1249
|
+
if (!isLogLevel(logLevel)) throw new TypeError(`baileys: logLevel desconhecido "${String(logLevel)}"`);
|
|
1156
1250
|
return (deps) => new BaileysTransport({
|
|
1157
1251
|
pairing,
|
|
1252
|
+
logLevel,
|
|
1158
1253
|
driver: driver(options.version, deps)
|
|
1159
1254
|
}, deps);
|
|
1160
1255
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["Code"],"sources":["../src/auth-state.ts","../src/disconnect-reason.ts","../src/normalize.ts","../src/events.ts","../src/format.ts","../src/logger.ts","../src/outgoing.ts","../src/polls.ts","../src/transport.ts","../src/index.ts"],"sourcesContent":["// Auth state do Baileys sobre o `AuthStateStore` do bot (ADR 0014/0037), no lugar do\n// `useMultiFileAuthState`. O store só guarda JSON; os `Buffer`/`Uint8Array` do Baileys vão e\n// voltam pelo `BufferJSON`, como no arquivo que o `useMultiFileAuthState` gravaria.\n\nimport type { JsonValue } from '@usebridger/core';\nimport type { AuthKeyData, AuthStateStore } from '@usebridger/core/adapter';\nimport {\n type AuthenticationState,\n BufferJSON,\n initAuthCreds,\n makeCacheableSignalKeyStore,\n proto,\n type SignalDataSet,\n type SignalDataTypeMap,\n} from 'baileys';\nimport type { ILogger } from './logger.ts';\n\nexport interface StoredAuthState {\n readonly state: AuthenticationState;\n /** Grava as credenciais atuais. O Baileys as altera no lugar antes de emitir `creds.update`. */\n readonly saveCreds: () => Promise<void>;\n}\n\n/**\n * Monta o auth state de uma tentativa de conexão. As chaves passam por um cache em memória\n * (o do Baileys, 5 min por chave): o Signal lê a sessão do remetente a cada mensagem, e sem ele\n * cada leitura iria ao storage e repetiria a conversão do `BufferJSON`. O cache vive só nesta\n * tentativa: depois de um `clear()` do bot, a próxima começa vazia e não ressuscita chave\n * apagada. Ele não vê gravações de outro processo, o que não acontece porque a mesma sessão\n * não roda em dois (ADR 0036).\n */\nexport async function loadAuthState(\n store: AuthStateStore,\n logger: ILogger,\n): Promise<StoredAuthState> {\n const stored = await store.getCreds();\n const creds = stored === undefined ? initAuthCreds() : fromJson(stored);\n const cached = makeCacheableSignalKeyStore(\n {\n get: async (type, ids) => {\n const raw = await store.getKeys(type, ids);\n const keys: { [id: string]: SignalDataTypeMap[typeof type] } = {};\n for (const [id, value] of Object.entries(raw)) {\n keys[id] =\n type === 'app-state-sync-key' ? toSyncKeyInstance(fromJson(value)) : fromJson(value);\n }\n return keys;\n },\n set: (data) => store.setKeys(toKeyData(data)),\n },\n logger,\n );\n return {\n state: {\n creds,\n keys: {\n // O cache guarda o `null` de uma chave apagada e o devolve; aqui ela some do resultado,\n // como na leitura direta do storage.\n get: async (type, ids) => {\n const found = await cached.get(type, ids);\n for (const id of Object.keys(found)) {\n if (found[id] === null || found[id] === undefined) delete found[id];\n }\n return found;\n },\n // O cache guarda o que recebe; convertido aqui, ele devolve o mesmo que o storage.\n set: (data) => cached.set(withSyncKeyInstances(data)),\n },\n },\n saveCreds: () => store.setCreds(toJson(creds)),\n };\n}\n\n// O Baileys espera a instância do protobuf, não o objeto cru (como no `useMultiFileAuthState`).\nfunction toSyncKeyInstance(value: object): proto.Message.AppStateSyncKeyData {\n return value instanceof proto.Message.AppStateSyncKeyData\n ? value\n : proto.Message.AppStateSyncKeyData.fromObject(value);\n}\n\nfunction withSyncKeyInstances(data: SignalDataSet): SignalDataSet {\n const syncKeys = data['app-state-sync-key'];\n if (syncKeys === undefined) return data;\n const converted: SignalDataSet['app-state-sync-key'] = {};\n for (const [id, value] of Object.entries(syncKeys)) {\n converted[id] = value ? toSyncKeyInstance(value) : value;\n }\n return { ...data, 'app-state-sync-key': converted };\n}\n\nfunction toKeyData(data: SignalDataSet): AuthKeyData {\n const out: Record<string, Record<string, JsonValue | null>> = {};\n for (const [type, entries] of Object.entries(data)) {\n const converted: Record<string, JsonValue | null> = {};\n for (const [id, value] of Object.entries(entries ?? {})) {\n converted[id] = value === null || value === undefined ? null : toJson(value);\n }\n out[type] = converted;\n }\n return out;\n}\n\nfunction toJson(value: unknown): JsonValue {\n return JSON.parse(JSON.stringify(value, BufferJSON.replacer)) as JsonValue;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: o tipo vem de quem chama; o JSON já foi validado na gravação.\nfunction fromJson(value: JsonValue): any {\n return JSON.parse(JSON.stringify(value), BufferJSON.reviver);\n}\n","// Código de desconexão do Baileys → `DisconnectReason` do core. A `ReconnectionPolicy` decide em\n// cima dele, e `logged-out`/`auth-failed` apagam as credenciais: só entram aqui quando o aparelho\n// ou o servidor rejeitou a credencial de fato (ADR 0045).\n\nimport type { DisconnectReason } from '@usebridger/core';\nimport { DisconnectReason as Code } from 'baileys';\n\nexport interface CloseContext {\n /** Esta tentativa mostrou QR ou código de pareamento e ainda não abriu. */\n readonly pairing: boolean;\n}\n\nexport function toDisconnectReason(error: unknown, { pairing }: CloseContext): DisconnectReason {\n switch (statusCode(error)) {\n case Code.loggedOut:\n return 'logged-out';\n // Servidor recusou a credencial (403) ou o aparelho não reconhece mais esta sessão (411).\n case Code.forbidden:\n case Code.multideviceMismatch:\n return 'auth-failed';\n case Code.connectionReplaced:\n return 'replaced';\n // O Baileys usa 408 tanto para o QR que expirou quanto para a conexão que caiu.\n case Code.timedOut:\n return pairing ? 'qr-timeout' : 'connection-lost';\n // 515 é o restart que o servidor pede logo depois do pareamento: reconecta pela política\n // (ADR 0048).\n case Code.connectionClosed:\n case Code.restartRequired:\n return 'connection-lost';\n // 500 (`badSession`) é também o código de todo stream error sem motivo conhecido: tratá-lo\n // como credencial rejeitada apagaria a sessão por um erro qualquer. 405 vem quando o\n // servidor recusa a versão do cliente, não a credencial.\n case Code.badSession:\n case Code.unavailableService:\n case 405:\n return 'server-error';\n default:\n return 'unknown';\n }\n}\n\n/** O Baileys encerra com um `Boom`, que traz o código em `output.statusCode`. */\nfunction statusCode(error: unknown): number | undefined {\n if (typeof error !== 'object' || error === null || !('output' in error)) return undefined;\n const { output } = error;\n if (typeof output !== 'object' || output === null || !('statusCode' in output)) return undefined;\n return typeof output.statusCode === 'number' ? output.statusCode : undefined;\n}\n","// Normalização (M2-1.2): `WAMessage` do Baileys → `Message` do core (ADR 0009). Desembrulha os\n// envelopes (ephemeral, viewOnce, documentWithCaption), resolve o telefone de cada contato,\n// inclusive com LID (M1-16.4, ADR 0046), e monta a citada como `Message` também.\n\nimport type { Contact, Message } from '@usebridger/core';\nimport { createMessage, type MediaSource, type MessageInit } from '@usebridger/core/adapter';\nimport {\n isJidGroup,\n isLidUser,\n isPnUser,\n jidDecode,\n jidNormalizedUser,\n type proto,\n toNumber,\n type WAMessage,\n type WAMessageKey,\n} from 'baileys';\n\n/** O que a normalização precisa da sessão; o transport liga ao socket, os testes a falsos. */\nexport interface NormalizeEnv {\n /**\n * Ids da própria sessão sem aparelho, o JID de telefone primeiro e depois o LID. Dão o autor\n * das mensagens da sessão na conversa privada e o `fromMe` da citada.\n */\n readonly selfIds: readonly string[];\n /** JID de telefone de um LID, ou `null` se a sessão ainda não conhece o par. */\n pnForLid(lid: string): Promise<string | null>;\n download(raw: WAMessage): Promise<Buffer>;\n stream(raw: WAMessage): Promise<ReadableStream<Uint8Array>>;\n}\n\ntype Content = proto.IMessage;\n\n/** Envelopes que só embrulham o conteúdo de verdade. */\nconst ENVELOPES = [\n 'ephemeralMessage',\n 'viewOnceMessage',\n 'viewOnceMessageV2',\n 'viewOnceMessageV2Extension',\n 'documentWithCaptionMessage',\n // Ao contrário das outras versões, a V4 da enquete é um envelope com a enquete dentro.\n 'pollCreationMessageV4',\n] as const satisfies readonly (keyof Content)[];\n\nconst VIEW_ONCE: ReadonlySet<string> = new Set([\n 'viewOnceMessage',\n 'viewOnceMessageV2',\n 'viewOnceMessageV2Extension',\n]);\n\n/**\n * Campos que não são o conteúdo da mensagem. Edição, apagamento e reação chegam por eventos\n * próprios do Baileys (`events.ts`); o resto é metadado do protocolo.\n */\nconst CONTROL: ReadonlySet<string> = new Set([\n 'protocolMessage',\n 'reactionMessage',\n 'encReactionMessage',\n 'pollUpdateMessage',\n 'keepInChatMessage',\n 'pinInChatMessage',\n 'senderKeyDistributionMessage',\n 'fastRatchetKeySenderKeyDistributionMessage',\n 'messageContextInfo',\n]);\n\n/**\n * Tira os envelopes, em qualquer ordem e aninhados (ephemeral com viewOnce dentro, por exemplo).\n * O limite só protege de um proto malformado.\n */\nexport function unwrap(content: Content): { content: Content; viewOnce: boolean } {\n let current = content;\n let viewOnce = false;\n for (let depth = 0; depth < 10; depth++) {\n const envelope = ENVELOPES.find((name) => current[name]?.message);\n if (envelope === undefined) break;\n if (VIEW_ONCE.has(envelope)) viewOnce = true;\n current = current[envelope]?.message ?? current;\n }\n return { content: current, viewOnce };\n}\n\n/** Campo que define o tipo: o primeiro preenchido que não é de controle. */\nfunction contentKey(content: Content): keyof Content | undefined {\n return (Object.keys(content) as (keyof Content)[]).find(\n (key) => content[key] != null && !CONTROL.has(key),\n );\n}\n\n/**\n * Converte uma mensagem do Baileys. `null` quando não há o que entregar: sem conteúdo (aviso de\n * grupo, mensagem que não deu para decifrar) ou só controle (edição, reação, apagamento).\n */\nexport function toMessage(raw: WAMessage, env: NormalizeEnv): Promise<Message | null> {\n return build(raw, env, toNumber(raw.messageTimestamp) * 1000, false);\n}\n\n/**\n * Nova versão de uma mensagem editada, com `isEdited: true`. `raw` é a chave da original com o\n * conteúdo novo; o Baileys não manda o `pushName` na edição, então o nome vem de quem chama.\n */\nexport function toEditedMessage(raw: WAMessage, env: NormalizeEnv): Promise<Message | null> {\n return build(raw, env, toNumber(raw.messageTimestamp) * 1000, true);\n}\n\nasync function build(\n raw: WAMessage,\n env: NormalizeEnv,\n timestamp: number,\n isEdited: boolean,\n): Promise<Message | null> {\n const chatId = raw.key.remoteJid;\n const id = raw.key.id;\n if (!raw.message || !chatId || !id) return null;\n\n const { content, viewOnce } = unwrap(raw.message);\n const key = contentKey(content);\n if (key === undefined) return null;\n\n const isGroup = isJidGroup(chatId) === true;\n const fromMe = raw.key.fromMe === true;\n const node = content[key];\n const context = contextOf(node);\n const base: Base = {\n id,\n chat: { id: chatId, isGroup },\n sender: await authorOf(raw.key, chatId, env, raw.pushName ?? null),\n timestamp,\n fromMe,\n quoted: context ? await quoted(context, chatId, env, timestamp) : null,\n mentions: await Promise.all(\n (context?.mentionedJid ?? []).map((jid) => resolveContact(env, jid, undefined, null)),\n ),\n isForwarded: context?.isForwarded === true,\n isViewOnce: viewOnce || raw.key.isViewOnce === true || flag(node, 'viewOnce'),\n isEdited,\n };\n // O download parte da mensagem sem envelopes: é o formato que o Baileys espera.\n const unwrapped: WAMessage = { ...raw, message: content };\n const media: MediaOf = (m) => ({\n mimetype: m.mimetype ?? 'application/octet-stream',\n size: m.fileLength == null ? null : toNumber(m.fileLength) || null,\n download: () => env.download(unwrapped),\n stream: () => env.stream(unwrapped),\n });\n\n const message = createMessage(init(key, content, base, media));\n natives.set(message, raw);\n return message;\n}\n\n/**\n * Mensagem do Baileys de onde cada `Message` saiu. Citar no envio precisa do proto original\n * (`quoted` do `sendMessage`); o `WeakMap` some com a `Message`, sem cache para limpar.\n */\nconst natives = new WeakMap<Message, WAMessage>();\n\n/** O `WAMessage` que originou a mensagem, se ela foi normalizada por este transport. */\nexport function nativeOf(message: Message): WAMessage | undefined {\n return natives.get(message);\n}\n\ntype Base = Omit<Extract<MessageInit, { type: 'unknown' }>, 'type' | 'text'>;\ntype MediaOf = (m: {\n readonly mimetype?: string | null;\n readonly fileLength?: Parameters<typeof toNumber>[0];\n}) => MediaSource;\n\nfunction init(key: keyof Content, c: Content, base: Base, media: MediaOf): MessageInit {\n switch (key) {\n case 'conversation':\n return { ...base, type: 'text', text: c.conversation ?? '' };\n case 'extendedTextMessage':\n return { ...base, type: 'text', text: c.extendedTextMessage?.text ?? '' };\n case 'imageMessage': {\n const m = c.imageMessage ?? {};\n return { ...base, type: 'image', text: m.caption ?? null, media: media(m) };\n }\n case 'videoMessage':\n case 'ptvMessage': {\n // `ptv` é o vídeo redondo (recado de vídeo): para o plugin, um vídeo.\n const m = c[key] ?? {};\n return { ...base, type: 'video', text: m.caption ?? null, media: media(m) };\n }\n case 'audioMessage': {\n const m = c.audioMessage ?? {};\n return { ...base, type: m.ptt ? 'voice' : 'audio', text: null, media: media(m) };\n }\n case 'stickerMessage':\n return { ...base, type: 'sticker', text: null, media: media(c.stickerMessage ?? {}) };\n case 'documentMessage': {\n const m = c.documentMessage ?? {};\n return {\n ...base,\n type: 'document',\n text: m.caption ?? null,\n fileName: m.fileName ?? null,\n media: media(m),\n };\n }\n case 'locationMessage': {\n const m = c.locationMessage ?? {};\n return {\n ...base,\n type: 'location',\n text: m.comment ?? null,\n location: {\n latitude: m.degreesLatitude ?? 0,\n longitude: m.degreesLongitude ?? 0,\n name: m.name ?? m.address ?? null,\n ...(m.address ? { address: m.address } : {}),\n },\n };\n }\n case 'liveLocationMessage': {\n const m = c.liveLocationMessage ?? {};\n return {\n ...base,\n type: 'location',\n text: m.caption ?? null,\n location: {\n latitude: m.degreesLatitude ?? 0,\n longitude: m.degreesLongitude ?? 0,\n name: null,\n },\n };\n }\n case 'contactMessage':\n case 'contactsArrayMessage': {\n const list =\n key === 'contactMessage'\n ? [c.contactMessage ?? {}]\n : (c.contactsArrayMessage?.contacts ?? []);\n return {\n ...base,\n type: 'contact',\n text: null,\n contacts: list.map((m) => ({ name: m.displayName ?? '', vcard: m.vcard ?? '' })),\n };\n }\n case 'pollCreationMessage':\n case 'pollCreationMessageV2':\n case 'pollCreationMessageV3':\n case 'pollCreationMessageV5': {\n const m = c[key] ?? {};\n return {\n ...base,\n type: 'poll',\n text: null,\n poll: { name: m.name ?? '', options: (m.options ?? []).map((o) => o.optionName ?? '') },\n };\n }\n default:\n return { ...base, type: 'unknown', text: null };\n }\n}\n\nfunction contextOf(node: unknown): proto.IContextInfo | null {\n if (typeof node !== 'object' || node === null || !('contextInfo' in node)) return null;\n return (node.contextInfo as proto.IContextInfo | null | undefined) ?? null;\n}\n\nfunction flag(node: unknown, name: string): boolean {\n return (\n typeof node === 'object' && node !== null && name in node && Reflect.get(node, name) === true\n );\n}\n\n/**\n * A citada vem só com id, autor e conteúdo: sem horário (vale o da mensagem que cita) e sem nome\n * do autor.\n */\nfunction quoted(\n context: proto.IContextInfo,\n chatId: string,\n env: NormalizeEnv,\n timestamp: number,\n): Promise<Message | null> {\n if (!context.quotedMessage || !context.stanzaId) return Promise.resolve(null);\n const author = context.participant ? jidNormalizedUser(context.participant) : undefined;\n return build(\n {\n key: {\n remoteJid: context.remoteJid ?? chatId,\n id: context.stanzaId,\n fromMe: author !== undefined && env.selfIds.includes(author),\n participant: author,\n },\n message: context.quotedMessage,\n },\n env,\n timestamp,\n false,\n );\n}\n\n/**\n * Autor de uma mensagem pela chave. Grupo, status e citada o trazem em `participant`. Sem ele\n * (conversa privada), o autor é o próprio chat, ou a sessão quando foi ela que mandou.\n */\nexport function authorOf(\n key: WAMessageKey,\n chatId: string,\n env: Pick<NormalizeEnv, 'selfIds' | 'pnForLid'>,\n name: string | null,\n): Promise<Contact> {\n const alt = key.participant ? key.participantAlt : key.fromMe ? undefined : key.remoteJidAlt;\n return resolveContact(env, authorJid(key, chatId, env.selfIds), alt, name);\n}\n\n/** O JID do autor pela chave, sem resolver o telefone (ver `authorOf`). */\nexport function authorJid(key: WAMessageKey, chatId: string, selfIds: readonly string[]): string {\n if (key.participant) return key.participant;\n return key.fromMe ? (selfIds[0] ?? chatId) : chatId;\n}\n\n/**\n * Contato com o telefone resolvido: do próprio JID de telefone, do JID alternativo que o\n * Baileys manda junto com um LID ou do mapeamento LID ↔ telefone da sessão.\n */\nexport async function resolveContact(\n env: Pick<NormalizeEnv, 'pnForLid'>,\n jid: string,\n alt: string | null | undefined,\n name: string | null,\n): Promise<Contact> {\n // Sem o aparelho: `5511…:12@s.whatsapp.net` e `5511…@s.whatsapp.net` são o mesmo contato.\n const id = jidNormalizedUser(jid) || jid;\n return { id, name, phone: await phoneOf(env, id, alt) };\n}\n\nasync function phoneOf(\n env: Pick<NormalizeEnv, 'pnForLid'>,\n id: string,\n alt: string | null | undefined,\n): Promise<string | null> {\n if (isPnUser(id)) return jidDecode(id)?.user ?? null;\n if (alt && isPnUser(alt)) return jidDecode(alt)?.user ?? null;\n if (!isLidUser(id)) return null;\n const pn = await env.pnForLid(id);\n return pn ? (jidDecode(pn)?.user ?? null) : null;\n}\n","// Mapeamento de eventos (M2-1.6): o que o Baileys emite além das mensagens novas → eventos do\n// barramento (plano §6.4). Reação, edição e apagamento chegam ao Baileys como mensagens de\n// controle, que ele já converte em `messages.reaction` e `messages.update`; grupos chegam em\n// `groups.upsert`, `groups.update` e `group-participants.update`.\n\nimport type { Chat, Contact, Message } from '@usebridger/core';\nimport type { TransportEvents } from '@usebridger/core/adapter';\nimport {\n type BaileysEventMap,\n type GroupMetadata as BaileysGroupMetadata,\n isJidGroup,\n isJidStatusBroadcast,\n jidNormalizedUser,\n type WAMessageUpdate,\n} from 'baileys';\nimport {\n authorJid,\n authorOf,\n type NormalizeEnv,\n resolveContact,\n toEditedMessage,\n} from './normalize.ts';\n\ntype Env = Pick<NormalizeEnv, 'selfIds' | 'pnForLid'>;\n\n/**\n * Nome e telefone já vistos de cada contato. Decide quando sai o `contact.updated` e dá nome a\n * quem aparece sem `pushName` (reação, edição, apagamento, grupo). Vive enquanto o transport\n * vive: depois de reiniciar o processo, cada contato conta de novo como visto pela primeira vez.\n */\nexport class ContactBook {\n readonly #known = new Map<\n string,\n { readonly name: string | null; readonly phone: string | null }\n >();\n\n /**\n * Registra um remetente. Devolve o `contact.updated` quando há o que contar: na primeira vez\n * que o contato aparece (ADR 0049) ou quando o nome ou o telefone mudou. Campo desconhecido\n * (`null`) não apaga o que já se sabia.\n */\n observe(contact: Contact): TransportEvents['contact.updated'] | null {\n const known = this.#known.get(contact.id);\n const name = contact.name ?? known?.name ?? null;\n const phone = contact.phone ?? known?.phone ?? null;\n this.#known.set(contact.id, { name, phone });\n const update: { id: string; name?: string; phone?: string } = { id: contact.id };\n if (name !== null && name !== known?.name) update.name = name;\n if (phone !== null && phone !== known?.phone) update.phone = phone;\n return update.name === undefined && update.phone === undefined ? null : update;\n }\n\n nameOf(id: string): string | null {\n return this.#known.get(id)?.name ?? null;\n }\n\n /** O contato com o nome já visto, quando o evento não trouxe nenhum. */\n named(contact: Contact): Contact {\n return contact.name === null ? { ...contact, name: this.nameOf(contact.id) } : contact;\n }\n}\n\n/** O `Chat` de um JID; os eventos de grupo também o usam (ADR 0059). */\nexport function chatOf(id: string): Chat {\n return { id, isGroup: isJidGroup(id) === true };\n}\n\n/**\n * `reaction` a partir do `messages.reaction`: `key` é a mensagem reagida e `reaction.key` a\n * mensagem de reação, que diz quem reagiu. Texto vazio é reação removida.\n */\nexport async function toReaction(\n { key, reaction }: BaileysEventMap['messages.reaction'][number],\n env: Env,\n contacts: ContactBook,\n): Promise<TransportEvents['reaction'] | null> {\n const from = reaction.key;\n const chatId = from?.remoteJid ?? key.remoteJid;\n if (!from || !chatId || !key.id || isJidStatusBroadcast(chatId)) return null;\n return {\n chat: chatOf(chatId),\n messageId: key.id,\n sender: contacts.named(await authorOf(from, chatId, env, null)),\n emoji: reaction.text || null,\n fromMe: from.fromMe === true,\n };\n}\n\n/**\n * `message.edited` a partir do `messages.update` de edição. A chave é a da original com o autor\n * da edição, e o conteúdo novo vem em `editedMessage`.\n */\nexport function toEdited(\n { key, update }: WAMessageUpdate,\n env: NormalizeEnv,\n contacts: ContactBook,\n): Promise<Message | null> {\n const content = update.message?.editedMessage?.message;\n const chatId = key.remoteJid;\n if (!content || !chatId || isJidStatusBroadcast(chatId)) return Promise.resolve(null);\n return toEditedMessage(\n {\n key,\n message: content,\n // Sem o horário da edição, vale o da chegada.\n messageTimestamp: update.messageTimestamp ?? Math.floor(Date.now() / 1000),\n pushName: contacts.nameOf(jidNormalizedUser(authorJid(key, chatId, env.selfIds))),\n },\n env,\n );\n}\n\n/**\n * `message.deleted` a partir do `messages.update` de apagamento (`REVOKE`). `key` é a apagada;\n * `update.key` é a mensagem que apagou, que diz quem apagou (o autor ou um admin do grupo).\n */\nexport async function toDeleted(\n { key, update }: WAMessageUpdate,\n env: Env,\n contacts: ContactBook,\n): Promise<TransportEvents['message.deleted'] | null> {\n const chatId = key.remoteJid;\n if (!chatId || !key.id || isJidStatusBroadcast(chatId)) return null;\n const by = update.key;\n return {\n chat: chatOf(chatId),\n messageId: key.id,\n deletedBy: by ? contacts.named(await authorOf(by, chatId, env, null)) : null,\n fromMe: (by ?? key).fromMe === true,\n };\n}\n\ntype ParticipantsUpdate = BaileysEventMap['group-participants.update'];\ntype Participant = ParticipantsUpdate['participants'][number];\n\n/** O que um `group-participants.update` vira no barramento. */\nexport interface ParticipantEvents {\n /** A própria sessão entrou ou saiu do grupo. */\n readonly self: 'group.joined' | 'group.left' | null;\n /** Os demais participantes; `null` se não sobrou nenhum. */\n readonly others: TransportEvents['group.participants'] | null;\n}\n\n/**\n * Converte a alteração de participantes. Entrada e saída da própria sessão viram\n * `group.joined`/`group.left` e saem da lista; promovida ou rebaixada, ela segue em\n * `group.participants`. Troca de número (`modify`) não tem evento no core.\n */\nexport async function toParticipantEvents(\n { id, author, authorPn, participants, action }: ParticipantsUpdate,\n env: Env,\n contacts: ContactBook,\n): Promise<ParticipantEvents> {\n if (action === 'modify') return { self: null, others: null };\n const isSelf = (p: Participant): boolean =>\n [p.id, p.phoneNumber, p.lid].some((jid) => jid && env.selfIds.includes(jidNormalizedUser(jid)));\n const selfIn = participants.some(isSelf);\n const self = !selfIn\n ? null\n : action === 'add'\n ? 'group.joined'\n : action === 'remove'\n ? 'group.left'\n : null;\n const rest = self === null ? participants : participants.filter((p) => !isSelf(p));\n if (rest.length === 0) return { self, others: null };\n const contact = async (jid: string, alt: string | undefined, name: string | null) =>\n contacts.named(await resolveContact(env, jid, alt, name));\n return {\n self,\n others: {\n chat: chatOf(id),\n action,\n participants: await Promise.all(\n rest.map((p) => contact(p.id, p.phoneNumber, p.notify ?? p.name ?? null)),\n ),\n actor: author ? await contact(author, authorPn, null) : null,\n },\n };\n}\n\n/**\n * `group.updated` com só os campos que mudaram. O Baileys também emite `groups.update` com os\n * metadados completos de cada grupo ao sincronizar (`groupFetchAllParticipating`); esse traz\n * `participants` e não é uma alteração, então fica de fora.\n */\nexport function toGroupUpdated(\n update: Partial<BaileysGroupMetadata>,\n): TransportEvents['group.updated'] | null {\n if (!update.id || update.participants) return null;\n const changed: {\n chat: Chat;\n title?: string;\n description?: string | null;\n announce?: boolean;\n restrict?: boolean;\n } = { chat: chatOf(update.id) };\n if (update.subject !== undefined) changed.title = update.subject;\n // Descrição removida chega com `desc` presente e vazio.\n if ('desc' in update) changed.description = update.desc || null;\n if (update.announce !== undefined) changed.announce = update.announce;\n if (update.restrict !== undefined) changed.restrict = update.restrict;\n return Object.keys(changed).length > 1 ? changed : null;\n}\n","// Texto formatado neutro do core (ADR 0061) na marcação do WhatsApp: `*negrito*`, `_itálico_`,\n// `` `código` `` e `@número` com o JID na lista de menções. Função pura.\n\nimport type { FormattedText, TextNode } from '@usebridger/core';\nimport { jidDecode } from 'baileys';\n\nexport interface RenderedText {\n readonly text: string;\n /** JIDs das menções da árvore, na ordem e sem repetição. */\n readonly mentions: readonly string[];\n}\n\n/**\n * Renderiza a árvore. O WhatsApp não tem escape: um `*` literal do texto pode casar com outro e\n * virar negrito, como já acontece no app. Por isso o texto literal vai como está.\n */\nexport function renderWhatsApp(text: FormattedText): RenderedText {\n const mentions = new Set<string>();\n const render = (nodes: readonly TextNode[]): string => {\n let out = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n out += node;\n continue;\n }\n switch (node.type) {\n case 'bold':\n case 'italic':\n out += wrap(node.type === 'bold' ? '*' : '_', render(node.children));\n break;\n case 'code':\n out += wrap('`', node.text);\n break;\n case 'link': {\n // O WhatsApp não tem link com rótulo: a URL aparece e vira link sozinha.\n const label = render(node.children);\n out += label === node.url ? node.url : `${label} (${node.url})`;\n break;\n }\n case 'mention':\n mentions.add(node.contact.id);\n // O app troca `@<usuário do JID>` pelo nome do contato, inclusive com LID.\n out += `@${jidDecode(node.contact.id)?.user ?? node.contact.id}`;\n break;\n }\n }\n return out;\n };\n return { text: render(text.nodes), mentions: [...mentions] };\n}\n\n/**\n * O marcador só vale colado no texto (`* a *` sai literal): o espaço das pontas fica do lado de\n * fora.\n */\nfunction wrap(marker: string, inner: string): string {\n const match = /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(inner);\n const [, lead = '', core = '', trail = ''] = match ?? [];\n if (core === '') return inner;\n return `${lead}${marker}${core}${marker}${trail}`;\n}\n","// O Baileys loga no formato do pino (`logger.info(obj, msg)`); o bot, no do core\n// (`log.info(msg, fields)`). Este adapter traduz um para o outro, para as linhas do Baileys\n// passarem pelo logger do bot, com a censura de segredos dele (ADR 0032).\n\nimport type { LogFields, Logger } from '@usebridger/core';\nimport type { SocketConfig } from 'baileys';\n\n/** Logger que o Baileys aceita; o pacote não exporta o `ILogger` pela entrada principal. */\nexport type ILogger = SocketConfig['logger'];\n\ntype Method = 'trace' | 'debug' | 'info' | 'warn' | 'error';\n\nexport function toBaileysLogger(log: Logger): ILogger {\n const write =\n (method: Method) =>\n (obj: unknown, msg?: string): void => {\n if (typeof obj === 'string') log[method](obj);\n else log[method](msg ?? '', toFields(obj));\n };\n return {\n // O Baileys consulta o nível para pular logs caros; lido a cada vez porque o logger da\n // fábrica só passa a valer no `start()`.\n get level(): string {\n return log.level;\n },\n child: (bindings) => toBaileysLogger(log.child(bindings)),\n trace: write('trace'),\n debug: write('debug'),\n info: write('info'),\n warn: write('warn'),\n error: write('error'),\n };\n}\n\nfunction toFields(obj: unknown): LogFields | undefined {\n if (obj instanceof Error) return { err: obj };\n if (typeof obj === 'object' && obj !== null) return obj as LogFields;\n return obj === undefined ? undefined : { value: obj };\n}\n","// Envio (M2-1.3): o conteúdo, a chave e os metadados de grupo do core no formato do Baileys, e\n// de volta. Funções puras; quem fala com o socket é o transport.\n\nimport {\n type GroupMetadata,\n type GroupParticipant,\n type Message,\n type MessageKey,\n type OutgoingContent,\n type SendOptions,\n UnsupportedError,\n} from '@usebridger/core';\nimport {\n type AnyMessageContent,\n type GroupMetadata as BaileysGroupMetadata,\n jidNormalizedUser,\n type WAMessage,\n type WAMessageKey,\n} from 'baileys';\nimport { renderWhatsApp } from './format.ts';\nimport { type NormalizeEnv, nativeOf, resolveContact } from './normalize.ts';\n\n/**\n * Conteúdo do `sendMessage`, com as menções que o Baileys põe no `contextInfo` de qualquer tipo.\n * A árvore neutra (`formatted`, `formattedCaption`) vira a marcação do WhatsApp, e as menções\n * dela se juntam às de `options.mentions` (ADR 0061).\n */\nexport function toContent(content: OutgoingContent, options?: SendOptions): AnyMessageContent {\n const ids = new Set(options?.mentions);\n let text: string | undefined;\n let caption: string | undefined;\n if (content.type === 'text') {\n text = content.text;\n if (content.formatted) {\n const rendered = renderWhatsApp(content.formatted);\n text = rendered.text;\n for (const id of rendered.mentions) ids.add(id);\n }\n } else if ('caption' in content || 'formattedCaption' in content) {\n caption = content.caption;\n if (content.formattedCaption) {\n const rendered = renderWhatsApp(content.formattedCaption);\n caption = rendered.text;\n for (const id of rendered.mentions) ids.add(id);\n }\n }\n const mentions = ids.size > 0 ? { mentions: [...ids] } : {};\n switch (content.type) {\n case 'text':\n return { text: text ?? content.text, ...mentions };\n case 'image':\n return {\n image: content.media,\n caption,\n mimetype: content.mimetype,\n ...mentions,\n };\n case 'video':\n return {\n video: content.media,\n caption,\n mimetype: content.mimetype,\n ...mentions,\n };\n case 'audio':\n case 'voice':\n // Voz é áudio com `ptt`; sem `mimetype`, o Baileys usa `audio/ogg; codecs=opus`.\n return {\n audio: content.media,\n ptt: content.type === 'voice',\n mimetype: content.mimetype,\n ...mentions,\n };\n case 'sticker':\n return { sticker: content.media, ...mentions };\n case 'document':\n return {\n document: content.media,\n fileName: content.fileName,\n mimetype: content.mimetype,\n caption,\n ...mentions,\n };\n case 'album':\n // O Baileys não monta álbum (o WhatsApp agrupa as imagens em sequência), então o transport\n // não declara `send.album`, e a fila envia item a item (ADR 0065). Chegar aqui é pular a\n // checagem.\n throw new UnsupportedError('send.album', 'baileys');\n case 'poll':\n return {\n poll: {\n name: content.name,\n values: [...content.options],\n // No WhatsApp, 0 libera marcar quantas quiser e 1 é escolha única.\n selectableCount: content.multiple === true ? 0 : 1,\n },\n ...mentions,\n };\n }\n}\n\nexport function toWAKey(key: MessageKey): WAMessageKey {\n return {\n remoteJid: key.chatId,\n id: key.id,\n fromMe: key.fromMe,\n participant: key.senderId ?? undefined,\n };\n}\n\n/**\n * A mensagem a citar como o Baileys a quer. Recebida por este transport, vai o proto original\n * (a citada mostra mídia e legenda); montada fora dele (testes, storage), vai só o texto.\n */\nexport function toQuoted(message: Message): WAMessage {\n return (\n nativeOf(message) ?? {\n key: toWAKey(message.key),\n message: { conversation: message.text ?? '' },\n }\n );\n}\n\n/** Metadados do grupo com o telefone de cada participante resolvido, inclusive com LID. */\nexport async function toGroupMetadata(\n native: BaileysGroupMetadata,\n env: Pick<NormalizeEnv, 'pnForLid'>,\n): Promise<GroupMetadata> {\n const participants = await Promise.all(\n native.participants.map(async (p): Promise<GroupParticipant> => {\n const contact = await resolveContact(env, p.id, p.phoneNumber, p.name ?? p.notify ?? null);\n return {\n ...contact,\n isAdmin: p.admin === 'admin' || p.admin === 'superadmin',\n isSuperAdmin: p.admin === 'superadmin',\n };\n }),\n );\n return {\n id: native.id,\n title: native.subject,\n description: native.desc ?? null,\n ownerId: native.owner ? jidNormalizedUser(native.owner) || native.owner : null,\n participants,\n };\n}\n","// Votos de enquete (#312, ADR 0071). O WhatsApp cifra o voto com o segredo da enquete\n// (`messageSecret`), que só vem na mensagem que a criou, e o Baileys 7 não decifra mais sozinho (o\n// trecho do `process-message` está comentado). Por isso o transport guarda as enquetes que vê e\n// decifra o voto com `decryptPollVote`.\n\nimport { createHash } from 'node:crypto';\nimport type { TransportEvents } from '@usebridger/core/adapter';\nimport {\n decryptPollVote,\n jidNormalizedUser,\n type proto,\n type WAMessage,\n type WAMessageKey,\n} from 'baileys';\nimport { type ContactBook, chatOf } from './events.ts';\nimport { authorOf, type NormalizeEnv, unwrap } from './normalize.ts';\n\ntype Env = Pick<NormalizeEnv, 'selfIds' | 'pnForLid'>;\n\ninterface KnownPoll {\n readonly key: WAMessageKey;\n readonly secret: Uint8Array;\n /** SHA-256 de cada opção, em hex, na ordem da enquete: o voto traz os hashes, não o texto. */\n readonly hashes: readonly string[];\n}\n\n/** Enquetes guardadas por padrão; a mais antiga sai primeiro. */\nconst DEFAULT_MAX_POLLS = 1000;\n\n/**\n * Enquetes que a sessão enviou ou recebeu enquanto conectada, pelo ID da mensagem. O ID basta: o\n * mesmo chat privado aparece ora como LID, ora como telefone, e o ID do WhatsApp é aleatório. Vive\n * até o `disconnect()`: voto de enquete anterior não se decifra e é descartado.\n */\nexport class PollBook {\n readonly #polls = new Map<string, KnownPoll>();\n readonly #max: number;\n\n constructor(max: number = DEFAULT_MAX_POLLS) {\n this.#max = max;\n }\n\n /** Guarda a enquete, se a mensagem for uma e trouxer o segredo; o resto é ignorado. */\n remember(raw: WAMessage): void {\n const id = raw.key.id;\n if (!id || !raw.message) return;\n const { content } = unwrap(raw.message);\n const poll =\n content.pollCreationMessage ??\n content.pollCreationMessageV2 ??\n content.pollCreationMessageV3 ??\n content.pollCreationMessageV5;\n // A V4 é envelope: o segredo pode vir fora ou dentro dele.\n const secret =\n raw.message.messageContextInfo?.messageSecret ?? content.messageContextInfo?.messageSecret;\n if (!poll || !secret) return;\n this.#polls.delete(id);\n this.#polls.set(id, {\n key: raw.key,\n secret,\n hashes: (poll.options ?? []).map((o) => sha256Hex(o.optionName ?? '')),\n });\n if (this.#polls.size > this.#max) {\n const oldest = this.#polls.keys().next().value;\n if (oldest !== undefined) this.#polls.delete(oldest);\n }\n }\n\n get(id: string): KnownPoll | undefined {\n return this.#polls.get(id);\n }\n\n clear(): void {\n this.#polls.clear();\n }\n}\n\n/** O `pollUpdateMessage` da mensagem, se ela for um voto. */\nexport function pollUpdateOf(raw: WAMessage): proto.Message.IPollUpdateMessage | null {\n return raw.message ? (unwrap(raw.message).content.pollUpdateMessage ?? null) : null;\n}\n\n/**\n * `poll.vote` a partir do `pollUpdateMessage`. Devolve `null` quando a enquete não está no\n * `PollBook` (enviada antes da conexão atual, por exemplo) e lança quando ela está, mas o voto não\n * decifra.\n */\nexport async function toPollVote(\n raw: WAMessage,\n polls: PollBook,\n env: Env,\n contacts: ContactBook,\n): Promise<TransportEvents['poll.vote'] | null> {\n const update = pollUpdateOf(raw);\n const pollKey = update?.pollCreationMessageKey;\n const chatId = raw.key.remoteJid;\n if (!update?.vote || !pollKey?.id || !chatId) return null;\n const poll = polls.get(pollKey.id);\n if (poll === undefined) return null;\n const vote = decrypt(update.vote, poll, pollKey, raw.key, env.selfIds);\n if (vote === null) throw new Error('baileys: o voto da enquete não decifrou');\n const options = new Set<number>();\n for (const hash of vote.selectedOptions ?? []) {\n const index = poll.hashes.indexOf(Buffer.from(hash).toString('hex'));\n // Hash fora da lista: opção que esta enquete não tem. Fica de fora em vez de virar índice.\n if (index >= 0) options.add(index);\n }\n return {\n chat: chatOf(chatId),\n messageId: pollKey.id,\n sender: contacts.named(await authorOf(raw.key, chatId, env, raw.pushName ?? null)),\n options: [...options].sort((a, b) => a - b),\n fromMe: raw.key.fromMe === true,\n };\n}\n\n/**\n * Decifra o voto. A chave sai do JID de quem criou e de quem votou, como o aparelho do votante os\n * viu, e com o LID ele pode ter usado o telefone ou o LID: tenta cada par conhecido.\n */\nfunction decrypt(\n vote: proto.Message.IPollEncValue,\n poll: KnownPoll,\n pollKey: proto.IMessageKey,\n voteKey: WAMessageKey,\n selfIds: readonly string[],\n): proto.Message.PollVoteMessage | null {\n const creators = unique([...jidsOf(poll.key, selfIds), ...jidsOf(pollKey, selfIds)]);\n const voters = unique(jidsOf(voteKey, selfIds));\n const pollMsgId = pollKey.id ?? '';\n for (const pollCreatorJid of creators) {\n for (const voterJid of voters) {\n const decrypted = tryDecrypt(vote, {\n pollCreatorJid,\n pollMsgId,\n pollEncKey: poll.secret,\n voterJid,\n });\n if (decrypted !== null) return decrypted;\n }\n }\n return null;\n}\n\nfunction tryDecrypt(\n vote: proto.Message.IPollEncValue,\n context: Parameters<typeof decryptPollVote>[1],\n): proto.Message.PollVoteMessage | null {\n try {\n return decryptPollVote(vote, context);\n } catch {\n // Par de JIDs errado: a autenticação do AES-GCM falha, e o próximo par é tentado.\n return null;\n }\n}\n\n/** JIDs possíveis do autor de uma chave: o da sessão, o do participante ou o do chat privado. */\nfunction jidsOf(\n key: proto.IMessageKey & { participantAlt?: string; remoteJidAlt?: string },\n selfIds: readonly string[],\n): string[] {\n if (key.fromMe) return [...selfIds];\n const jids = key.participant\n ? [key.participant, key.participantAlt]\n : [key.remoteJid, key.remoteJidAlt];\n return jids.flatMap((jid) => (jid ? [jidNormalizedUser(jid) || jid] : []));\n}\n\nfunction unique(values: readonly string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction sha256Hex(text: string): string {\n return createHash('sha256').update(text).digest('hex');\n}\n","// Transport do WhatsApp sobre o Baileys (M2-1). Este módulo cuida da conexão: socket, QR ou\n// código de pareamento, credenciais no storage do bot e o motivo de cada queda. Quem decide\n// reconectar é o `Bot`, pela `ReconnectionPolicy` (ADR 0048). As mensagens recebidas passam\n// pela normalização (`normalize.ts`) antes de virar o evento `message`, e os demais eventos do\n// Baileys (reação, edição, apagamento, grupos) são convertidos em `events.ts`; o envio e as\n// demais ações traduzem o formato do core em `outgoing.ts`.\n\nimport { Readable } from 'node:stream';\nimport type {\n Capability,\n Contact,\n FormattedText,\n GroupMetadata,\n GroupParticipantAction,\n Logger,\n Message,\n MessageKey,\n OutgoingContent,\n SendOptions,\n TypingKind,\n Unsubscribe,\n} from '@usebridger/core';\nimport {\n type Interaction,\n type Transport,\n type TransportDeps,\n type TransportEventHandler,\n type TransportEventName,\n type TransportEvents,\n TypedEmitter,\n} from '@usebridger/core/adapter';\nimport {\n type AnyMessageContent,\n type AuthenticationState,\n type Contact as BaileysContact,\n type BaileysEventMap,\n type GroupMetadata as BaileysGroupMetadata,\n downloadMediaMessage,\n isJidGroup,\n isJidStatusBroadcast,\n jidDecode,\n jidNormalizedUser,\n type MiscMessageGenerationOptions,\n type ParticipantAction,\n type WAMessage,\n WAMessageStubType,\n type WAPresence,\n type WAVersion,\n} from 'baileys';\nimport { loadAuthState } from './auth-state.ts';\nimport { toDisconnectReason } from './disconnect-reason.ts';\nimport {\n ContactBook,\n chatOf,\n toDeleted,\n toEdited,\n toGroupUpdated,\n toParticipantEvents,\n toReaction,\n} from './events.ts';\nimport { renderWhatsApp } from './format.ts';\nimport { type ILogger, toBaileysLogger } from './logger.ts';\nimport { type NormalizeEnv, nativeOf, toMessage } from './normalize.ts';\nimport { toContent, toGroupMetadata, toQuoted, toWAKey } from './outgoing.ts';\nimport { PollBook, pollUpdateOf, toPollVote } from './polls.ts';\n\n/** Como parear uma sessão sem credenciais: escaneando o QR ou digitando um código no aparelho. */\nexport type BaileysPairing = 'qr' | { readonly phone: string };\n\n/** O que o transport usa do socket do Baileys; nos testes, um socket falso. */\nexport interface BaileysSocket {\n readonly ev: {\n on<E extends keyof BaileysEventMap>(\n event: E,\n listener: (arg: BaileysEventMap[E]) => void,\n ): void;\n };\n readonly user: BaileysContact | undefined;\n /** Mapeamento LID ↔ telefone que o Baileys aprende com a sessão. */\n readonly signalRepository: {\n readonly lidMapping: { getPNForLID(lid: string): Promise<string | null> };\n };\n end(error: Error | undefined): Promise<void>;\n requestPairingCode(phoneNumber: string): Promise<string>;\n /** Pede ao aparelho que reenvie uma mídia cujo link expirou. */\n updateMediaMessage(message: WAMessage): Promise<WAMessage>;\n sendMessage(\n jid: string,\n content: AnyMessageContent,\n options?: MiscMessageGenerationOptions,\n ): Promise<WAMessage | undefined>;\n sendPresenceUpdate(type: WAPresence, toJid?: string): Promise<void>;\n groupMetadata(jid: string): Promise<BaileysGroupMetadata>;\n groupParticipantsUpdate(\n jid: string,\n participants: string[],\n action: ParticipantAction,\n ): Promise<readonly { readonly status: string; readonly jid: string | undefined }[]>;\n}\n\nexport interface SocketConfig {\n readonly auth: AuthenticationState;\n readonly logger: ILogger;\n readonly version: WAVersion;\n /** Metadados de grupo já conhecidos: o envio em grupo não consulta o servidor de novo. */\n readonly cachedGroupMetadata: (jid: string) => Promise<BaileysGroupMetadata | undefined>;\n}\n\n/** Acesso ao Baileys que tem efeito fora do processo; os testes trocam pelos falsos. */\nexport interface BaileysDriver {\n makeSocket(config: SocketConfig): BaileysSocket;\n /** Versão do protocolo do WhatsApp Web a anunciar. */\n version(): Promise<WAVersion>;\n}\n\nexport interface BaileysTransportOptions {\n readonly pairing: BaileysPairing;\n readonly driver: BaileysDriver;\n}\n\nexport class BaileysTransport implements Transport {\n readonly name = 'baileys';\n /**\n * Todas as capabilities do core, menos `actions`: o WhatsApp pelo Baileys não tem botões\n * confiáveis, e o kernel envia o menu em texto numerado (ADR 0062).\n */\n readonly capabilities: ReadonlySet<Capability> = new Set<Capability>([\n 'groups',\n 'groups.add',\n 'groups.remove',\n 'groups.promote',\n 'mentions',\n 'reactions',\n 'typing',\n 'send.text',\n 'send.image',\n 'send.video',\n 'send.audio',\n 'send.voice',\n 'send.sticker',\n 'send.document',\n 'media.download',\n 'message.edit',\n 'message.delete',\n 'polls',\n 'quoted',\n // Pareia por QR ou código: credencial rejeitada limpa a sessão e pareia de novo (ADR 0068).\n 'pairing',\n ]);\n\n readonly #pairing: BaileysPairing;\n readonly #driver: BaileysDriver;\n readonly #deps: TransportDeps;\n readonly #events: TypedEmitter<TransportEvents>;\n #socket: BaileysSocket | null = null;\n #self: Contact | null = null;\n /** Sobe a cada `connect()`/`disconnect()`: invalida a tentativa que ainda estava começando. */\n #attempt = 0;\n /**\n * Metadados por grupo (ADR 0046): o kernel os pede a cada comando `group-admin`. Invalidado\n * pelos eventos de grupo do Baileys e a cada conexão, porque a queda pode ter perdido algum.\n */\n readonly #groups = new Map<string, Promise<BaileysGroupMetadata>>();\n /** Contatos já vistos, entre conexões: o `contact.updated` sai só no que é novo. */\n readonly #contacts = new ContactBook();\n /** Enquetes vistas, para decifrar os votos (ADR 0071); o `disconnect()` as esquece. */\n readonly #polls = new PollBook();\n\n constructor(options: BaileysTransportOptions, deps: TransportDeps) {\n this.#pairing = options.pairing;\n this.#driver = options.driver;\n this.#deps = deps;\n this.#events = new TypedEmitter<TransportEvents>((error, event) =>\n this.#log.error('handler de evento do transport falhou', { err: error, event }),\n );\n }\n\n get self(): Contact | null {\n return this.#self;\n }\n\n /** O socket do Baileys (`WASocket`) da tentativa atual, ou `null` sem conexão. */\n get native(): unknown {\n return this.#socket;\n }\n\n /**\n * O `WAMessage` de onde a mensagem saiu (ADR 0066), o mesmo que o envio usa para citar. A citada\n * devolve o proto montado do `contextInfo`, sem `pushName` nem horário. O Baileys não emite\n * `interaction`: para ela, e para mensagem que não veio daqui, `undefined`.\n */\n raw(source: Message | Interaction): unknown {\n return 'key' in source ? nativeOf(source) : undefined;\n }\n\n get #log(): Logger {\n return this.#deps.log;\n }\n\n on<E extends TransportEventName>(event: E, handler: TransportEventHandler<E>): Unsubscribe {\n return this.#events.on(event, handler);\n }\n\n async connect(): Promise<void> {\n const attempt = ++this.#attempt;\n // Reconexão: o socket anterior já caiu, mas pode ainda estar de pé se alguém chamou\n // `connect()` duas vezes. Os eventos dele deixam de valer a partir daqui.\n this.#endSocket();\n const version = await this.#driver.version();\n const logger = toBaileysLogger(this.#log.child({ lib: 'baileys' }));\n const { state, saveCreds } = await loadAuthState(this.#deps.auth, logger);\n // `disconnect()` ou outro `connect()` enquanto as credenciais carregavam.\n if (attempt !== this.#attempt) return;\n\n this.#groups.clear();\n const socket = this.#driver.makeSocket({\n auth: state,\n logger,\n version,\n cachedGroupMetadata: (jid) => this.#cachedGroup(jid),\n });\n this.#socket = socket;\n const current = (): boolean => this.#socket === socket;\n // Gravações em fila: uma `creds.update` não pode sobrescrever a seguinte fora de ordem.\n let saving = Promise.resolve();\n // Mostrou QR/código e não abriu: o 408 que vier é o pareamento que expirou.\n let pairing = false;\n let codeRequested = false;\n\n socket.ev.on('creds.update', () => {\n if (!current()) return;\n saving = saving.then(saveCreds).catch((error: unknown) => {\n this.#log.error('falha ao gravar as credenciais da sessão', { err: error });\n });\n });\n\n // Em fila: a conversão é assíncrona (telefone de LID) e não pode inverter a ordem de\n // chegada, que a fila de entrada do bot preserva por chat. Reação, edição e apagamento entram\n // na mesma fila: a edição de uma mensagem não passa à frente dela.\n let inbound = Promise.resolve();\n const enqueue = (work: () => Promise<void>, failure: string, messageId?: string | null) => {\n inbound = inbound.then(work).catch((error: unknown) => {\n this.#log.error(failure, { err: error, messageId });\n });\n };\n const env = this.#normalizeEnv(socket, state, logger);\n const contacts = this.#contacts;\n const polls = this.#polls;\n\n socket.ev.on('messages.upsert', ({ messages, type }) => {\n if (!current()) return;\n // `append` é histórico e cópia de sincronização; só `notify` é mensagem nova.\n if (type !== 'notify') return;\n for (const raw of messages) {\n // Status (stories) não é conversa: fica de fora até haver um evento para ele.\n if (raw.key.remoteJid && isJidStatusBroadcast(raw.key.remoteJid)) continue;\n enqueue(\n async () => {\n // Na fila, como o resto: o voto chega depois da enquete e já a encontra guardada, e\n // um proto malformado descarta só esta mensagem.\n polls.remember(raw);\n if (pollUpdateOf(raw) !== null) {\n const vote = await toPollVote(raw, polls, env, contacts);\n if (vote === null) {\n this.#log.debug('voto de enquete desconhecida; descartado', {\n messageId: raw.key.id,\n });\n } else if (current()) {\n this.#events.emit('poll.vote', vote);\n }\n return;\n }\n const message = await toMessage(raw, env);\n if (message === null || !current()) return;\n // Antes da mensagem: quem guarda nomes já o tem ao tratá-la.\n const contact = message.fromMe ? null : contacts.observe(message.sender);\n if (contact !== null) this.#events.emit('contact.updated', contact);\n this.#events.emit('message', message);\n },\n 'falha ao normalizar mensagem do Baileys; descartada',\n raw.key.id,\n );\n }\n });\n\n socket.ev.on('messages.reaction', (reactions) => {\n if (!current()) return;\n for (const item of reactions) {\n enqueue(\n async () => {\n const reaction = await toReaction(item, env, contacts);\n if (reaction !== null && current()) this.#events.emit('reaction', reaction);\n },\n 'falha ao converter reação do Baileys; descartada',\n item.key.id,\n );\n }\n });\n\n socket.ev.on('messages.update', (updates) => {\n if (!current()) return;\n // A maior parte é recibo de entrega e leitura, que não tem evento no core.\n for (const item of updates) {\n if (item.update.message?.editedMessage) {\n enqueue(\n async () => {\n const message = await toEdited(item, env, contacts);\n if (message !== null && current()) this.#events.emit('message.edited', message);\n },\n 'falha ao converter edição do Baileys; descartada',\n item.key.id,\n );\n } else if (item.update.messageStubType === WAMessageStubType.REVOKE) {\n enqueue(\n async () => {\n const deleted = await toDeleted(item, env, contacts);\n if (deleted !== null && current()) this.#events.emit('message.deleted', deleted);\n },\n 'falha ao converter apagamento do Baileys; descartado',\n item.key.id,\n );\n }\n }\n });\n\n // Grupo criado com a sessão dentro: o Baileys avisa pelo `groups.upsert`, não pelos\n // participantes.\n socket.ev.on('groups.upsert', (groups) => {\n if (!current()) return;\n for (const { id } of groups) {\n enqueue(async () => {\n if (current()) this.#events.emit('group.joined', { chat: chatOf(id) });\n }, 'falha ao repassar grupo novo');\n }\n });\n socket.ev.on('groups.update', (updates) => {\n if (!current()) return;\n for (const update of updates) {\n if (update.id) this.#groups.delete(update.id);\n const changed = toGroupUpdated(update);\n if (changed === null) continue;\n enqueue(async () => {\n if (current()) this.#events.emit('group.updated', changed);\n }, 'falha ao repassar alteração de grupo');\n }\n });\n socket.ev.on('group-participants.update', (update) => {\n if (!current()) return;\n this.#groups.delete(update.id);\n enqueue(async () => {\n const { self, others } = await toParticipantEvents(update, env, contacts);\n if (!current()) return;\n if (self !== null) this.#events.emit(self, { chat: chatOf(update.id) });\n if (others !== null) this.#events.emit('group.participants', others);\n }, 'falha ao converter alteração de participantes do Baileys; descartada');\n });\n\n socket.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {\n if (!current()) return;\n if (qr !== undefined) {\n pairing = true;\n if (this.#pairing === 'qr') {\n this.#events.emit('connection.qr', { qr });\n } else if (!codeRequested && !state.creds.registered) {\n // Um código por tentativa: o Baileys segue girando o QR, mas o código vale até a\n // tentativa expirar (408), e aí a política pede outro.\n codeRequested = true;\n this.#requestPairingCode(socket, this.#pairing.phone);\n }\n }\n switch (connection) {\n case 'connecting':\n this.#events.emit('connection.status', { status: 'connecting' });\n return;\n case 'open':\n pairing = false;\n this.#self = socket.user ? toContact(socket.user) : null;\n this.#events.emit('connection.status', { status: 'open' });\n return;\n case 'close': {\n this.#socket = null;\n const error = lastDisconnect?.error;\n const reason = toDisconnectReason(error, { pairing });\n this.#events.emit('connection.status', { status: 'closed', reason, error });\n return;\n }\n }\n });\n }\n\n async disconnect(): Promise<void> {\n this.#attempt++;\n this.#endSocket();\n this.#polls.clear();\n }\n\n /** Encerra o socket atual sem emitir nada: quem chamou já sabe que a conexão acabou. */\n #endSocket(): void {\n const socket = this.#socket;\n if (socket === null) return;\n this.#socket = null;\n socket.end(undefined).catch((error: unknown) => {\n this.#log.warn('falha ao encerrar o socket do Baileys', { err: error });\n });\n }\n\n #normalizeEnv(socket: BaileysSocket, state: AuthenticationState, logger: ILogger): NormalizeEnv {\n const media = { reuploadRequest: (m: WAMessage) => socket.updateMediaMessage(m), logger };\n return {\n // Lido a cada mensagem: no primeiro pareamento o `me` só chega depois do socket criado.\n get selfIds() {\n const me = state.creds.me;\n return [me?.id, me?.lid].flatMap((id) => (id ? [jidNormalizedUser(id)] : []));\n },\n pnForLid: (lid) => this.#pnForLid(socket, lid),\n download: (raw) => downloadMediaMessage(raw, 'buffer', {}, media),\n stream: async (raw) =>\n Readable.toWeb(\n await downloadMediaMessage(raw, 'stream', {}, media),\n ) as ReadableStream<Uint8Array>,\n };\n }\n\n #pnForLid(socket: BaileysSocket, lid: string): Promise<string | null> {\n return socket.signalRepository.lidMapping.getPNForLID(lid).catch((error: unknown) => {\n // Sem o par, o contato segue com `phone: null`: os papéis falham fechados (ADR 0046).\n this.#log.warn('falha ao resolver o telefone de um LID', { err: error, lid });\n return null;\n });\n }\n\n #requestPairingCode(socket: BaileysSocket, phone: string): void {\n socket.requestPairingCode(phone).then(\n (code) => {\n if (this.#socket === socket) this.#events.emit('connection.pairing-code', { code });\n },\n (error: unknown) => {\n // Sem código, a tentativa expira (`qr-timeout`) e a próxima pede outro.\n this.#log.error('falha ao pedir o código de pareamento', { err: error });\n },\n );\n }\n\n async send(chatId: string, content: OutgoingContent, options?: SendOptions): Promise<MessageKey> {\n const sent = await this.#connected().sendMessage(\n chatId,\n toContent(content, options),\n options?.quoted ? { quoted: toQuoted(options.quoted) } : undefined,\n );\n const id = sent?.key.id;\n // O Baileys só devolve `undefined` para conteúdo que não vira mensagem (ex.: apagar); sem a\n // chave, não daria para reagir, editar nem apagar depois.\n if (!id) throw new Error('baileys: o envio não devolveu a chave da mensagem');\n // O segredo que cifra os votos só existe na mensagem enviada.\n if (content.type === 'poll' && sent) this.#polls.remember(sent);\n return {\n chatId,\n id,\n fromMe: true,\n senderId: isJidGroup(chatId) ? (this.#self?.id ?? null) : null,\n };\n }\n\n async react(key: MessageKey, emoji: string | null): Promise<void> {\n // Texto vazio é como o WhatsApp remove a reação.\n await this.#connected().sendMessage(key.chatId, {\n react: { text: emoji ?? '', key: toWAKey(key) },\n });\n }\n\n async edit(key: MessageKey, text: string, formatted?: FormattedText): Promise<void> {\n if (!formatted) {\n await this.#connected().sendMessage(key.chatId, { text, edit: toWAKey(key) });\n return;\n }\n const rendered = renderWhatsApp(formatted);\n await this.#connected().sendMessage(key.chatId, {\n text: rendered.text,\n edit: toWAKey(key),\n ...(rendered.mentions.length > 0 && { mentions: [...rendered.mentions] }),\n });\n }\n\n async delete(key: MessageKey): Promise<void> {\n await this.#connected().sendMessage(key.chatId, { delete: toWAKey(key) });\n }\n\n async sendTyping(chatId: string, kind: TypingKind): Promise<void> {\n await this.#connected().sendPresenceUpdate(\n kind === 'voice' ? 'recording' : 'composing',\n chatId,\n );\n }\n\n async getGroupMetadata(groupId: string): Promise<GroupMetadata> {\n const socket = this.#connected();\n let native = this.#groups.get(groupId);\n if (native === undefined) {\n const fetching = socket.groupMetadata(groupId);\n native = fetching;\n this.#groups.set(groupId, fetching);\n // Falha não fica no cache: a próxima chamada consulta de novo. O erro chega ao chamador\n // pela própria promise; este handler só limpa a entrada.\n fetching.catch(() => {\n if (this.#groups.get(groupId) === fetching) this.#groups.delete(groupId);\n });\n }\n return toGroupMetadata(await native, { pnForLid: (lid) => this.#pnForLid(socket, lid) });\n }\n\n async updateGroupParticipants(\n groupId: string,\n participantIds: readonly string[],\n action: GroupParticipantAction,\n ): Promise<void> {\n const results = await this.#connected().groupParticipantsUpdate(\n groupId,\n [...participantIds],\n action,\n );\n // Os participantes mudaram mesmo que o evento do Baileys ainda não tenha chegado.\n this.#groups.delete(groupId);\n // O servidor responde por participante; fora do 200, aquele falhou (ex.: 403 sem ser admin,\n // 409 já no grupo). Falha parcial também lança: quem chamou precisa saber.\n const failed = results.filter((r) => r.status !== '200');\n if (failed.length > 0) {\n const list = failed.map((r) => `${r.jid ?? '?'} (${r.status})`).join(', ');\n throw new Error(`baileys: ${action} recusado para ${list}`);\n }\n }\n\n /** Socket da conexão atual; sem ele, a ação falha na hora em vez de esperar. */\n #connected(): BaileysSocket {\n if (this.#socket === null) throw new Error('baileys: sem conexão');\n return this.#socket;\n }\n\n /** Para o envio em grupo: usa a consulta que já existe, sem disparar outra. */\n async #cachedGroup(jid: string): Promise<BaileysGroupMetadata | undefined> {\n return this.#groups.get(jid)?.catch(() => undefined);\n }\n}\n\n/** A própria sessão: o `id` do Baileys traz o aparelho (`5511…:12@s.whatsapp.net`). */\nfunction toContact(user: BaileysContact): Contact {\n const id = jidNormalizedUser(user.id);\n const jid = jidDecode(id);\n const phone =\n jid?.server === 's.whatsapp.net' ? jid.user : (jidDecode(user.phoneNumber)?.user ?? null);\n return { id, name: user.name ?? user.notify ?? null, phone };\n}\n","// Entry `@usebridger/transport-baileys`: a fábrica que o app passa em `createBot({ transport })`\n// (ADR 0037). A classe fica interna: o transport precisa das dependências do bot.\n\nimport type { Transport, TransportDeps } from '@usebridger/core/adapter';\nimport { Browsers, fetchLatestBaileysVersion, makeWASocket, type WAVersion } from 'baileys';\nimport { type BaileysDriver, type BaileysPairing, BaileysTransport } from './transport.ts';\n\nexport type { BaileysPairing } from './transport.ts';\n\nexport interface BaileysOptions {\n /**\n * Como parear quando a sessão não tem credenciais: `'qr'` (padrão) emite `connection.qr`;\n * `{ phone }` pede um código de pareamento para o número (só dígitos, com DDI) e emite\n * `connection.pairing-code`.\n */\n readonly pairing?: BaileysPairing;\n /**\n * Versão do WhatsApp Web a anunciar. Sem ela, o transport busca a mais recente na primeira\n * conexão e, se a busca falhar, usa a que vem com o Baileys.\n */\n readonly version?: WAVersion;\n}\n\nexport function baileys(options: BaileysOptions = {}): (deps: TransportDeps) => Transport {\n const pairing = options.pairing ?? 'qr';\n // Na fábrica, um número inválido vira `BotConfigError` no `createBot`, antes de qualquer\n // conexão.\n if (pairing !== 'qr' && !/^\\d{8,15}$/.test(pairing.phone)) {\n throw new TypeError(\n `baileys: pairing.phone deve ter só dígitos, com DDI (ex.: 5511999999999); recebido \"${pairing.phone}\"`,\n );\n }\n return (deps) => new BaileysTransport({ pairing, driver: driver(options.version, deps) }, deps);\n}\n\nfunction driver(fixed: WAVersion | undefined, deps: TransportDeps): BaileysDriver {\n let latest: Promise<WAVersion> | undefined;\n return {\n makeSocket: ({ auth, logger, version, cachedGroupMetadata }) =>\n makeWASocket({\n auth,\n logger,\n version,\n cachedGroupMetadata,\n browser: Browsers.ubuntu('Chrome'),\n }),\n version: () => {\n if (fixed) return Promise.resolve(fixed);\n // Uma busca por transport: a versão não muda entre reconexões do mesmo processo.\n latest ??= fetchLatestBaileysVersion().then(({ version, error }) => {\n if (error !== undefined) {\n deps.log.warn('não deu para buscar a versão do WhatsApp Web; usando a do Baileys', {\n err: error,\n });\n }\n return version;\n });\n return latest;\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["Code"],"sources":["../src/logger.ts","../src/auth-state.ts","../src/console.ts","../src/disconnect-reason.ts","../src/normalize.ts","../src/events.ts","../src/format.ts","../src/outgoing.ts","../src/polls.ts","../src/transport.ts","../src/index.ts"],"sourcesContent":["// O Baileys loga no formato do pino (`logger.info(obj, msg)`); o bot, no do core\n// (`log.info(msg, fields)`). Este adapter traduz um para o outro, para as linhas do Baileys\n// passarem pelo logger do bot, com a censura de segredos dele (ADR 0032).\n\nimport type { LogFields, Logger, LogLevel } from '@usebridger/core';\nimport type { SocketConfig } from 'baileys';\n\n/** Logger que o Baileys aceita; o pacote não exporta o `ILogger` pela entrada principal. */\nexport type ILogger = SocketConfig['logger'];\n\ntype Method = 'trace' | 'debug' | 'info' | 'warn' | 'error';\n\nconst RANK: Readonly<Record<LogLevel, number>> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n silent: Number.POSITIVE_INFINITY,\n};\n\n/** Valida níveis vindos de fora do sistema de tipos (opção em JS). */\nexport function isLogLevel(value: unknown): value is LogLevel {\n return typeof value === 'string' && Object.hasOwn(RANK, value);\n}\n\n/**\n * `floor` é o nível mínimo das linhas do Baileys, além do nível do bot: vale o mais alto dos\n * dois. Sem ele, só o do bot.\n */\nexport function toBaileysLogger(log: Logger, floor: LogLevel = 'trace'): ILogger {\n /** O mais alto entre o nível do bot e o piso. */\n const effective = (): LogLevel => (RANK[log.level] >= RANK[floor] ? log.level : floor);\n const write = (method: Method) => {\n const rank = RANK[method];\n return (obj: unknown, msg?: string): void => {\n if (rank < RANK[floor]) return;\n if (typeof obj === 'string') log[method](obj);\n else log[method](msg ?? '', toFields(obj));\n };\n };\n return {\n // O Baileys consulta o nível para pular logs caros; lido a cada vez porque o logger da\n // fábrica só passa a valer no `start()`.\n get level(): string {\n return effective();\n },\n child: (bindings) => toBaileysLogger(log.child(bindings), floor),\n trace: write('trace'),\n debug: write('debug'),\n info: write('info'),\n warn: write('warn'),\n error: write('error'),\n };\n}\n\nfunction toFields(obj: unknown): LogFields | undefined {\n if (obj instanceof Error) return { err: obj };\n if (typeof obj === 'object' && obj !== null) return obj as LogFields;\n return obj === undefined ? undefined : { value: obj };\n}\n","// Auth state do Baileys sobre o `AuthStateStore` do bot (ADR 0014/0037), no lugar do\n// `useMultiFileAuthState`. O store só guarda JSON; os `Buffer`/`Uint8Array` do Baileys vão e\n// voltam pelo `BufferJSON`, como no arquivo que o `useMultiFileAuthState` gravaria.\n\nimport type { JsonValue } from '@usebridger/core';\nimport type { AuthKeyData, AuthStateStore } from '@usebridger/core/adapter';\nimport {\n type AuthenticationState,\n BufferJSON,\n initAuthCreds,\n makeCacheableSignalKeyStore,\n proto,\n type SignalDataSet,\n type SignalDataTypeMap,\n} from 'baileys';\nimport type { ILogger } from './logger.ts';\n\nexport interface StoredAuthState {\n readonly state: AuthenticationState;\n /** Grava as credenciais atuais. O Baileys as altera no lugar antes de emitir `creds.update`. */\n readonly saveCreds: () => Promise<void>;\n}\n\n/**\n * Monta o auth state de uma tentativa de conexão. As chaves passam por um cache em memória\n * (o do Baileys, 5 min por chave): o Signal lê a sessão do remetente a cada mensagem, e sem ele\n * cada leitura iria ao storage e repetiria a conversão do `BufferJSON`. O cache vive só nesta\n * tentativa: depois de um `clear()` do bot, a próxima começa vazia e não ressuscita chave\n * apagada. Ele não vê gravações de outro processo, o que não acontece porque a mesma sessão\n * não roda em dois (ADR 0036).\n */\nexport async function loadAuthState(\n store: AuthStateStore,\n logger: ILogger,\n): Promise<StoredAuthState> {\n const stored = await store.getCreds();\n const creds = stored === undefined ? initAuthCreds() : fromJson(stored);\n const cached = makeCacheableSignalKeyStore(\n {\n get: async (type, ids) => {\n const raw = await store.getKeys(type, ids);\n const keys: { [id: string]: SignalDataTypeMap[typeof type] } = {};\n for (const [id, value] of Object.entries(raw)) {\n keys[id] =\n type === 'app-state-sync-key' ? toSyncKeyInstance(fromJson(value)) : fromJson(value);\n }\n return keys;\n },\n set: (data) => store.setKeys(toKeyData(data)),\n },\n logger,\n );\n return {\n state: {\n creds,\n keys: {\n // O cache guarda o `null` de uma chave apagada e o devolve; aqui ela some do resultado,\n // como na leitura direta do storage.\n get: async (type, ids) => {\n const found = await cached.get(type, ids);\n for (const id of Object.keys(found)) {\n if (found[id] === null || found[id] === undefined) delete found[id];\n }\n return found;\n },\n // O cache guarda o que recebe; convertido aqui, ele devolve o mesmo que o storage.\n set: (data) => cached.set(withSyncKeyInstances(data)),\n },\n },\n saveCreds: () => store.setCreds(toJson(creds)),\n };\n}\n\n// O Baileys espera a instância do protobuf, não o objeto cru (como no `useMultiFileAuthState`).\nfunction toSyncKeyInstance(value: object): proto.Message.AppStateSyncKeyData {\n return value instanceof proto.Message.AppStateSyncKeyData\n ? value\n : proto.Message.AppStateSyncKeyData.fromObject(value);\n}\n\nfunction withSyncKeyInstances(data: SignalDataSet): SignalDataSet {\n const syncKeys = data['app-state-sync-key'];\n if (syncKeys === undefined) return data;\n const converted: SignalDataSet['app-state-sync-key'] = {};\n for (const [id, value] of Object.entries(syncKeys)) {\n converted[id] = value ? toSyncKeyInstance(value) : value;\n }\n return { ...data, 'app-state-sync-key': converted };\n}\n\nfunction toKeyData(data: SignalDataSet): AuthKeyData {\n const out: Record<string, Record<string, JsonValue | null>> = {};\n for (const [type, entries] of Object.entries(data)) {\n const converted: Record<string, JsonValue | null> = {};\n for (const [id, value] of Object.entries(entries ?? {})) {\n converted[id] = value === null || value === undefined ? null : toJson(value);\n }\n out[type] = converted;\n }\n return out;\n}\n\nfunction toJson(value: unknown): JsonValue {\n return JSON.parse(JSON.stringify(value, BufferJSON.replacer)) as JsonValue;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: o tipo vem de quem chama; o JSON já foi validado na gravação.\nfunction fromJson(value: JsonValue): any {\n return JSON.parse(JSON.stringify(value), BufferJSON.reviver);\n}\n","// O libsignal, que o Baileys usa para a criptografia, escreve direto no `console`\n// (`Closing session: SessionEntry {...}`), sem logger para configurar. Enquanto um socket está\n// aberto, as chamadas cujo chamador direto é um arquivo do libsignal vão para o logger do\n// Baileys, com o mesmo piso de nível; o resto do `console` passa intacto (ADR 0091).\n\nimport type { ILogger } from './logger.ts';\n\nconst METHODS = ['log', 'info', 'warn', 'error', 'debug'] as const;\ntype Method = (typeof METHODS)[number];\n\n/** Arquivo do pacote `libsignal` (no pnpm: `.pnpm/libsignal@x/node_modules/libsignal/src/...`). */\nconst LIBSIGNAL_FRAME = /[\\\\/]node_modules[\\\\/]libsignal[\\\\/]/;\n\n// Um desvio por processo, não por transport: o `console` é global. Com várias sessões, as linhas\n// vão para o logger do socket aberto mais recente, porque o libsignal não diz de qual sessão é.\nconst active: ILogger[] = [];\ntype ConsoleFn = (...args: unknown[]) => void;\nconst installed = new Map<Method, { readonly original: ConsoleFn; readonly wrapper: ConsoleFn }>();\n\n/** Liga o desvio para `logger`; devolve a função que o desliga (idempotente). */\nexport function routeLibsignalConsole(logger: ILogger): () => void {\n if (active.length === 0) install();\n active.push(logger);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n active.splice(active.indexOf(logger), 1);\n if (active.length === 0) uninstall();\n };\n}\n\nfunction install(): void {\n for (const method of METHODS) {\n const original: ConsoleFn = console[method];\n const wrapper: ConsoleFn = (...args) => {\n const target = active.at(-1);\n if (target === undefined || !calledFromLibsignal(wrapper)) {\n original.apply(console, args);\n return;\n }\n write(target, method, args);\n };\n installed.set(method, { original, wrapper });\n console[method] = wrapper;\n }\n}\n\nfunction uninstall(): void {\n for (const [method, { original, wrapper }] of installed) {\n // Quem trocou o método depois de nós fica com a troca dele; o nosso wrapper, que ficou na\n // cadeia dele, sem desvio ativo só repassa ao original.\n if (console[method] === wrapper) console[method] = original;\n }\n installed.clear();\n}\n\n/** O chamador direto de `wrapper` é um arquivo do libsignal. */\nfunction calledFromLibsignal(wrapper: ConsoleFn): boolean {\n // Só o primeiro quadro abaixo do `wrapper`: um callback do app chamado de dentro do libsignal\n // continua no `console` dele.\n const limit = Error.stackTraceLimit;\n Error.stackTraceLimit = 1;\n const holder: { stack?: string } = {};\n Error.captureStackTrace(holder, wrapper);\n Error.stackTraceLimit = limit;\n return LIBSIGNAL_FRAME.test(holder.stack ?? '');\n}\n\nfunction write(logger: ILogger, method: Method, args: readonly unknown[]): void {\n // Só o texto: os objetos (`SessionEntry`, registros de sessão) carregam as chaves da sessão\n // e não podem ir para o log.\n const text = args.filter((arg): arg is string => typeof arg === 'string').join(' ');\n const fields = { source: 'libsignal' };\n // `console.error` do libsignal é falha de migração de sessão: vale um aviso. O resto é a\n // rotina de abrir e fechar sessões.\n if (method === 'error') logger.warn(fields, text);\n else logger.debug(fields, text);\n}\n","// Código de desconexão do Baileys → `DisconnectReason` do core. A `ReconnectionPolicy` decide em\n// cima dele, e `logged-out`/`auth-failed` apagam as credenciais: só entram aqui quando o aparelho\n// ou o servidor rejeitou a credencial de fato (ADR 0045).\n\nimport type { DisconnectReason } from '@usebridger/core';\nimport { DisconnectReason as Code } from 'baileys';\n\nexport interface CloseContext {\n /** Esta tentativa mostrou QR ou código de pareamento e ainda não abriu. */\n readonly pairing: boolean;\n}\n\nexport function toDisconnectReason(error: unknown, { pairing }: CloseContext): DisconnectReason {\n switch (statusCode(error)) {\n case Code.loggedOut:\n return 'logged-out';\n // Servidor recusou a credencial (403) ou o aparelho não reconhece mais esta sessão (411).\n case Code.forbidden:\n case Code.multideviceMismatch:\n return 'auth-failed';\n case Code.connectionReplaced:\n return 'replaced';\n // O Baileys usa 408 tanto para o QR que expirou quanto para a conexão que caiu.\n case Code.timedOut:\n return pairing ? 'qr-timeout' : 'connection-lost';\n // 515 é o restart que o servidor pede logo depois do pareamento: reconecta pela política\n // (ADR 0048).\n case Code.connectionClosed:\n case Code.restartRequired:\n return 'connection-lost';\n // 500 (`badSession`) é também o código de todo stream error sem motivo conhecido: tratá-lo\n // como credencial rejeitada apagaria a sessão por um erro qualquer. 405 vem quando o\n // servidor recusa a versão do cliente, não a credencial.\n case Code.badSession:\n case Code.unavailableService:\n case 405:\n return 'server-error';\n default:\n return 'unknown';\n }\n}\n\n/** O Baileys encerra com um `Boom`, que traz o código em `output.statusCode`. */\nfunction statusCode(error: unknown): number | undefined {\n if (typeof error !== 'object' || error === null || !('output' in error)) return undefined;\n const { output } = error;\n if (typeof output !== 'object' || output === null || !('statusCode' in output)) return undefined;\n return typeof output.statusCode === 'number' ? output.statusCode : undefined;\n}\n","// Normalização (M2-1.2): `WAMessage` do Baileys → `Message` do core (ADR 0009). Desembrulha os\n// envelopes (ephemeral, viewOnce, documentWithCaption), resolve o telefone de cada contato,\n// inclusive com LID (M1-16.4, ADR 0046), e monta a citada como `Message` também.\n\nimport type { Contact, Message } from '@usebridger/core';\nimport { createMessage, type MediaSource, type MessageInit } from '@usebridger/core/adapter';\nimport {\n isJidGroup,\n isLidUser,\n isPnUser,\n jidDecode,\n jidNormalizedUser,\n type proto,\n toNumber,\n type WAMessage,\n type WAMessageKey,\n} from 'baileys';\n\n/** O que a normalização precisa da sessão; o transport liga ao socket, os testes a falsos. */\nexport interface NormalizeEnv {\n /**\n * Ids da própria sessão sem aparelho, o JID de telefone primeiro e depois o LID. Dão o autor\n * das mensagens da sessão na conversa privada e o `fromMe` da citada.\n */\n readonly selfIds: readonly string[];\n /** JID de telefone de um LID, ou `null` se a sessão ainda não conhece o par. */\n pnForLid(lid: string): Promise<string | null>;\n download(raw: WAMessage): Promise<Buffer>;\n stream(raw: WAMessage): Promise<ReadableStream<Uint8Array>>;\n}\n\ntype Content = proto.IMessage;\n\n/** Envelopes que só embrulham o conteúdo de verdade. */\nconst ENVELOPES = [\n 'ephemeralMessage',\n 'viewOnceMessage',\n 'viewOnceMessageV2',\n 'viewOnceMessageV2Extension',\n 'documentWithCaptionMessage',\n // Ao contrário das outras versões, a V4 da enquete é um envelope com a enquete dentro.\n 'pollCreationMessageV4',\n] as const satisfies readonly (keyof Content)[];\n\nconst VIEW_ONCE: ReadonlySet<string> = new Set([\n 'viewOnceMessage',\n 'viewOnceMessageV2',\n 'viewOnceMessageV2Extension',\n]);\n\n/**\n * Campos que não são o conteúdo da mensagem. Edição, apagamento e reação chegam por eventos\n * próprios do Baileys (`events.ts`); o resto é metadado do protocolo.\n */\nconst CONTROL: ReadonlySet<string> = new Set([\n 'protocolMessage',\n 'reactionMessage',\n 'encReactionMessage',\n 'pollUpdateMessage',\n 'keepInChatMessage',\n 'pinInChatMessage',\n 'senderKeyDistributionMessage',\n 'fastRatchetKeySenderKeyDistributionMessage',\n 'messageContextInfo',\n]);\n\n/**\n * Tira os envelopes, em qualquer ordem e aninhados (ephemeral com viewOnce dentro, por exemplo).\n * O limite só protege de um proto malformado.\n */\nexport function unwrap(content: Content): { content: Content; viewOnce: boolean } {\n let current = content;\n let viewOnce = false;\n for (let depth = 0; depth < 10; depth++) {\n const envelope = ENVELOPES.find((name) => current[name]?.message);\n if (envelope === undefined) break;\n if (VIEW_ONCE.has(envelope)) viewOnce = true;\n current = current[envelope]?.message ?? current;\n }\n return { content: current, viewOnce };\n}\n\n/** Campo que define o tipo: o primeiro preenchido que não é de controle. */\nfunction contentKey(content: Content): keyof Content | undefined {\n return (Object.keys(content) as (keyof Content)[]).find(\n (key) => content[key] != null && !CONTROL.has(key),\n );\n}\n\n/**\n * Converte uma mensagem do Baileys. `null` quando não há o que entregar: sem conteúdo (aviso de\n * grupo, mensagem que não deu para decifrar) ou só controle (edição, reação, apagamento).\n */\nexport function toMessage(raw: WAMessage, env: NormalizeEnv): Promise<Message | null> {\n return build(raw, env, toNumber(raw.messageTimestamp) * 1000, false);\n}\n\n/**\n * Nova versão de uma mensagem editada, com `isEdited: true`. `raw` é a chave da original com o\n * conteúdo novo; o Baileys não manda o `pushName` na edição, então o nome vem de quem chama.\n */\nexport function toEditedMessage(raw: WAMessage, env: NormalizeEnv): Promise<Message | null> {\n return build(raw, env, toNumber(raw.messageTimestamp) * 1000, true);\n}\n\nasync function build(\n raw: WAMessage,\n env: NormalizeEnv,\n timestamp: number,\n isEdited: boolean,\n): Promise<Message | null> {\n const chatId = raw.key.remoteJid;\n const id = raw.key.id;\n if (!raw.message || !chatId || !id) return null;\n\n const { content, viewOnce } = unwrap(raw.message);\n const key = contentKey(content);\n if (key === undefined) return null;\n\n const isGroup = isJidGroup(chatId) === true;\n const fromMe = raw.key.fromMe === true;\n const node = content[key];\n const context = contextOf(node);\n const base: Base = {\n id,\n chat: { id: chatId, isGroup },\n sender: await authorOf(raw.key, chatId, env, raw.pushName ?? null),\n timestamp,\n fromMe,\n quoted: context ? await quoted(context, chatId, env, timestamp) : null,\n mentions: await Promise.all(\n (context?.mentionedJid ?? []).map((jid) => resolveContact(env, jid, undefined, null)),\n ),\n isForwarded: context?.isForwarded === true,\n isViewOnce: viewOnce || raw.key.isViewOnce === true || flag(node, 'viewOnce'),\n isEdited,\n };\n // O download parte da mensagem sem envelopes: é o formato que o Baileys espera.\n const unwrapped: WAMessage = { ...raw, message: content };\n const media: MediaOf = (m) => ({\n mimetype: m.mimetype ?? 'application/octet-stream',\n size: m.fileLength == null ? null : toNumber(m.fileLength) || null,\n download: () => env.download(unwrapped),\n stream: () => env.stream(unwrapped),\n });\n\n const message = createMessage(init(key, content, base, media));\n natives.set(message, raw);\n return message;\n}\n\n/**\n * Mensagem do Baileys de onde cada `Message` saiu. Citar no envio precisa do proto original\n * (`quoted` do `sendMessage`); o `WeakMap` some com a `Message`, sem cache para limpar.\n */\nconst natives = new WeakMap<Message, WAMessage>();\n\n/** O `WAMessage` que originou a mensagem, se ela foi normalizada por este transport. */\nexport function nativeOf(message: Message): WAMessage | undefined {\n return natives.get(message);\n}\n\ntype Base = Omit<Extract<MessageInit, { type: 'unknown' }>, 'type' | 'text'>;\ntype MediaOf = (m: {\n readonly mimetype?: string | null;\n readonly fileLength?: Parameters<typeof toNumber>[0];\n}) => MediaSource;\n\nfunction init(key: keyof Content, c: Content, base: Base, media: MediaOf): MessageInit {\n switch (key) {\n case 'conversation':\n return { ...base, type: 'text', text: c.conversation ?? '' };\n case 'extendedTextMessage':\n return { ...base, type: 'text', text: c.extendedTextMessage?.text ?? '' };\n case 'imageMessage': {\n const m = c.imageMessage ?? {};\n return { ...base, type: 'image', text: m.caption ?? null, media: media(m) };\n }\n case 'videoMessage':\n case 'ptvMessage': {\n // `ptv` é o vídeo redondo (recado de vídeo): para o plugin, um vídeo.\n const m = c[key] ?? {};\n return { ...base, type: 'video', text: m.caption ?? null, media: media(m) };\n }\n case 'audioMessage': {\n const m = c.audioMessage ?? {};\n return { ...base, type: m.ptt ? 'voice' : 'audio', text: null, media: media(m) };\n }\n case 'stickerMessage':\n return { ...base, type: 'sticker', text: null, media: media(c.stickerMessage ?? {}) };\n case 'documentMessage': {\n const m = c.documentMessage ?? {};\n return {\n ...base,\n type: 'document',\n text: m.caption ?? null,\n fileName: m.fileName ?? null,\n media: media(m),\n };\n }\n case 'locationMessage': {\n const m = c.locationMessage ?? {};\n return {\n ...base,\n type: 'location',\n text: m.comment ?? null,\n location: {\n latitude: m.degreesLatitude ?? 0,\n longitude: m.degreesLongitude ?? 0,\n name: m.name ?? m.address ?? null,\n ...(m.address ? { address: m.address } : {}),\n },\n };\n }\n case 'liveLocationMessage': {\n const m = c.liveLocationMessage ?? {};\n return {\n ...base,\n type: 'location',\n text: m.caption ?? null,\n location: {\n latitude: m.degreesLatitude ?? 0,\n longitude: m.degreesLongitude ?? 0,\n name: null,\n },\n };\n }\n case 'contactMessage':\n case 'contactsArrayMessage': {\n const list =\n key === 'contactMessage'\n ? [c.contactMessage ?? {}]\n : (c.contactsArrayMessage?.contacts ?? []);\n return {\n ...base,\n type: 'contact',\n text: null,\n contacts: list.map((m) => ({ name: m.displayName ?? '', vcard: m.vcard ?? '' })),\n };\n }\n case 'pollCreationMessage':\n case 'pollCreationMessageV2':\n case 'pollCreationMessageV3':\n case 'pollCreationMessageV5': {\n const m = c[key] ?? {};\n return {\n ...base,\n type: 'poll',\n text: null,\n poll: { name: m.name ?? '', options: (m.options ?? []).map((o) => o.optionName ?? '') },\n };\n }\n default:\n return { ...base, type: 'unknown', text: null };\n }\n}\n\nfunction contextOf(node: unknown): proto.IContextInfo | null {\n if (typeof node !== 'object' || node === null || !('contextInfo' in node)) return null;\n return (node.contextInfo as proto.IContextInfo | null | undefined) ?? null;\n}\n\nfunction flag(node: unknown, name: string): boolean {\n return (\n typeof node === 'object' && node !== null && name in node && Reflect.get(node, name) === true\n );\n}\n\n/**\n * A citada vem só com id, autor e conteúdo: sem horário (vale o da mensagem que cita) e sem nome\n * do autor.\n */\nfunction quoted(\n context: proto.IContextInfo,\n chatId: string,\n env: NormalizeEnv,\n timestamp: number,\n): Promise<Message | null> {\n if (!context.quotedMessage || !context.stanzaId) return Promise.resolve(null);\n const author = context.participant ? jidNormalizedUser(context.participant) : undefined;\n return build(\n {\n key: {\n remoteJid: context.remoteJid ?? chatId,\n id: context.stanzaId,\n fromMe: author !== undefined && env.selfIds.includes(author),\n participant: author,\n },\n message: context.quotedMessage,\n },\n env,\n timestamp,\n false,\n );\n}\n\n/**\n * Autor de uma mensagem pela chave. Grupo, status e citada o trazem em `participant`. Sem ele\n * (conversa privada), o autor é o próprio chat, ou a sessão quando foi ela que mandou.\n */\nexport function authorOf(\n key: WAMessageKey,\n chatId: string,\n env: Pick<NormalizeEnv, 'selfIds' | 'pnForLid'>,\n name: string | null,\n): Promise<Contact> {\n const alt = key.participant ? key.participantAlt : key.fromMe ? undefined : key.remoteJidAlt;\n return resolveContact(env, authorJid(key, chatId, env.selfIds), alt, name);\n}\n\n/** O JID do autor pela chave, sem resolver o telefone (ver `authorOf`). */\nexport function authorJid(key: WAMessageKey, chatId: string, selfIds: readonly string[]): string {\n if (key.participant) return key.participant;\n return key.fromMe ? (selfIds[0] ?? chatId) : chatId;\n}\n\n/**\n * Contato com o telefone resolvido: do próprio JID de telefone, do JID alternativo que o\n * Baileys manda junto com um LID ou do mapeamento LID ↔ telefone da sessão.\n */\nexport async function resolveContact(\n env: Pick<NormalizeEnv, 'pnForLid'>,\n jid: string,\n alt: string | null | undefined,\n name: string | null,\n): Promise<Contact> {\n // Sem o aparelho: `5511…:12@s.whatsapp.net` e `5511…@s.whatsapp.net` são o mesmo contato.\n const id = jidNormalizedUser(jid) || jid;\n return { id, name, phone: await phoneOf(env, id, alt) };\n}\n\nasync function phoneOf(\n env: Pick<NormalizeEnv, 'pnForLid'>,\n id: string,\n alt: string | null | undefined,\n): Promise<string | null> {\n if (isPnUser(id)) return jidDecode(id)?.user ?? null;\n if (alt && isPnUser(alt)) return jidDecode(alt)?.user ?? null;\n if (!isLidUser(id)) return null;\n const pn = await env.pnForLid(id);\n return pn ? (jidDecode(pn)?.user ?? null) : null;\n}\n","// Mapeamento de eventos (M2-1.6): o que o Baileys emite além das mensagens novas → eventos do\n// barramento (plano §6.4). Reação, edição e apagamento chegam ao Baileys como mensagens de\n// controle, que ele já converte em `messages.reaction` e `messages.update`; grupos chegam em\n// `groups.upsert`, `groups.update` e `group-participants.update`.\n\nimport type { Chat, Contact, Message } from '@usebridger/core';\nimport type { TransportEvents } from '@usebridger/core/adapter';\nimport {\n type BaileysEventMap,\n type GroupMetadata as BaileysGroupMetadata,\n isJidGroup,\n isJidStatusBroadcast,\n jidNormalizedUser,\n type WAMessageUpdate,\n} from 'baileys';\nimport {\n authorJid,\n authorOf,\n type NormalizeEnv,\n resolveContact,\n toEditedMessage,\n} from './normalize.ts';\n\ntype Env = Pick<NormalizeEnv, 'selfIds' | 'pnForLid'>;\n\n/**\n * Nome e telefone já vistos de cada contato. Decide quando sai o `contact.updated` e dá nome a\n * quem aparece sem `pushName` (reação, edição, apagamento, grupo). Vive enquanto o transport\n * vive: depois de reiniciar o processo, cada contato conta de novo como visto pela primeira vez.\n */\nexport class ContactBook {\n readonly #known = new Map<\n string,\n { readonly name: string | null; readonly phone: string | null }\n >();\n\n /**\n * Registra um remetente. Devolve o `contact.updated` quando há o que contar: na primeira vez\n * que o contato aparece (ADR 0049) ou quando o nome ou o telefone mudou. Campo desconhecido\n * (`null`) não apaga o que já se sabia.\n */\n observe(contact: Contact): TransportEvents['contact.updated'] | null {\n const known = this.#known.get(contact.id);\n const name = contact.name ?? known?.name ?? null;\n const phone = contact.phone ?? known?.phone ?? null;\n this.#known.set(contact.id, { name, phone });\n const update: { id: string; name?: string; phone?: string } = { id: contact.id };\n if (name !== null && name !== known?.name) update.name = name;\n if (phone !== null && phone !== known?.phone) update.phone = phone;\n return update.name === undefined && update.phone === undefined ? null : update;\n }\n\n nameOf(id: string): string | null {\n return this.#known.get(id)?.name ?? null;\n }\n\n /** O contato com o nome já visto, quando o evento não trouxe nenhum. */\n named(contact: Contact): Contact {\n return contact.name === null ? { ...contact, name: this.nameOf(contact.id) } : contact;\n }\n}\n\n/** O `Chat` de um JID; os eventos de grupo também o usam (ADR 0059). */\nexport function chatOf(id: string): Chat {\n return { id, isGroup: isJidGroup(id) === true };\n}\n\n/**\n * `reaction` a partir do `messages.reaction`: `key` é a mensagem reagida e `reaction.key` a\n * mensagem de reação, que diz quem reagiu. Texto vazio é reação removida.\n */\nexport async function toReaction(\n { key, reaction }: BaileysEventMap['messages.reaction'][number],\n env: Env,\n contacts: ContactBook,\n): Promise<TransportEvents['reaction'] | null> {\n const from = reaction.key;\n const chatId = from?.remoteJid ?? key.remoteJid;\n if (!from || !chatId || !key.id || isJidStatusBroadcast(chatId)) return null;\n return {\n chat: chatOf(chatId),\n messageId: key.id,\n sender: contacts.named(await authorOf(from, chatId, env, null)),\n emoji: reaction.text || null,\n fromMe: from.fromMe === true,\n };\n}\n\n/**\n * `message.edited` a partir do `messages.update` de edição. A chave é a da original com o autor\n * da edição, e o conteúdo novo vem em `editedMessage`.\n */\nexport function toEdited(\n { key, update }: WAMessageUpdate,\n env: NormalizeEnv,\n contacts: ContactBook,\n): Promise<Message | null> {\n const content = update.message?.editedMessage?.message;\n const chatId = key.remoteJid;\n if (!content || !chatId || isJidStatusBroadcast(chatId)) return Promise.resolve(null);\n return toEditedMessage(\n {\n key,\n message: content,\n // Sem o horário da edição, vale o da chegada.\n messageTimestamp: update.messageTimestamp ?? Math.floor(Date.now() / 1000),\n pushName: contacts.nameOf(jidNormalizedUser(authorJid(key, chatId, env.selfIds))),\n },\n env,\n );\n}\n\n/**\n * `message.deleted` a partir do `messages.update` de apagamento (`REVOKE`). `key` é a apagada;\n * `update.key` é a mensagem que apagou, que diz quem apagou (o autor ou um admin do grupo).\n */\nexport async function toDeleted(\n { key, update }: WAMessageUpdate,\n env: Env,\n contacts: ContactBook,\n): Promise<TransportEvents['message.deleted'] | null> {\n const chatId = key.remoteJid;\n if (!chatId || !key.id || isJidStatusBroadcast(chatId)) return null;\n const by = update.key;\n return {\n chat: chatOf(chatId),\n messageId: key.id,\n deletedBy: by ? contacts.named(await authorOf(by, chatId, env, null)) : null,\n fromMe: (by ?? key).fromMe === true,\n };\n}\n\ntype ParticipantsUpdate = BaileysEventMap['group-participants.update'];\ntype Participant = ParticipantsUpdate['participants'][number];\n\n/** O que um `group-participants.update` vira no barramento. */\nexport interface ParticipantEvents {\n /** A própria sessão entrou ou saiu do grupo. */\n readonly self: 'group.joined' | 'group.left' | null;\n /** Os demais participantes; `null` se não sobrou nenhum. */\n readonly others: TransportEvents['group.participants'] | null;\n}\n\n/**\n * Converte a alteração de participantes. Entrada e saída da própria sessão viram\n * `group.joined`/`group.left` e saem da lista; promovida ou rebaixada, ela segue em\n * `group.participants`. Troca de número (`modify`) não tem evento no core.\n */\nexport async function toParticipantEvents(\n { id, author, authorPn, participants, action }: ParticipantsUpdate,\n env: Env,\n contacts: ContactBook,\n): Promise<ParticipantEvents> {\n if (action === 'modify') return { self: null, others: null };\n const isSelf = (p: Participant): boolean =>\n [p.id, p.phoneNumber, p.lid].some((jid) => jid && env.selfIds.includes(jidNormalizedUser(jid)));\n const selfIn = participants.some(isSelf);\n const self = !selfIn\n ? null\n : action === 'add'\n ? 'group.joined'\n : action === 'remove'\n ? 'group.left'\n : null;\n const rest = self === null ? participants : participants.filter((p) => !isSelf(p));\n if (rest.length === 0) return { self, others: null };\n const contact = async (jid: string, alt: string | undefined, name: string | null) =>\n contacts.named(await resolveContact(env, jid, alt, name));\n return {\n self,\n others: {\n chat: chatOf(id),\n action,\n participants: await Promise.all(\n rest.map((p) => contact(p.id, p.phoneNumber, p.notify ?? p.name ?? null)),\n ),\n actor: author ? await contact(author, authorPn, null) : null,\n },\n };\n}\n\n/**\n * `group.updated` com só os campos que mudaram. O Baileys também emite `groups.update` com os\n * metadados completos de cada grupo ao sincronizar (`groupFetchAllParticipating`); esse traz\n * `participants` e não é uma alteração, então fica de fora.\n */\nexport function toGroupUpdated(\n update: Partial<BaileysGroupMetadata>,\n): TransportEvents['group.updated'] | null {\n if (!update.id || update.participants) return null;\n const changed: {\n chat: Chat;\n title?: string;\n description?: string | null;\n announce?: boolean;\n restrict?: boolean;\n } = { chat: chatOf(update.id) };\n if (update.subject !== undefined) changed.title = update.subject;\n // Descrição removida chega com `desc` presente e vazio.\n if ('desc' in update) changed.description = update.desc || null;\n if (update.announce !== undefined) changed.announce = update.announce;\n if (update.restrict !== undefined) changed.restrict = update.restrict;\n return Object.keys(changed).length > 1 ? changed : null;\n}\n","// Texto formatado neutro do core (ADR 0061) na marcação do WhatsApp: `*negrito*`, `_itálico_`,\n// `` `código` `` e `@número` com o JID na lista de menções. Função pura.\n\nimport type { FormattedText, TextNode } from '@usebridger/core';\nimport { jidDecode } from 'baileys';\n\nexport interface RenderedText {\n readonly text: string;\n /** JIDs das menções da árvore, na ordem e sem repetição. */\n readonly mentions: readonly string[];\n}\n\n/**\n * Renderiza a árvore. O WhatsApp não tem escape: um `*` literal do texto pode casar com outro e\n * virar negrito, como já acontece no app. Por isso o texto literal vai como está.\n */\nexport function renderWhatsApp(text: FormattedText): RenderedText {\n const mentions = new Set<string>();\n const render = (nodes: readonly TextNode[]): string => {\n let out = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n out += node;\n continue;\n }\n switch (node.type) {\n case 'bold':\n case 'italic':\n out += wrap(node.type === 'bold' ? '*' : '_', render(node.children));\n break;\n case 'code':\n out += wrap('`', node.text);\n break;\n case 'link': {\n // O WhatsApp não tem link com rótulo: a URL aparece e vira link sozinha.\n const label = render(node.children);\n out += label === node.url ? node.url : `${label} (${node.url})`;\n break;\n }\n case 'mention':\n mentions.add(node.contact.id);\n // O app troca `@<usuário do JID>` pelo nome do contato, inclusive com LID.\n out += `@${jidDecode(node.contact.id)?.user ?? node.contact.id}`;\n break;\n }\n }\n return out;\n };\n return { text: render(text.nodes), mentions: [...mentions] };\n}\n\n/**\n * O marcador só vale colado no texto (`* a *` sai literal): o espaço das pontas fica do lado de\n * fora.\n */\nfunction wrap(marker: string, inner: string): string {\n const match = /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(inner);\n const [, lead = '', core = '', trail = ''] = match ?? [];\n if (core === '') return inner;\n return `${lead}${marker}${core}${marker}${trail}`;\n}\n","// Envio (M2-1.3): o conteúdo, a chave e os metadados de grupo do core no formato do Baileys, e\n// de volta. Funções puras; quem fala com o socket é o transport.\n\nimport {\n type GroupMetadata,\n type GroupParticipant,\n type Message,\n type MessageKey,\n type OutgoingContent,\n type SendOptions,\n UnsupportedError,\n} from '@usebridger/core';\nimport {\n type AnyMessageContent,\n type GroupMetadata as BaileysGroupMetadata,\n jidNormalizedUser,\n type WAMessage,\n type WAMessageKey,\n} from 'baileys';\nimport { renderWhatsApp } from './format.ts';\nimport { type NormalizeEnv, nativeOf, resolveContact } from './normalize.ts';\n\n/**\n * Conteúdo do `sendMessage`, com as menções que o Baileys põe no `contextInfo` de qualquer tipo.\n * A árvore neutra (`formatted`, `formattedCaption`) vira a marcação do WhatsApp, e as menções\n * dela se juntam às de `options.mentions` (ADR 0061).\n */\nexport function toContent(content: OutgoingContent, options?: SendOptions): AnyMessageContent {\n const ids = new Set(options?.mentions);\n let text: string | undefined;\n let caption: string | undefined;\n if (content.type === 'text') {\n text = content.text;\n if (content.formatted) {\n const rendered = renderWhatsApp(content.formatted);\n text = rendered.text;\n for (const id of rendered.mentions) ids.add(id);\n }\n } else if ('caption' in content || 'formattedCaption' in content) {\n caption = content.caption;\n if (content.formattedCaption) {\n const rendered = renderWhatsApp(content.formattedCaption);\n caption = rendered.text;\n for (const id of rendered.mentions) ids.add(id);\n }\n }\n const mentions = ids.size > 0 ? { mentions: [...ids] } : {};\n switch (content.type) {\n case 'text':\n return { text: text ?? content.text, ...mentions };\n case 'image':\n return {\n image: content.media,\n caption,\n mimetype: content.mimetype,\n ...mentions,\n };\n case 'video':\n return {\n video: content.media,\n caption,\n mimetype: content.mimetype,\n ...mentions,\n };\n case 'audio':\n case 'voice':\n // Voz é áudio com `ptt`; sem `mimetype`, o Baileys usa `audio/ogg; codecs=opus`.\n return {\n audio: content.media,\n ptt: content.type === 'voice',\n mimetype: content.mimetype,\n ...mentions,\n };\n case 'sticker':\n return { sticker: content.media, ...mentions };\n case 'document':\n return {\n document: content.media,\n fileName: content.fileName,\n mimetype: content.mimetype,\n caption,\n ...mentions,\n };\n case 'album':\n // O Baileys não monta álbum (o WhatsApp agrupa as imagens em sequência), então o transport\n // não declara `send.album`, e a fila envia item a item (ADR 0065). Chegar aqui é pular a\n // checagem.\n throw new UnsupportedError('send.album', 'baileys');\n case 'poll':\n return {\n poll: {\n name: content.name,\n values: [...content.options],\n // No WhatsApp, 0 libera marcar quantas quiser e 1 é escolha única.\n selectableCount: content.multiple === true ? 0 : 1,\n },\n ...mentions,\n };\n }\n}\n\nexport function toWAKey(key: MessageKey): WAMessageKey {\n return {\n remoteJid: key.chatId,\n id: key.id,\n fromMe: key.fromMe,\n participant: key.senderId ?? undefined,\n };\n}\n\n/**\n * A mensagem a citar como o Baileys a quer. Recebida por este transport, vai o proto original\n * (a citada mostra mídia e legenda); montada fora dele (testes, storage), vai só o texto.\n */\nexport function toQuoted(message: Message): WAMessage {\n return (\n nativeOf(message) ?? {\n key: toWAKey(message.key),\n message: { conversation: message.text ?? '' },\n }\n );\n}\n\n/** Metadados do grupo com o telefone de cada participante resolvido, inclusive com LID. */\nexport async function toGroupMetadata(\n native: BaileysGroupMetadata,\n env: Pick<NormalizeEnv, 'pnForLid'>,\n): Promise<GroupMetadata> {\n const participants = await Promise.all(\n native.participants.map(async (p): Promise<GroupParticipant> => {\n const contact = await resolveContact(env, p.id, p.phoneNumber, p.name ?? p.notify ?? null);\n return {\n ...contact,\n isAdmin: p.admin === 'admin' || p.admin === 'superadmin',\n isSuperAdmin: p.admin === 'superadmin',\n };\n }),\n );\n return {\n id: native.id,\n title: native.subject,\n description: native.desc ?? null,\n ownerId: native.owner ? jidNormalizedUser(native.owner) || native.owner : null,\n participants,\n };\n}\n","// Votos de enquete (#312, ADR 0071). O WhatsApp cifra o voto com o segredo da enquete\n// (`messageSecret`), que só vem na mensagem que a criou, e o Baileys 7 não decifra mais sozinho (o\n// trecho do `process-message` está comentado). Por isso o transport guarda as enquetes que vê e\n// decifra o voto com `decryptPollVote`.\n\nimport { createHash } from 'node:crypto';\nimport type { TransportEvents } from '@usebridger/core/adapter';\nimport {\n decryptPollVote,\n jidNormalizedUser,\n type proto,\n type WAMessage,\n type WAMessageKey,\n} from 'baileys';\nimport { type ContactBook, chatOf } from './events.ts';\nimport { authorOf, type NormalizeEnv, unwrap } from './normalize.ts';\n\ntype Env = Pick<NormalizeEnv, 'selfIds' | 'pnForLid'>;\n\ninterface KnownPoll {\n readonly key: WAMessageKey;\n readonly secret: Uint8Array;\n /** SHA-256 de cada opção, em hex, na ordem da enquete: o voto traz os hashes, não o texto. */\n readonly hashes: readonly string[];\n}\n\n/** Enquetes guardadas por padrão; a mais antiga sai primeiro. */\nconst DEFAULT_MAX_POLLS = 1000;\n\n/**\n * Enquetes que a sessão enviou ou recebeu enquanto conectada, pelo ID da mensagem. O ID basta: o\n * mesmo chat privado aparece ora como LID, ora como telefone, e o ID do WhatsApp é aleatório. Vive\n * até o `disconnect()`: voto de enquete anterior não se decifra e é descartado.\n */\nexport class PollBook {\n readonly #polls = new Map<string, KnownPoll>();\n readonly #max: number;\n\n constructor(max: number = DEFAULT_MAX_POLLS) {\n this.#max = max;\n }\n\n /** Guarda a enquete, se a mensagem for uma e trouxer o segredo; o resto é ignorado. */\n remember(raw: WAMessage): void {\n const id = raw.key.id;\n if (!id || !raw.message) return;\n const { content } = unwrap(raw.message);\n const poll =\n content.pollCreationMessage ??\n content.pollCreationMessageV2 ??\n content.pollCreationMessageV3 ??\n content.pollCreationMessageV5;\n // A V4 é envelope: o segredo pode vir fora ou dentro dele.\n const secret =\n raw.message.messageContextInfo?.messageSecret ?? content.messageContextInfo?.messageSecret;\n if (!poll || !secret) return;\n this.#polls.delete(id);\n this.#polls.set(id, {\n key: raw.key,\n secret,\n hashes: (poll.options ?? []).map((o) => sha256Hex(o.optionName ?? '')),\n });\n if (this.#polls.size > this.#max) {\n const oldest = this.#polls.keys().next().value;\n if (oldest !== undefined) this.#polls.delete(oldest);\n }\n }\n\n get(id: string): KnownPoll | undefined {\n return this.#polls.get(id);\n }\n\n clear(): void {\n this.#polls.clear();\n }\n}\n\n/** O `pollUpdateMessage` da mensagem, se ela for um voto. */\nexport function pollUpdateOf(raw: WAMessage): proto.Message.IPollUpdateMessage | null {\n return raw.message ? (unwrap(raw.message).content.pollUpdateMessage ?? null) : null;\n}\n\n/**\n * `poll.vote` a partir do `pollUpdateMessage`. Devolve `null` quando a enquete não está no\n * `PollBook` (enviada antes da conexão atual, por exemplo) e lança quando ela está, mas o voto não\n * decifra.\n */\nexport async function toPollVote(\n raw: WAMessage,\n polls: PollBook,\n env: Env,\n contacts: ContactBook,\n): Promise<TransportEvents['poll.vote'] | null> {\n const update = pollUpdateOf(raw);\n const pollKey = update?.pollCreationMessageKey;\n const chatId = raw.key.remoteJid;\n if (!update?.vote || !pollKey?.id || !chatId) return null;\n const poll = polls.get(pollKey.id);\n if (poll === undefined) return null;\n const vote = decrypt(update.vote, poll, pollKey, raw.key, env.selfIds);\n if (vote === null) throw new Error('baileys: o voto da enquete não decifrou');\n const options = new Set<number>();\n for (const hash of vote.selectedOptions ?? []) {\n const index = poll.hashes.indexOf(Buffer.from(hash).toString('hex'));\n // Hash fora da lista: opção que esta enquete não tem. Fica de fora em vez de virar índice.\n if (index >= 0) options.add(index);\n }\n return {\n chat: chatOf(chatId),\n messageId: pollKey.id,\n sender: contacts.named(await authorOf(raw.key, chatId, env, raw.pushName ?? null)),\n options: [...options].sort((a, b) => a - b),\n fromMe: raw.key.fromMe === true,\n };\n}\n\n/**\n * Decifra o voto. A chave sai do JID de quem criou e de quem votou, como o aparelho do votante os\n * viu, e com o LID ele pode ter usado o telefone ou o LID: tenta cada par conhecido.\n */\nfunction decrypt(\n vote: proto.Message.IPollEncValue,\n poll: KnownPoll,\n pollKey: proto.IMessageKey,\n voteKey: WAMessageKey,\n selfIds: readonly string[],\n): proto.Message.PollVoteMessage | null {\n const creators = unique([...jidsOf(poll.key, selfIds), ...jidsOf(pollKey, selfIds)]);\n const voters = unique(jidsOf(voteKey, selfIds));\n const pollMsgId = pollKey.id ?? '';\n for (const pollCreatorJid of creators) {\n for (const voterJid of voters) {\n const decrypted = tryDecrypt(vote, {\n pollCreatorJid,\n pollMsgId,\n pollEncKey: poll.secret,\n voterJid,\n });\n if (decrypted !== null) return decrypted;\n }\n }\n return null;\n}\n\nfunction tryDecrypt(\n vote: proto.Message.IPollEncValue,\n context: Parameters<typeof decryptPollVote>[1],\n): proto.Message.PollVoteMessage | null {\n try {\n return decryptPollVote(vote, context);\n } catch {\n // Par de JIDs errado: a autenticação do AES-GCM falha, e o próximo par é tentado.\n return null;\n }\n}\n\n/** JIDs possíveis do autor de uma chave: o da sessão, o do participante ou o do chat privado. */\nfunction jidsOf(\n key: proto.IMessageKey & { participantAlt?: string; remoteJidAlt?: string },\n selfIds: readonly string[],\n): string[] {\n if (key.fromMe) return [...selfIds];\n const jids = key.participant\n ? [key.participant, key.participantAlt]\n : [key.remoteJid, key.remoteJidAlt];\n return jids.flatMap((jid) => (jid ? [jidNormalizedUser(jid) || jid] : []));\n}\n\nfunction unique(values: readonly string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction sha256Hex(text: string): string {\n return createHash('sha256').update(text).digest('hex');\n}\n","// Transport do WhatsApp sobre o Baileys (M2-1). Este módulo cuida da conexão: socket, QR ou\n// código de pareamento, credenciais no storage do bot e o motivo de cada queda. Quem decide\n// reconectar é o `Bot`, pela `ReconnectionPolicy` (ADR 0048). As mensagens recebidas passam\n// pela normalização (`normalize.ts`) antes de virar o evento `message`, e os demais eventos do\n// Baileys (reação, edição, apagamento, grupos) são convertidos em `events.ts`; o envio e as\n// demais ações traduzem o formato do core em `outgoing.ts`.\n\nimport { Readable } from 'node:stream';\nimport type {\n Capability,\n Contact,\n FormattedText,\n GroupMetadata,\n GroupParticipantAction,\n Logger,\n LogLevel,\n Message,\n MessageKey,\n OutgoingContent,\n SendOptions,\n TypingKind,\n Unsubscribe,\n} from '@usebridger/core';\nimport {\n type Interaction,\n type Transport,\n type TransportDeps,\n type TransportEventHandler,\n type TransportEventName,\n type TransportEvents,\n TypedEmitter,\n} from '@usebridger/core/adapter';\nimport {\n type AnyMessageContent,\n type AuthenticationState,\n type Contact as BaileysContact,\n type BaileysEventMap,\n type GroupMetadata as BaileysGroupMetadata,\n downloadMediaMessage,\n isJidGroup,\n isJidStatusBroadcast,\n jidDecode,\n jidNormalizedUser,\n type MiscMessageGenerationOptions,\n type ParticipantAction,\n type WAMessage,\n WAMessageStubType,\n type WAPresence,\n type WAVersion,\n} from 'baileys';\nimport { loadAuthState } from './auth-state.ts';\nimport { routeLibsignalConsole } from './console.ts';\nimport { toDisconnectReason } from './disconnect-reason.ts';\nimport {\n ContactBook,\n chatOf,\n toDeleted,\n toEdited,\n toGroupUpdated,\n toParticipantEvents,\n toReaction,\n} from './events.ts';\nimport { renderWhatsApp } from './format.ts';\nimport { type ILogger, toBaileysLogger } from './logger.ts';\nimport { type NormalizeEnv, nativeOf, toMessage } from './normalize.ts';\nimport { toContent, toGroupMetadata, toQuoted, toWAKey } from './outgoing.ts';\nimport { PollBook, pollUpdateOf, toPollVote } from './polls.ts';\n\n/** Como parear uma sessão sem credenciais: escaneando o QR ou digitando um código no aparelho. */\nexport type BaileysPairing = 'qr' | { readonly phone: string };\n\n/** O que o transport usa do socket do Baileys; nos testes, um socket falso. */\nexport interface BaileysSocket {\n readonly ev: {\n on<E extends keyof BaileysEventMap>(\n event: E,\n listener: (arg: BaileysEventMap[E]) => void,\n ): void;\n };\n readonly user: BaileysContact | undefined;\n /** Mapeamento LID ↔ telefone que o Baileys aprende com a sessão. */\n readonly signalRepository: {\n readonly lidMapping: { getPNForLID(lid: string): Promise<string | null> };\n };\n end(error: Error | undefined): Promise<void>;\n requestPairingCode(phoneNumber: string): Promise<string>;\n /** Pede ao aparelho que reenvie uma mídia cujo link expirou. */\n updateMediaMessage(message: WAMessage): Promise<WAMessage>;\n sendMessage(\n jid: string,\n content: AnyMessageContent,\n options?: MiscMessageGenerationOptions,\n ): Promise<WAMessage | undefined>;\n sendPresenceUpdate(type: WAPresence, toJid?: string): Promise<void>;\n groupMetadata(jid: string): Promise<BaileysGroupMetadata>;\n groupParticipantsUpdate(\n jid: string,\n participants: string[],\n action: ParticipantAction,\n ): Promise<readonly { readonly status: string; readonly jid: string | undefined }[]>;\n}\n\nexport interface SocketConfig {\n readonly auth: AuthenticationState;\n readonly logger: ILogger;\n readonly version: WAVersion;\n /** Metadados de grupo já conhecidos: o envio em grupo não consulta o servidor de novo. */\n readonly cachedGroupMetadata: (jid: string) => Promise<BaileysGroupMetadata | undefined>;\n}\n\n/** Acesso ao Baileys que tem efeito fora do processo; os testes trocam pelos falsos. */\nexport interface BaileysDriver {\n makeSocket(config: SocketConfig): BaileysSocket;\n /** Versão do protocolo do WhatsApp Web a anunciar. */\n version(): Promise<WAVersion>;\n}\n\nexport interface BaileysTransportOptions {\n readonly pairing: BaileysPairing;\n readonly driver: BaileysDriver;\n /** Nível mínimo das linhas do próprio Baileys; sem ele, vale só o do bot. */\n readonly logLevel?: LogLevel;\n}\n\nexport class BaileysTransport implements Transport {\n readonly name = 'baileys';\n /**\n * Todas as capabilities do core, menos `actions`: o WhatsApp pelo Baileys não tem botões\n * confiáveis, e o kernel envia o menu em texto numerado (ADR 0062).\n */\n readonly capabilities: ReadonlySet<Capability> = new Set<Capability>([\n 'groups',\n 'groups.add',\n 'groups.remove',\n 'groups.promote',\n 'mentions',\n 'reactions',\n 'typing',\n 'send.text',\n 'send.image',\n 'send.video',\n 'send.audio',\n 'send.voice',\n 'send.sticker',\n 'send.document',\n 'media.download',\n 'message.edit',\n 'message.delete',\n 'polls',\n 'quoted',\n // Pareia por QR ou código: credencial rejeitada limpa a sessão e pareia de novo (ADR 0068).\n 'pairing',\n ]);\n\n readonly #pairing: BaileysPairing;\n readonly #driver: BaileysDriver;\n readonly #logLevel: LogLevel | undefined;\n /** Desliga o desvio do `console` do libsignal; presente enquanto há socket. */\n #releaseConsole: (() => void) | undefined;\n readonly #deps: TransportDeps;\n readonly #events: TypedEmitter<TransportEvents>;\n #socket: BaileysSocket | null = null;\n #self: Contact | null = null;\n /** Sobe a cada `connect()`/`disconnect()`: invalida a tentativa que ainda estava começando. */\n #attempt = 0;\n /**\n * Metadados por grupo (ADR 0046): o kernel os pede a cada comando `group-admin`. Invalidado\n * pelos eventos de grupo do Baileys e a cada conexão, porque a queda pode ter perdido algum.\n */\n readonly #groups = new Map<string, Promise<BaileysGroupMetadata>>();\n /** Contatos já vistos, entre conexões: o `contact.updated` sai só no que é novo. */\n readonly #contacts = new ContactBook();\n /** Enquetes vistas, para decifrar os votos (ADR 0071); o `disconnect()` as esquece. */\n readonly #polls = new PollBook();\n\n constructor(options: BaileysTransportOptions, deps: TransportDeps) {\n this.#pairing = options.pairing;\n this.#driver = options.driver;\n this.#logLevel = options.logLevel;\n this.#deps = deps;\n this.#events = new TypedEmitter<TransportEvents>((error, event) =>\n this.#log.error('handler de evento do transport falhou', { err: error, event }),\n );\n }\n\n get self(): Contact | null {\n return this.#self;\n }\n\n /** O socket do Baileys (`WASocket`) da tentativa atual, ou `null` sem conexão. */\n get native(): unknown {\n return this.#socket;\n }\n\n /**\n * O `WAMessage` de onde a mensagem saiu (ADR 0066), o mesmo que o envio usa para citar. A citada\n * devolve o proto montado do `contextInfo`, sem `pushName` nem horário. O Baileys não emite\n * `interaction`: para ela, e para mensagem que não veio daqui, `undefined`.\n */\n raw(source: Message | Interaction): unknown {\n return 'key' in source ? nativeOf(source) : undefined;\n }\n\n get #log(): Logger {\n return this.#deps.log;\n }\n\n on<E extends TransportEventName>(event: E, handler: TransportEventHandler<E>): Unsubscribe {\n return this.#events.on(event, handler);\n }\n\n async connect(): Promise<void> {\n const attempt = ++this.#attempt;\n // Reconexão: o socket anterior já caiu, mas pode ainda estar de pé se alguém chamou\n // `connect()` duas vezes. Os eventos dele deixam de valer a partir daqui.\n this.#endSocket();\n const version = await this.#driver.version();\n const logger = toBaileysLogger(this.#log.child({ lib: 'baileys' }), this.#logLevel);\n const { state, saveCreds } = await loadAuthState(this.#deps.auth, logger);\n // `disconnect()` ou outro `connect()` enquanto as credenciais carregavam.\n if (attempt !== this.#attempt) return;\n\n this.#groups.clear();\n const socket = this.#driver.makeSocket({\n auth: state,\n logger,\n version,\n cachedGroupMetadata: (jid) => this.#cachedGroup(jid),\n });\n this.#socket = socket;\n this.#releaseConsole = routeLibsignalConsole(logger);\n const current = (): boolean => this.#socket === socket;\n // Gravações em fila: uma `creds.update` não pode sobrescrever a seguinte fora de ordem.\n let saving = Promise.resolve();\n // Mostrou QR/código e não abriu: o 408 que vier é o pareamento que expirou.\n let pairing = false;\n let codeRequested = false;\n\n socket.ev.on('creds.update', () => {\n if (!current()) return;\n saving = saving.then(saveCreds).catch((error: unknown) => {\n this.#log.error('falha ao gravar as credenciais da sessão', { err: error });\n });\n });\n\n // Em fila: a conversão é assíncrona (telefone de LID) e não pode inverter a ordem de\n // chegada, que a fila de entrada do bot preserva por chat. Reação, edição e apagamento entram\n // na mesma fila: a edição de uma mensagem não passa à frente dela.\n let inbound = Promise.resolve();\n const enqueue = (work: () => Promise<void>, failure: string, messageId?: string | null) => {\n inbound = inbound.then(work).catch((error: unknown) => {\n this.#log.error(failure, { err: error, messageId });\n });\n };\n const env = this.#normalizeEnv(socket, state, logger);\n const contacts = this.#contacts;\n const polls = this.#polls;\n\n socket.ev.on('messages.upsert', ({ messages, type }) => {\n if (!current()) return;\n // `append` é histórico e cópia de sincronização; só `notify` é mensagem nova.\n if (type !== 'notify') return;\n for (const raw of messages) {\n // Status (stories) não é conversa: fica de fora até haver um evento para ele.\n if (raw.key.remoteJid && isJidStatusBroadcast(raw.key.remoteJid)) continue;\n enqueue(\n async () => {\n // Na fila, como o resto: o voto chega depois da enquete e já a encontra guardada, e\n // um proto malformado descarta só esta mensagem.\n polls.remember(raw);\n if (pollUpdateOf(raw) !== null) {\n const vote = await toPollVote(raw, polls, env, contacts);\n if (vote === null) {\n this.#log.debug('voto de enquete desconhecida; descartado', {\n messageId: raw.key.id,\n });\n } else if (current()) {\n this.#events.emit('poll.vote', vote);\n }\n return;\n }\n const message = await toMessage(raw, env);\n if (message === null || !current()) return;\n // Antes da mensagem: quem guarda nomes já o tem ao tratá-la.\n const contact = message.fromMe ? null : contacts.observe(message.sender);\n if (contact !== null) this.#events.emit('contact.updated', contact);\n this.#events.emit('message', message);\n },\n 'falha ao normalizar mensagem do Baileys; descartada',\n raw.key.id,\n );\n }\n });\n\n socket.ev.on('messages.reaction', (reactions) => {\n if (!current()) return;\n for (const item of reactions) {\n enqueue(\n async () => {\n const reaction = await toReaction(item, env, contacts);\n if (reaction !== null && current()) this.#events.emit('reaction', reaction);\n },\n 'falha ao converter reação do Baileys; descartada',\n item.key.id,\n );\n }\n });\n\n socket.ev.on('messages.update', (updates) => {\n if (!current()) return;\n // A maior parte é recibo de entrega e leitura, que não tem evento no core.\n for (const item of updates) {\n if (item.update.message?.editedMessage) {\n enqueue(\n async () => {\n const message = await toEdited(item, env, contacts);\n if (message !== null && current()) this.#events.emit('message.edited', message);\n },\n 'falha ao converter edição do Baileys; descartada',\n item.key.id,\n );\n } else if (item.update.messageStubType === WAMessageStubType.REVOKE) {\n enqueue(\n async () => {\n const deleted = await toDeleted(item, env, contacts);\n if (deleted !== null && current()) this.#events.emit('message.deleted', deleted);\n },\n 'falha ao converter apagamento do Baileys; descartado',\n item.key.id,\n );\n }\n }\n });\n\n // Grupo criado com a sessão dentro: o Baileys avisa pelo `groups.upsert`, não pelos\n // participantes.\n socket.ev.on('groups.upsert', (groups) => {\n if (!current()) return;\n for (const { id } of groups) {\n enqueue(async () => {\n if (current()) this.#events.emit('group.joined', { chat: chatOf(id) });\n }, 'falha ao repassar grupo novo');\n }\n });\n socket.ev.on('groups.update', (updates) => {\n if (!current()) return;\n for (const update of updates) {\n if (update.id) this.#groups.delete(update.id);\n const changed = toGroupUpdated(update);\n if (changed === null) continue;\n enqueue(async () => {\n if (current()) this.#events.emit('group.updated', changed);\n }, 'falha ao repassar alteração de grupo');\n }\n });\n socket.ev.on('group-participants.update', (update) => {\n if (!current()) return;\n this.#groups.delete(update.id);\n enqueue(async () => {\n const { self, others } = await toParticipantEvents(update, env, contacts);\n if (!current()) return;\n if (self !== null) this.#events.emit(self, { chat: chatOf(update.id) });\n if (others !== null) this.#events.emit('group.participants', others);\n }, 'falha ao converter alteração de participantes do Baileys; descartada');\n });\n\n socket.ev.on('connection.update', ({ connection, lastDisconnect, qr }) => {\n if (!current()) return;\n if (qr !== undefined) {\n pairing = true;\n if (this.#pairing === 'qr') {\n this.#events.emit('connection.qr', { qr });\n } else if (!codeRequested && !state.creds.registered) {\n // Um código por tentativa: o Baileys segue girando o QR, mas o código vale até a\n // tentativa expirar (408), e aí a política pede outro.\n codeRequested = true;\n this.#requestPairingCode(socket, this.#pairing.phone);\n }\n }\n switch (connection) {\n case 'connecting':\n this.#events.emit('connection.status', { status: 'connecting' });\n return;\n case 'open':\n pairing = false;\n this.#self = socket.user ? toContact(socket.user) : null;\n this.#events.emit('connection.status', { status: 'open' });\n return;\n case 'close': {\n this.#socket = null;\n const error = lastDisconnect?.error;\n const reason = toDisconnectReason(error, { pairing });\n this.#events.emit('connection.status', { status: 'closed', reason, error });\n return;\n }\n }\n });\n }\n\n async disconnect(): Promise<void> {\n this.#attempt++;\n this.#endSocket();\n this.#polls.clear();\n }\n\n /** Encerra o socket atual sem emitir nada: quem chamou já sabe que a conexão acabou. */\n #endSocket(): void {\n const socket = this.#socket;\n if (socket === null) return;\n this.#socket = null;\n this.#releaseConsole?.();\n this.#releaseConsole = undefined;\n socket.end(undefined).catch((error: unknown) => {\n this.#log.warn('falha ao encerrar o socket do Baileys', { err: error });\n });\n }\n\n #normalizeEnv(socket: BaileysSocket, state: AuthenticationState, logger: ILogger): NormalizeEnv {\n const media = { reuploadRequest: (m: WAMessage) => socket.updateMediaMessage(m), logger };\n return {\n // Lido a cada mensagem: no primeiro pareamento o `me` só chega depois do socket criado.\n get selfIds() {\n const me = state.creds.me;\n return [me?.id, me?.lid].flatMap((id) => (id ? [jidNormalizedUser(id)] : []));\n },\n pnForLid: (lid) => this.#pnForLid(socket, lid),\n download: (raw) => downloadMediaMessage(raw, 'buffer', {}, media),\n stream: async (raw) =>\n Readable.toWeb(\n await downloadMediaMessage(raw, 'stream', {}, media),\n ) as ReadableStream<Uint8Array>,\n };\n }\n\n #pnForLid(socket: BaileysSocket, lid: string): Promise<string | null> {\n return socket.signalRepository.lidMapping.getPNForLID(lid).catch((error: unknown) => {\n // Sem o par, o contato segue com `phone: null`: os papéis falham fechados (ADR 0046).\n this.#log.warn('falha ao resolver o telefone de um LID', { err: error, lid });\n return null;\n });\n }\n\n #requestPairingCode(socket: BaileysSocket, phone: string): void {\n socket.requestPairingCode(phone).then(\n (code) => {\n if (this.#socket === socket) this.#events.emit('connection.pairing-code', { code });\n },\n (error: unknown) => {\n // Sem código, a tentativa expira (`qr-timeout`) e a próxima pede outro.\n this.#log.error('falha ao pedir o código de pareamento', { err: error });\n },\n );\n }\n\n async send(chatId: string, content: OutgoingContent, options?: SendOptions): Promise<MessageKey> {\n const sent = await this.#connected().sendMessage(\n chatId,\n toContent(content, options),\n options?.quoted ? { quoted: toQuoted(options.quoted) } : undefined,\n );\n const id = sent?.key.id;\n // O Baileys só devolve `undefined` para conteúdo que não vira mensagem (ex.: apagar); sem a\n // chave, não daria para reagir, editar nem apagar depois.\n if (!id) throw new Error('baileys: o envio não devolveu a chave da mensagem');\n // O segredo que cifra os votos só existe na mensagem enviada.\n if (content.type === 'poll' && sent) this.#polls.remember(sent);\n return {\n chatId,\n id,\n fromMe: true,\n senderId: isJidGroup(chatId) ? (this.#self?.id ?? null) : null,\n };\n }\n\n async react(key: MessageKey, emoji: string | null): Promise<void> {\n // Texto vazio é como o WhatsApp remove a reação.\n await this.#connected().sendMessage(key.chatId, {\n react: { text: emoji ?? '', key: toWAKey(key) },\n });\n }\n\n async edit(key: MessageKey, text: string, formatted?: FormattedText): Promise<void> {\n if (!formatted) {\n await this.#connected().sendMessage(key.chatId, { text, edit: toWAKey(key) });\n return;\n }\n const rendered = renderWhatsApp(formatted);\n await this.#connected().sendMessage(key.chatId, {\n text: rendered.text,\n edit: toWAKey(key),\n ...(rendered.mentions.length > 0 && { mentions: [...rendered.mentions] }),\n });\n }\n\n async delete(key: MessageKey): Promise<void> {\n await this.#connected().sendMessage(key.chatId, { delete: toWAKey(key) });\n }\n\n async sendTyping(chatId: string, kind: TypingKind): Promise<void> {\n await this.#connected().sendPresenceUpdate(\n kind === 'voice' ? 'recording' : 'composing',\n chatId,\n );\n }\n\n async getGroupMetadata(groupId: string): Promise<GroupMetadata> {\n const socket = this.#connected();\n let native = this.#groups.get(groupId);\n if (native === undefined) {\n const fetching = socket.groupMetadata(groupId);\n native = fetching;\n this.#groups.set(groupId, fetching);\n // Falha não fica no cache: a próxima chamada consulta de novo. O erro chega ao chamador\n // pela própria promise; este handler só limpa a entrada.\n fetching.catch(() => {\n if (this.#groups.get(groupId) === fetching) this.#groups.delete(groupId);\n });\n }\n return toGroupMetadata(await native, { pnForLid: (lid) => this.#pnForLid(socket, lid) });\n }\n\n async updateGroupParticipants(\n groupId: string,\n participantIds: readonly string[],\n action: GroupParticipantAction,\n ): Promise<void> {\n const results = await this.#connected().groupParticipantsUpdate(\n groupId,\n [...participantIds],\n action,\n );\n // Os participantes mudaram mesmo que o evento do Baileys ainda não tenha chegado.\n this.#groups.delete(groupId);\n // O servidor responde por participante; fora do 200, aquele falhou (ex.: 403 sem ser admin,\n // 409 já no grupo). Falha parcial também lança: quem chamou precisa saber.\n const failed = results.filter((r) => r.status !== '200');\n if (failed.length > 0) {\n const list = failed.map((r) => `${r.jid ?? '?'} (${r.status})`).join(', ');\n throw new Error(`baileys: ${action} recusado para ${list}`);\n }\n }\n\n /** Socket da conexão atual; sem ele, a ação falha na hora em vez de esperar. */\n #connected(): BaileysSocket {\n if (this.#socket === null) throw new Error('baileys: sem conexão');\n return this.#socket;\n }\n\n /** Para o envio em grupo: usa a consulta que já existe, sem disparar outra. */\n async #cachedGroup(jid: string): Promise<BaileysGroupMetadata | undefined> {\n return this.#groups.get(jid)?.catch(() => undefined);\n }\n}\n\n/** A própria sessão: o `id` do Baileys traz o aparelho (`5511…:12@s.whatsapp.net`). */\nfunction toContact(user: BaileysContact): Contact {\n const id = jidNormalizedUser(user.id);\n const jid = jidDecode(id);\n const phone =\n jid?.server === 's.whatsapp.net' ? jid.user : (jidDecode(user.phoneNumber)?.user ?? null);\n return { id, name: user.name ?? user.notify ?? null, phone };\n}\n","// Entry `@usebridger/transport-baileys`: a fábrica que o app passa em `createBot({ transport })`\n// (ADR 0037). A classe fica interna: o transport precisa das dependências do bot.\n\nimport type { LogLevel } from '@usebridger/core';\nimport type { Transport, TransportDeps } from '@usebridger/core/adapter';\nimport { Browsers, fetchLatestBaileysVersion, makeWASocket, type WAVersion } from 'baileys';\nimport { isLogLevel } from './logger.ts';\nimport { type BaileysDriver, type BaileysPairing, BaileysTransport } from './transport.ts';\n\nexport type { BaileysPairing } from './transport.ts';\n\nexport interface BaileysOptions {\n /**\n * Como parear quando a sessão não tem credenciais: `'qr'` (padrão) emite `connection.qr`;\n * `{ phone }` pede um código de pareamento para o número (só dígitos, com DDI) e emite\n * `connection.pairing-code`.\n */\n readonly pairing?: BaileysPairing;\n /**\n * Versão do WhatsApp Web a anunciar. Sem ela, o transport busca a mais recente na primeira\n * conexão e, se a busca falhar, usa a que vem com o Baileys.\n */\n readonly version?: WAVersion;\n /**\n * Nível mínimo das linhas do próprio Baileys (sincronização, pre-keys, protocolo), em inglês.\n * Padrão: `'warn'`; o estado da conexão o bot já loga em PT. Use `'debug'` para investigar o\n * Baileys. Vale o mais alto entre este e o nível do bot.\n */\n readonly logLevel?: LogLevel;\n}\n\nexport function baileys(options: BaileysOptions = {}): (deps: TransportDeps) => Transport {\n const pairing = options.pairing ?? 'qr';\n // Na fábrica, um número inválido vira `BotConfigError` no `createBot`, antes de qualquer\n // conexão.\n if (pairing !== 'qr' && !/^\\d{8,15}$/.test(pairing.phone)) {\n throw new TypeError(\n `baileys: pairing.phone deve ter só dígitos, com DDI (ex.: 5511999999999); recebido \"${pairing.phone}\"`,\n );\n }\n const logLevel = options.logLevel ?? 'warn';\n if (!isLogLevel(logLevel)) {\n throw new TypeError(`baileys: logLevel desconhecido \"${String(logLevel)}\"`);\n }\n return (deps) =>\n new BaileysTransport({ pairing, logLevel, driver: driver(options.version, deps) }, deps);\n}\n\nfunction driver(fixed: WAVersion | undefined, deps: TransportDeps): BaileysDriver {\n let latest: Promise<WAVersion> | undefined;\n return {\n makeSocket: ({ auth, logger, version, cachedGroupMetadata }) =>\n makeWASocket({\n auth,\n logger,\n version,\n cachedGroupMetadata,\n browser: Browsers.ubuntu('Chrome'),\n }),\n version: () => {\n if (fixed) return Promise.resolve(fixed);\n // Uma busca por transport: a versão não muda entre reconexões do mesmo processo.\n latest ??= fetchLatestBaileysVersion().then(({ version, error }) => {\n if (error !== undefined) {\n deps.log.warn('não deu para buscar a versão do WhatsApp Web; usando a do Baileys', {\n err: error,\n });\n }\n return version;\n });\n return latest;\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usebridger/transport-baileys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Transport do Bridger para o WhatsApp via Baileys.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@usebridger/core": "^0.
|
|
28
|
+
"@usebridger/core": "^0.3.0",
|
|
29
29
|
"baileys": "7.0.0-rc14"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@usebridger/testing": "^0.
|
|
32
|
+
"@usebridger/testing": "^0.3.0"
|
|
33
33
|
},
|
|
34
34
|
"publishConfig": {
|
|
35
35
|
"access": "public"
|