Venom WhatsApp Automation Framework

repository·master·Indexed 27 days ago

https://github.com/vynect/venom

A high-performance WhatsApp automation platform for Node.js built on Puppeteer. Venom provides a clean API for building chatbots and enterprise-scale solutions, featuring session persistence, multi-session support, and advanced messaging capabilities. It supports sending text, media, locations, and interactive elements like polls and list menus, as well as managing groups, retrieving chat data, and listening to WhatsApp events.

Tokens
14.4K
Snippets
38
Records
64
Agent score
90%

What's inside venom-bot

  1. Quick Start with Venom

    master

    Initialize a new session using create() and listen for messages using onMessage. When a specific message is received, respond using sendText.

    Note: Sessions are saved automatically, so you do not need to re-scan the QR code on every restart.

    import { create } from 'venom-bot';
    
    create({ session: 'venom-bot' }).then((client) => {
    
      client.onMessage(async (message) => {
        if (message.body === 'hello') {
          await client.sendText(message.from, 'Hey there! 👋 I\'m running on Venom.');
        }
      });
    
    });
  2. Initialize a Venom session

    master

    Use venom.create() to start a WhatsApp session. By default, it uses multidevice: true. If you need to use a non-multidevice version, set multidevice: false in the options.

    Venom creates an instance of WhatsApp Web. If you are not logged in, a QR code will be printed in the terminal for you to scan with your phone. Sessions are remembered, so you won't need to authenticate every time.

    You can run multiple sessions simultaneously by providing unique session names.

    const venom = require('venom-bot');
    
    venom
      .create({
        session: 'session-name', // name of session
        multidevice: false // for version not multidevice use false (default: true)
      })
      .then((client) => start(client))
      .catch((erro) => {
        console.log(erro);
      });
    
    function start(client) {
      client.onMessage((message) => {
        if (message.body === 'Hi' && message.isGroupMsg === false) {
          client
            .sendText(message.from, 'Welcome Venom 🕷')
            .then((result) => {
              console.log('Result: ', result); // returns success object
            })
            .catch((erro) => {
              console.error('Error when sending: ', erro);
            });
        }
      });
    }
    const venom = require('venom-bot');
    
    venom
      .create({
        session: 'session-name', //name of session
        multidevice: false // for version not multidevice use false.(default: true)
      })
      .then((client) => start(client))
      .catch((erro) => {
        console.log(erro);
      });
    
    function start(client) {
      client.onMessage((message) => {
        if (message.body === 'Hi' && message.isGroupMsg === false) {
          client
            .sendText(message.from, 'Welcome Venom 🕷')
            .then((result) => {
              console.log('Result: ', result); //return object success
            })
            .catch((erro) => {
              console.error('Error when sending: ', erro); //return object error
            });
        }
      });
    }
  3. Install venom-bot

    master

    You can install the stable version of venom-bot via npm, use nightly releases for the latest features, or install directly from the GitHub repository.

    Stable version:

    npm i --save venom-bot

    Nightly releases:

    npm i --save https://github.com/orkestral/venom/releases/download/nightly/venom-bot-nightly.tgz

    Current repository (Beta):

    npm i github:orkestral/venom
    npm i --save venom-bot
  4. Export the QR Code as an image

    master

    By default, the QR code is displayed in the terminal. To capture the QR code and save it as an image file (e.g., out.png), use the venom.create callback function. You can parse the base64Qr string to extract the image data and write it to the file system using fs.writeFile.

    const fs = require('fs');
    const venom = require('venom-bot');
    
    venom
      .create(
        'sessionName',
        (base64Qr, asciiQR, attempts, urlCode) => {
          console.log(asciiQR); // Optional to log the QR in the terminal
          var matches = base64Qr.match(/^data:([A-Za-z-+/]+);base64,(.+)$/),
            response = {};
    
          if (matches.length !== 3) {
            return new Error('Invalid input string');
          }
          response.type = matches[1];
          response.data = new Buffer.from(matches[2], 'base64');
    
          var imageBuffer = response;
          require('fs').writeFile(
            'out.png',
            imageBuffer['data'],
            'binary',
            function (err) {
              if (err != null) {
                console.log(err);
              }
            }
          );
        },
        undefined,
        { logQR: false }
      )
      .then((client) => {
        start(client);
      })
      .catch((erro) => {
        console.log(erro);
      });
  5. Create a Venom Bot client

    master

    To initialize a Venom Bot instance, call the create() method. This method returns a Promise that resolves to a Whatsapp instance. You can start a basic session without arguments, or provide a session name to support multiple concurrent sessions.

    const venom = require('venom-bot');
    
    venom
      .create()
      .then((client) => start(client))
      .catch((error) => console.log(error));
  6. Download and decrypt media files

    master

    To download media sent in a message, listen for messages where isMedia or isMMS is true. Use client.decryptFile(message) to obtain a buffer of the decrypted file. You can then use a library like mime-types to determine the correct file extension and save the buffer to disk.

    import fs = require('fs');
    import mime = require('mime-types');
    
    client.onMessage( async (message) => {
      if (message.isMedia === true || message.isMMS === true) {
        const buffer = await client.decryptFile(message);
        // At this point you can do whatever you want with the buffer
        // Most likely you want to write it into a file
        const fileName = `some-file-name.${mime.extension(message.mimetype)}`;
        await fs.writeFile(fileName, buffer, (err) => {
          ...
        });
      }
    });
  7. Handle session resilience and shutdown

    master

    To prevent session loss and handle disconnections:

    1. Handle State Changes: Use onStateChange to react to CONFLICT (reclaim session with client.useHere()) or UNPAIRED (session expired).
    2. Graceful Shutdown: Always call client.close() when shutting down the process (e.g., on SIGINT) to ensure the session is saved correctly. Do not simply kill the process.

    Session Statuses: isLogged, notLogged, browserClose, qrReadSuccess, qrReadFail, autocloseCalled, desconnectedMobile, serverClose, chatsAvailable, deviceNotConnected, successChat, waitForLogin, waitChat.

    client.onStateChange((state) => {
      if (state === 'CONFLICT') client.useHere();   // reclaim session
      if (state === 'UNPAIRED') console.log('Session expired');
    });
    
    // Graceful shutdown
    process.on('SIGINT', () => client.close());
  8. Configure Venom advanced options

    master

    The create() function accepts an options object to control the browser, session, logging, and connection settings.

    Key Configuration Groups:

    • Browser: headless, devtools, browserWS, browserPathExecutable, puppeteerOptions, browserArgs, addBrowserArgs.
    • Session: folderNameToken, mkdirFolderToken, createPathFileToken.
    • Logging: debug, logQR, updatesLog, disableSpins, disableWelcome.
    • Connection: autoClose, addProxy, userProxy, userPass.

    You can also provide a browserInstance callback to access the Puppeteer browser and page objects directly.

    create({
      session: 'production',
    
      catchQR: (base64Qr, asciiQR, attempts, urlCode) => {
        console.log(`Scan attempt ${attempts}`);
      },
    
      statusFind: (status, session) => {
        console.log(`[${session}] Status: ${status}`);
      },
    
      options: {
        // Browser
        headless: 'new',
        devtools: false,
        browserWS: '',
        browserPathExecutable: '',
        puppeteerOptions: {},
        browserArgs: [''],
        addBrowserArgs: [''],
    
        // Session
        folderNameToken: 'tokens',
        mkdirFolderToken: '',
        createPathFileToken: false,
    
        // Logging
        debug: false,
        logQR: true,
        updatesLog: true,
        disableSpins: false,
        disableWelcome: false,
    
        // Connection
        autoClose: 60000,
        addProxy: [''],
        userProxy: '',
        userPass: ''
      },
    
      browserInstance: (browser, waPage) => {
        console.log('Browser PID:', browser.process().pid);
      }
    });
  9. Configure venom.create() options

    master

    The venom.create() method accepts several optional parameters to customize the session behavior.

    Note for Linux users: You must pass the --user-agent argument within browserArgs if running on a Linux server.

    Common Configuration Options

    KeyTypeDescription
    multidevicebooleanUse false for non-multidevice versions (default: true)
    folderNameTokenstringFolder name where tokens are saved
    mkdirFolderTokenstringDirectory for tokens (e.g., '/node_modules')
    headlessbooleanRun Chrome in headless mode
    devtoolsbooleanOpen devtools by default
    debugbooleanOpens a debug session
    logQRbooleanAutomatically logs QR in terminal
    browserWSstringUse a specific BrowserWSEndpoint
    browserArgsarrayOriginal Puppeteer browser arguments
    addBrowserArgsarrayAdd arguments without overwriting original ones
    puppeteerOptionsobjectOptions passed to puppeteer.launch
    disableSpinsbooleanDisables Spinnies animation (useful for Docker)
    disableWelcomebooleanDisables the initial welcome message
    updatesLogbooleanLogs info updates automatically
    autoClosenumberAutomatically closes Venom after scanning QR (ms). Set 0 or false to disable (default: 60000)
    createPathFileTokenbooleanCreates a folder when inserting an object into the browser
    addProxyarrayProxy server list (e.g., ['e1.p.webshare.io:01'])
    userProxystringProxy login username
    userPassstringProxy password

    Callback Signatures

    venom.create supports the following callback arguments:

    1. catchQR: (base64Qrimg, asciiQR, attempts, urlCode) => void
    2. statusFind: (statusSession, session) => void
    3. BrowserSessionToken: An object containing WABrowserId, WASecretBundle, WAToken1, and WAToken2 to manually restore a session.
    4. BrowserInstance: (browser, waPage) => void (provides access to the Puppeteer browser and page).
    venom
      .create(
        'sessionName',
        (base64Qrimg, asciiQR, attempts, urlCode) => {
          console.log('Number of attempts to read the qrcode: ', attempts);
          console.log('Terminal qrcode: ', asciiQR);
          console.log('base64 image string qrcode: ', base64Qrimg);
          console.log('urlCode (data-ref): ', urlCode);
        },
        (statusSession, session) => {
          console.log('Status Session: ', statusSession);
          console.log('Session name: ', session);
        },
        {
          multidevice: false,
          folderNameToken: 'tokens',
          headless: true,
          logQR: true,
          autoClose: 60000,
        },
        {
          WABrowserId: '"UnXjH....."',
          WASecretBundle: '{"key":"+i/nRgW...."}',
          WAToken1: '"0i8...."',
          WAToken2: '"1@lPpzwC...."'
        },
        (browser, waPage) => {
          console.log('Browser PID:', browser.process().pid);
          waPage.screenshot({ path: 'screenshot.png' });
        }
      )
      .then((client) => {
        start(client);
      });
  10. Export QR Code to a file

    master

    To save the QR code as an image file instead of just displaying it in the terminal, use the catchQR callback (the second argument to create) to process the base64Qr string and save it using fs.

    const fs = require('fs');
    const venom = require('venom-bot');
    
    venom
      .create(
        'sessionName',
        (base64Qr, asciiQR) => {
          var matches = base64Qr.match(/^data:([A-Za-z\-\/]+);base64,(.+)$/),
            response = {};
    
          if (matches.length !== 3) {
            return new Error('Invalid input string');
          }
          response.type = matches[1];
          response.data = new Buffer.from(matches[2], 'base64');
    
          var imageBuffer = response;
          fs.writeFile(
            'out.png',
            imageBuffer['data'],
            'binary',
            function (err) {
              if (err != null) {
                console.log(err);
              }
            }
          );
        },
        undefined,
        { logQR: false }
      )
      .then((client) => start(client));