Separate WhatsApp auth from daemon into standalone script

- Add src/auth.ts for interactive QR code authentication
- Add `npm run auth` script
- Update setup skill for current Node.js architecture
- Daemon (src/index.ts) now only uses stored credentials

Auth is run during setup; daemon assumes credentials exist and
shows macOS notification if re-auth is needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-01-31 19:06:25 +02:00
parent e1867f8d27
commit 8a385c7988
4 changed files with 232 additions and 118 deletions

89
src/auth.ts Normal file
View File

@@ -0,0 +1,89 @@
/**
* WhatsApp Authentication Script
*
* Run this during setup to authenticate with WhatsApp.
* Displays QR code, waits for scan, saves credentials, then exits.
*
* Usage: npx tsx src/auth.ts
*/
import makeWASocket, {
useMultiFileAuthState,
DisconnectReason,
makeCacheableSignalKeyStore,
} from '@whiskeysockets/baileys';
import pino from 'pino';
import qrcode from 'qrcode-terminal';
import fs from 'fs';
import path from 'path';
const AUTH_DIR = './store/auth';
const logger = pino({
level: 'warn', // Quiet logging - only show errors
});
async function authenticate(): Promise<void> {
fs.mkdirSync(AUTH_DIR, { recursive: true });
const { state, saveCreds } = await useMultiFileAuthState(AUTH_DIR);
// Check if already authenticated
if (state.creds.registered) {
console.log('✓ Already authenticated with WhatsApp');
console.log(' To re-authenticate, delete the store/auth folder and run again.');
process.exit(0);
}
console.log('Starting WhatsApp authentication...\n');
const sock = makeWASocket({
auth: {
creds: state.creds,
keys: makeCacheableSignalKeyStore(state.keys, logger),
},
printQRInTerminal: false,
logger,
browser: ['NanoClaw', 'Chrome', '1.0.0'],
});
sock.ev.on('connection.update', (update) => {
const { connection, lastDisconnect, qr } = update;
if (qr) {
console.log('Scan this QR code with WhatsApp:\n');
console.log(' 1. Open WhatsApp on your phone');
console.log(' 2. Tap Settings → Linked Devices → Link a Device');
console.log(' 3. Point your camera at the QR code below\n');
qrcode.generate(qr, { small: true });
}
if (connection === 'close') {
const reason = (lastDisconnect?.error as any)?.output?.statusCode;
if (reason === DisconnectReason.loggedOut) {
console.log('\n✗ Logged out. Delete store/auth and try again.');
process.exit(1);
} else {
console.log('\n✗ Connection failed. Please try again.');
process.exit(1);
}
}
if (connection === 'open') {
console.log('\n✓ Successfully authenticated with WhatsApp!');
console.log(' Credentials saved to store/auth/');
console.log(' You can now start the NanoClaw service.\n');
// Give it a moment to save credentials, then exit
setTimeout(() => process.exit(0), 1000);
}
});
sock.ev.on('creds.update', saveCreds);
}
authenticate().catch((err) => {
console.error('Authentication failed:', err.message);
process.exit(1);
});