-
-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathwa-web-to-baileys.ts
More file actions
97 lines (84 loc) · 3.75 KB
/
Copy pathwa-web-to-baileys.ts
File metadata and controls
97 lines (84 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* eslint-disable */
/**
* Reads `.auth/wa-web-dump.json` (produced by `examples/wa-web-dump.js`
* in a logged-in WhatsApp Web tab), runs the migration through the IR,
* and writes a baileys-compatible multi-file auth state.
*
* node --import tsx examples/wa-web-to-baileys.ts
*
* Output goes under `.auth/baileys_from_wa-web/` ready to be fed to
* `useMultiFileAuthState('.auth/baileys_from_wa-web')` from baileys.
*/
import { mkdir, writeFile } from 'node:fs/promises'
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import type { WaWebSnapshot } from '@adapters/wa-web'
import { bufferJsonReplacer, bufferJsonReviver } from '@codec/buffer-json'
import { migrate } from '@migrate'
const IN = process.env.WA_WEB_DUMP ?? '.auth/wa-web-dump-from-web.json'
const OUT_DIR = process.env.WA_WEB_OUT_DIR ?? '.auth/baileys_from_wa-web'
function fileNameForKey(type: string, id: string): string {
// Mirror baileys' useMultiFileAuthState fixFileName:
// `:` → `-`, `/` → `__`. The dump key is the raw libsignal id.
const safe = id.replace(/\//g, '__').replace(/:/g, '-')
return `${type}-${safe}.json`
}
async function main(): Promise<void> {
const text = readFileSync(IN, 'utf-8')
const dump = JSON.parse(text, bufferJsonReviver) as WaWebSnapshot
if (!dump.device.noiseKey) {
console.error(
'wa-web dump has no noiseKey — baileys cannot do Noise handshake without it.\n' +
'Re-run the dumper inside the wa-web tab; if the internal-module path\n' +
'failed, the Noise key cannot be recovered without re-pairing.'
)
process.exit(1)
}
const { data: out, losses } = migrate({
from: 'wa-web',
to: 'baileys',
data: dump,
validate: false
})
console.log('[wa-web → baileys] conversion summary:')
console.log(` registrationId: ${out.creds.registrationId}`)
console.log(` me.id: ${out.creds.me?.id ?? '(none)'}`)
console.log(` me.lid: ${out.creds.me?.lid ?? '(none)'}`)
console.log(` preKeys: ${Object.keys(out.keys['pre-key'] ?? {}).length}`)
console.log(` sessions: ${Object.keys(out.keys.session ?? {}).length}`)
console.log(` sender-keys: ${Object.keys(out.keys['sender-key'] ?? {}).length}`)
console.log(` identities: ${Object.keys(out.keys['identity-key'] ?? {}).length}`)
if (losses.length > 0) {
for (const l of losses) console.log(` ${l.severity} ${l.domain}×${l.count}`)
}
// Write multi-file layout: creds.json + every key family with one file
// per id, JSON-stringified through bufferJsonReplacer so Uint8Array
// round-trips as { type: 'Buffer', data: '<base64>' } — exactly what
// useMultiFileAuthState expects.
const dir = resolve(OUT_DIR)
await mkdir(dir, { recursive: true })
await writeFile(
resolve(dir, 'creds.json'),
JSON.stringify(out.creds, bufferJsonReplacer, 2),
'utf-8'
)
for (const [type, dict] of Object.entries(out.keys)) {
if (!dict) continue
for (const [id, value] of Object.entries(dict as Record<string, unknown>)) {
if (value === null || value === undefined) continue
const path = resolve(dir, fileNameForKey(type, id))
await writeFile(path, JSON.stringify(value, bufferJsonReplacer, 2), 'utf-8')
}
}
console.log(`\n✓ wrote multi-file auth state to ${dir}`)
console.log(
'\nNext step:\n' +
' import { useMultiFileAuthState } from "baileys"\n' +
` const { state, saveCreds } = await useMultiFileAuthState("${OUT_DIR}")\n` +
" // pass `state` to baileys' makeWASocket"
)
}
void main().catch((e) => {
console.error(e)
process.exit(1)
})