You are browsing as a guest. Sign up (or log in) to start making projects!

2h 28m 4s logged

Devlog: XenoDeal | The Listener Wakes Up

June 20

Today was a bit hard (it’s the first day on this project, and I’m catching strays breh). I started with:

  1. Planning out the infra
  2. Making the project base

The stack for this one is: PostgreSQL, Node.js, Telegraf, and wwebjs.

I ended up building out the basis for the Telegram, PostgreSQL, and WhatsApp wrappers. Telegram and Postgres were easy, being a few lines each, for now. WhatsApp, being the main part of the app, wanted to give me problems. Four total.

Issue 1: Puppeteer ghosting me. Setting up the project, making sure init and env loading worked across all files, Node kept complaining about

“Puppeteer Missing.” I’d just installed it, so I assumed it was fine. Turns out pnpm takes security seriously and silently blocks Puppeteer’s install script by default. To make it worse, I fat-fingered Enter instead of Space on the approve-builds screen, so even the prompt to fix it slipped past me. Couldn’t figure out how to re-trigger the script, so I just pointed it at my system Chromium instead:

const client = new Client({
    puppeteer: {
        executablePath: '/usr/bin/chromium',
        headless: true,
        args: ['--no-sandbox', '--disable-setuid-sandbox']
    },
    authStrategy: new LocalAuth({
        dataPath: 'auth_data'
    })
});

Issue 2: The Logout Crash. I wanted to check that client.on('disconnected') actually fires correctly, so I tested it the easy way: logged out the linked WhatsApp session from my phone. Instead of a clean disconnect, client.on('ready') fired three times, then it crashed:

Failed to add page binding with name onQRChangedEvent: window['onQRChangedEvent'] already exists!

Best guess: wwebjs trying to inject its page bindings into a page that already had them. Possibly a puppeteer-core@24.38.0 version mismatch against what whatsapp-web.js@1.34.7 actually expects internally, but I’m not fully sure that’s the real cause yet. Problem for another day.

Issue 3: The Silent Hang. Whilst testing the LocalAuth implementation, I Ctrl+C’d the process without realizing Chromium leaves behind a SingletonLock file. Next launch just hung indefinitely; no warning, no error, nothing. Found that out the hard way. I ended up clearing the stale lock and added this so it can’t happen again:

process.on('SIGINT', async () => {
    await client.destroy();
    process.exit(0);
});

tl;dr: It lets Chromium clean up after itself on every manual stop, instead of leaving a corpse behind for next time.

Issue 4: the Date/Time Problem. Setting up message logging, I converted msg.timestamp (Unix seconds) to milliseconds for Postgres with msg.timestamp * 1000. It wasn’t enough. Every insert failed with:

date/time field value out of range: "1782000093000"

Turns out pg doesn’t know what to do with a raw JS number where it expects a date, and just stringifies it and Postgres rejects the result outright. Had to wrap it in an actual Date object:

new Date(msg.timestamp * 1000)

(Need to double check: I remember it still not behaving right away even after this fix, possibly just the client needing a moment to fully reconnect after restart rather than the date fix itself being incomplete. Worth confirming next time it comes up.)

What’s Next

So… reads design docs, according to this, I’ll be establishing Core Intelligence next. Second most exciting part of the whole build. Covers:

  • Claude integration (analyze each listing, provide a ranking)
  • Sold tracking
  • The dashboard

See y’all later!

(PS: It did end up working)

0
2

Comments 0

No comments yet. Be the first!