wechaty / puppet-whatsapp

Wechaty Puppet for Whatsapp
https://npmjs.com/package/wechaty-puppet-whatsapp
Apache License 2.0
24 stars 17 forks source link

Is there possible to run two Wechaty instance with Puppet Whatsapp? #393

Open huan opened 1 year ago

huan commented 1 year ago

There's a scenario where in one Node.js process, we need to instantiate two Wechaty instances to support managing two Whatsapp accounts.

We know that Puppet Whatsapp will use.wwebjs_auth folder to store the session data. Have we tested this situation? Will it work or not?

kaihungc1993 commented 1 year ago

Here's an example code of this scenario:

app.post('/register', (req: Request, res: Response) => {
  // Create a bot
  var bot = WechatyBuilder.build({name: bot',})

  // onScan
  bot.on('scan', (qrcode, status) => {
    if (status === ScanStatus.Waiting || status === ScanStatus.Timeout) {
      const qrcodeImageUrl = ['https://wechaty.js.org/qrcode/', encodeURIComponent(qrcode),].join('')
      log.info('[Wechaty]', 'onScan: %s(%s) - qrcodeImageUrl: %s', ScanStatus[status], status, qrcodeImageUrl)
      res.send(`<div><a href="${qrcodeImageUrl}" target="_blank">Scan this QR Code</a></div>`);  // Output the QR link on the webpage
    } else {
      log.info('[Wechaty]', 'onScan: %s(%s)', ScanStatus[status], status)
    }
  })

  // onLogin / onLogout
  bot.on('login', (user: Contact) =>{
    log.info('[Wechaty] ', '%s login', user))
  bot.on('logout', onLogout)

  bot.start()
    .then(() => {log.info('[Wechaty] ', 'Wechaty Bot Started.')})
    .catch(e => log.error('[Wechaty] ', e))
});

Here's the error code when a second account logs in

Server listening on port 3000
////// New User Register Request //////
23:50:56 INFO [Wechaty]  Wechaty Bot Started.
23:51:20 INFO LoginEventHandler 
...
23:51:20 INFO [Wechaty] onScan: Waiting(2) - qrcodeImageUrl: ..
23:51:42 INFO LoginEventHandler onAuthenticated()
...
23:51:50 INFO PuppetWhatsapp READY
////// New User Register Request //////
23:52:10 WARN Manager asystole count: 1
23:52:10 INFO [Wechaty]  Wechaty Bot Started.
Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'getContacts')
    at __puppeteer_evaluation_script__:2:34
    at ExecutionContext._evaluateInternal (C:\Wechaty_v1.2\wechaty\node_modules\puppeteer\src\common\ExecutionContext.ts:273:13)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ExecutionContext.evaluate (C:\Wechaty_v1.2\wechaty\node_modules\puppeteer\src\common\ExecutionContext.ts:140:12)
    at async Client.getContacts (C:\Wechaty_v1.2\wechaty\node_modules\@juzi\whatsapp-web.js\src\Client.js:768:24)
    at async Manager.syncContactOrRoomList (file:///C:/D(Kai)/%E5%89%B5%E6%A5%AD/Wechaty_v1.2/wechaty/node_modules/wechaty-puppet-whatsapp/src/manager.ts:190:44)
    at async Job.job (file:///C:/D(Kai)/%E5%89%B5%E6%A5%AD/Wechaty_v1.2/wechaty/node_modules/wechaty-puppet-whatsapp/src/manager.ts:237:33)
kaihungc1993 commented 1 year ago

According to this discussion, I found that the Whatsapp instance is created with fixed authStrategy

https://github.com/wechaty/puppet-whatsapp/blob/75bb0c06c44286f3a7042773dc9159efe2dc9cf5/src/whatsapp/whatsapp-manager.ts#L84

this.whatsAppClient = new WhatsApp({
      authStrategy: new LocalAuth({ clientId: session }),
      puppeteer: puppeteerOptions,
      // can no longer customize refresh interval
      // refresh time gap is set to 15 seconds
      restartOnAuthFail: true,
      ...restOptions,
    })

Is there a way that wechaty users can change this?

According to this, we should allow the Wechaty wrapper to take in this Client ID.

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

const client1 = new Client({
    authStrategy: new LocalAuth({ clientId: "client-one" })
});

const client2 = new Client({
    authStrategy: new LocalAuth({ clientId: "client-two" })
});

For example

const bot = WechatyBuilder.build({name: 'wechaty-bot', client_id:'client-one'})

@su-chang Given that you are the most recent author, could you response to this? Thank you.

huan commented 1 year ago

@kaihungc1993 thank you very much for the detailed investigation and the solution proposal! We will have a community meeting the day after tomorrow and I believe the @su-chang will be there, you are welcome to join and let’s add this issue to the discussion agenda!

see: https://docs.google.com/document/u/0/d/1fVCk8qRYc4RKGMf2UY5HOe07hEhPUOpGC34v88GEFJg/mobilebasic

su-chang commented 1 year ago

@kaihungc1993 puppet-whatsapp support customize the authStrategy by memory-card. Here is a specific code example for you.

I hope you can resolve it using this approach. If you still have any questions or concerns about it, please feel free to let me know.

Example

import MemoryCard from 'memory-card'
import { WechatyBuilder } from 'wechaty'
import PuppetWhatsapp from 'wechaty-puppet-whatsapp'

(async () => {
  const MEMORY_SLOT = 'PUPPET_WHATSAPP_CLIENT_ID'
  const puppet = new PuppetWhatsapp()

  const memoryCard = new MemoryCard('wechaty')
  await memoryCard.load()
  const puppetMemoryCard = memoryCard.multiplex('puppet') // DO NOT CHANGE IT!
  await puppetMemoryCard.set(MEMORY_SLOT, 'client-1') // user defined
  const bot = WechatyBuilder.build({
    puppet: puppet,
    memory: memoryCard,
  })

  bot
    // base event
    .on('scan', (data) => {
      console.log('data :>> ', JSON.stringify(data));
    })
    .on('login', (user) => {
      console.log('user :>> ', JSON.stringify(user));
    })

  await bot.start()
})()

Screenshot

image

kaihungc1993 commented 1 year ago

I have modified the code accordingly. It now shows the QR code image and allows me to scan it. However, the scan doesn't seem to be successful. Here's the error log:

19:45:46 INFO PuppetWhatsapp SCAN
19:45:46 INFO [Wechaty] onScan: Waiting(2) - qrcodeImageUrl: https://wechaty.js.org/qrcode/2%40SIsenHr7L0N%2F3S2AuJVsp3ZUlFKgpNoEIO7YI%2FpvM7N0ZfvK3%2B1%2By6EFjtUVoQf6%2F24eH6qQ5JIuBw%3D%3D%2Cl2%2FhctzbrBh7F%2
FZGa%2B8nB7%2FUnfI3Cw48mhUvoMriHnE%3D%2CL7rntphKMJEVWpeLVt2OnCHvTsnL5hF%2BFmIBEFC22CQ%3D%2CTlQzNRhwIll8spKZGomxFITUILCVBnrC%2BzZwlbjC7Ss%3D
Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'getContacts')
    at __puppeteer_evaluation_script__:2:34
    at ExecutionContext._evaluateInternal (C:\xxx\Wechaty_v1.2\wechaty\node_modules\puppeteer\src\common\ExecutionContext.ts:273:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ExecutionContext.evaluate (C:\xxx\Wechaty_v1.2\wechaty\node_modules\puppeteer\src\common\ExecutionContext.ts:140:12)
    at async Client.getContacts (C:\xxx\Wechaty_v1.2\wechaty\node_modules\@juzi\whatsapp-web.js\src\Client.js:768:24)
    at async Manager.syncContactOrRoomList (file:///C:/xxx/%E5%89%B5%E6%A5%AD/Wechaty_v1.2/wechaty/node_modules/wechaty-puppet-whatsapp/src/manager.ts:190:44)
    at async Job.job (file:///C:/xxx/%E5%89%B5%E6%A5%AD/Wechaty_v1.2/wechaty/node_modules/wechaty-puppet-whatsapp/src/manager.ts:237:33)

Appreciate your help.

su-chang commented 1 year ago

@kaihungc1993 Please use @juzi/wechaty-puppet-whatsapp and I think it could resolve this problem.

Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'getContacts')

It seems that the version of whatsapp-web.js in wechaty-puppet-whatsapp is outdated. I will fix it this week.

kaihungc1993 commented 1 year ago

Thank you. I'm able to support multi-user now.