Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem when restoring the session with Mongo store #2631

Closed
1 task done
eletroswing opened this issue Nov 12, 2023 · 7 comments
Closed
1 task done

Problem when restoring the session with Mongo store #2631

eletroswing opened this issue Nov 12, 2023 · 7 comments
Labels
bug Something isn't working

Comments

@eletroswing
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When creating the first session, everything goes fine, and I wait for it to be saved to the database (about 2 minutes). However, when trying to recreate the client using the same clientId, I only get the qr code, not a session. Doing a quick debug I saw that the zip returned from mongo has nothing inside.

Expected behavior

The client(session) will be restored and opened normally

Steps to Reproduce the Bug or Issue

Create a session with mongostore, using a unique client Id and try to restore it by killing the application and starting again.

Relevant Code

const { Client, RemoteAuth } = require('whatsapp-web.js');

// Require database
const { MongoStore } = require('wwebjs-mongo');
const mongoose = require('mongoose');

// Load the session data
mongoose.connect(process.env.MONGODB_URI).then(() => {
const store = new MongoStore({ mongoose: mongoose });
const client = new Client({
authStrategy: new RemoteAuth({
clientId: 'client-id',
store: store,
backupSyncIntervalMs: 300000
})
});

client.initialize();

});

Browser Type

Chromium

WhatsApp Account Type

Standard

Does your WhatsApp account have multidevice enabled?

Yes, I am using Multi Device

Environment

Windows
Android

Additional context

No response

@eletroswing eletroswing added the bug Something isn't working label Nov 12, 2023
@cantdocpp
Copy link

I got the same issue too

@eletroswing
Copy link
Author

Based on what I researched, this is an error in the implementation of remote auth, I found a commit 'trying to fix', but still without success

@farias-77
Copy link

im having the same problem

@eletroswing
Copy link
Author

for me, only local auth is working, i will try to implement a fix for this problem, i think that the error happen on 'zip' step of the process.

@themazim
Copy link

anyone tried this PR?

#2412

Solved the issue for me.

@alechkos
Copy link
Collaborator

alechkos commented Dec 1, 2023

The issue is not related to the library but to the wwebjs-mongo

@alechkos alechkos closed this as completed Dec 1, 2023
@alechkos alechkos mentioned this issue Dec 6, 2023
1 task
@edmilson-dk
Copy link

After a lot of research I discovered that we can use this solution with nodejs 18.20.0 and two other versions mentioned in this issue with more details of the problem caused by the unzipper lib:

I also decided to update the MongoStore code to a newer version of nodejs with typescript that you can import into your code:

import fs from 'fs';
import { GridFSBucket } from 'mongodb';

interface MongoOptions {
  session?: string;
  path?: string;
  bucket?: GridFSBucket;
}

export class MongoStore {
  private mongoose: any;

  constructor({ mongoose }: { mongoose: any }) {
    if (!mongoose) throw new Error('A valid Mongoose instance is required for MongoStore.');
    this.mongoose = mongoose;
  }

  async sessionExists(options: MongoOptions): Promise<boolean> {
    const multiDeviceCollection = this.mongoose.connection.db.collection(`whatsapp-${options.session}.files`);
    const hasExistingSession = await multiDeviceCollection.countDocuments();
    return !!hasExistingSession;
  }

  async save(options: MongoOptions): Promise<void> {
    const bucket = new GridFSBucket(this.mongoose.connection.db, {
      bucketName: `whatsapp-${options.session}`,
    });
    const uploadStream = bucket.openUploadStream(`${options.session}.zip`);
    const readStream = fs.createReadStream(`${options.session}.zip`);
    await new Promise<void>((resolve, reject) => {
      readStream.pipe(uploadStream).on('error', reject).on('finish', resolve);
    });
    await this.deletePrevious(bucket, `${options.session}`);
  }

  async extract(options: MongoOptions): Promise<void> {
    const bucket = new GridFSBucket(this.mongoose.connection.db, {
      bucketName: `whatsapp-${options.session}`,
    });
    return new Promise((resolve, reject) => {
      bucket
        .openDownloadStreamByName(`${options.session}.zip`)
        .pipe(fs.createWriteStream(`${options.path}`))
        .on('error', reject)
        .on('finish', resolve);
    });
  }

  async delete(options: MongoOptions): Promise<void> {
    const bucket = new GridFSBucket(this.mongoose.connection.db, {
      bucketName: `whatsapp-${options.session}`,
    });
    const documents = await bucket
      .find({
        filename: `${options.session}.zip`,
      })
      .toArray();

    await Promise.all(documents.map((doc) => bucket.delete(doc._id)));
  }

  private async deletePrevious(bucket: GridFSBucket, session: string): Promise<void> {
    const documents = await bucket
      .find({
        filename: `${session}.zip`,
      })
      .toArray();
    if (documents.length > 1) {
      const oldSession = documents.reduce((a, b) => (a.uploadDate < b.uploadDate ? a : b));
      await bucket.delete(oldSession._id);
    }
  }
}

@edmilson-dk edmilson-dk mentioned this issue Mar 30, 2024
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants