How to Build Your First Whatsapp Bot with Node.js

WhatsApp Messenger, or simply WhatsApp, is an American freeware, cross-platform messaging and Voice over IP (VoIP) service owned by Facebook, Inc. It allows users to send text messages and voice messages, make voice and video calls, and share images, documents, user locations, and other media. It became the world's most popular messaging application by 2015 and has over 2 billion users worldwide as of February 2020. It has become the primary means of electronic communication in multiple countries and locations, including Latin America, the Indian subcontinent, and large parts of Europe and Africa.

Whatsapp offers the Whatsapp business API, the official API for businesses to reach their clients on Whatsapp. The Whatsapp Business API is not available for everyone. Therefore, in this article rather than using the official API, we'll use whatsapp-web.js a third-party library based on Whatsapp web, the WhatsApp version running in the browser.

Prerequisites

  • Node.js v10 or higher installed. You can get Node.js at nodejs.org/en/download
  • a Whatsapp account
  • basic javascript knowledge

Let's set up the project. In the terminal, change the directory to the folder specially created for this project and run npm init to create a package.json file. Now we will install the whatsapp-web.js and qrcode-terminal (to display QR codes) libraries by running npm i whatsapp-web.js qrcode-terminal.

Let's create our bot now. First, let's discuss what our bot will be able to do. For this article, we're going to create a simple bot that:

  • responds to every message by 'Well received!'
  • updates the user status message when the message has this template: !status hello.

To start, create a new file named app.js in the project directory and insert the following code.

const { Client } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');
const fs = require('fs');

// Check if a session file exists and load it if so
const SESSION_FILE_PATH = './session.json';
let sessionCfg;
if (fs.existsSync(SESSION_FILE_PATH)) {
    sessionCfg = require(SESSION_FILE_PATH);
}

// You can use an existing session and avoid scanning a QR code
// by adding a "session" object to the client options.
const bot = new Client({ session: sessionCfg });

// Initialize the bot instance
bot.initialize();

// Display the Qr Code when created
bot.on('qr', (qr) => {
    qrcode.generate(qr, { small: true });
});

// Save session when the user scans the QR code
bot.on('authenticated', (session) => {
  console.log('AUTHENTICATED', session);
  sessionCfg=session;
  fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), (err) => {
      if (err) {
          console.error(err);
      }
  });
});

// React to incomming messages
bot.on('message', async (msg) => {
  if (msg.body.startsWith('!status ')) {
      // Update user status message
      let newStatus = msg.body.split('!status ')[1];
      await bot.setStatus(newStatus);
      msg.reply('Status message updated!');
  } else {
      // Reply to any other messages with `Well received!`
      msg.reply('Well received!');
  }
});

// Display a disconnection message when client get logged out
bot.on('disconnected', (reason) => {
  console.log('Client was logged out', reason);
});

Let's go through the different parts of this code.

const { Client } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');
const fs = require('fs');

At this point, we're just importing the libraries we need in this project.

// Check if a session file exists and load it if so
const SESSION_FILE_PATH = './session.json';
let sessionCfg;
if (fs.existsSync(SESSION_FILE_PATH)) {
    sessionCfg = require(SESSION_FILE_PATH);
}

// You can use an existing session and avoid scanning a QR code
// by adding a "session" object to the client options.
const bot = new Client({ session: sessionCfg });

// Initialize the bot instance
bot.initialize();

We are now checking if an old Whatsapp web session exists and creating the bot using that session if so. The session is saved in the file session.json. After creating the bot we initialize it to use it.

// Display the Qr Code when created
bot.on('qr', (qr) => {
    qrcode.generate(qr, { small: true });
});

// Save session when the user scans the QR code
bot.on('authenticated', (session) => {
  console.log('AUTHENTICATED', session);
  sessionCfg=session;
  fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), (err) => {
      if (err) {
          console.error(err);
      }
  });
});

Like many things in javascript, this library is event-based. When the library is ready, and a QR code is generated, a qr event gets fired. We use the qrcode-terminal library to display it in the terminal. When the user scans that QR code, the authentication event gets fired. We save the session file in session.json for future use.

// React to incomming messages
bot.on('message', async (msg) => {
  if (msg.body.startsWith('!status ')) {
      // Update user status message
      let newStatus = msg.body.split('!status ')[1];
      await bot.setStatus(newStatus);
      msg.reply('Status message updated!');
  } else {
      // Reply to any other messages with `I got you`
      msg.reply('Well received!');
  }
});

In this last part, we react to message events; when the message has this template '!status xxx', we set the user status message to 'xxx' and reply by 'Well received!' if not.

Obviously, you can do more than a bot that sets the user's status message and reply with 'Well received!'. The whatsapp-web.js library has way more features. I hope you enjoyed this article, let me know your impressions.

References

Credits

No Comments Yet