Integrate WhatsApp Cloud API with your AdonisJS App

·

4 min read

Integrate WhatsApp Cloud API with your AdonisJS App

A few months ago I tried AdonisJS and miraculously it was able to make me comfortable, which is offered, like Laravel but in a Node.js environment.

During this period of approach (Taaruf in Islam), I found a lot of cool new things, Before that I made a package for Node.js and I'm interested in making a package for AdonisJS.

It just happened that I am working on a project that also happened to have AdoninJS as the base project, so all I had to do was create a package to integrate with the WhatsApp Cloud API.

It so happened that I was working on a project that also happened to be the base project AdonisJS, so all I had to do was create a package to integrate with the WhatsApp Cloud API.

Let's get started, Make sure you have registered yourself as a Meta Developer here, and then don't forget to activate two-factor authentication. You can see it in full on the official page here.

Setup

To start with the setup, the first thing we need to do is install the package I have published.

npm i adonisjs-whatsapp
# or
yarn add adonisjs-whatsapp

Then run the configuration command to apply some of the existing requirements.

node ace configure adonisjs-whatsapp

After executing the command above, it will create several files including config/whatsapp.ts, you can customize them.

// config/whatsapp.ts
import Env from '@ioc:Adonis/Core/Env'
import { WhatsAppConfig } from '@ioc:Adonis/Addons/WhatsApp'

const whatsappConfig: WhatsAppConfig = {
  webhookRoute: '/webhook/whatsapp',
  timeout: 60_000,
  phoneNumberId: Env.get('WABA_ID'),
  accessToken: Env.get('WABA_TOKEN'),
  verifyToken: Env.get('WABA_VERIFY'),
  graphUrl: 'https://graph.facebook.com',
  graphVersion: 'v16.0',
}

export default whatsappConfig

Most importantly, you have to adjust the value of the environment variables that have been created, including the following.

WABA_ID=
WABA_TOKEN=
WABA_VERIFY=

And don't forget to add the following lines to the env.ts file.

WABA_ID: Env.schema.number(),
WABA_TOKEN: Env.schema.string(),
WABA_VERIFY: Env.schema.string(),

Usages

It's very easy to set up, just a few steps, then we'll go to its use. Let's open the start/whatsapp.ts file.

// start/whatsapp.ts

import WhatsApp from '@ioc:Adonis/Addons/WhatsApp'

WhatsApp.on('message:text', (message) => {
  // listen to text messages
})

Events currently supported include the following: message:text, message:image, message:document, message:audio, message:video, message:sticker, message:location, message:contacts, message:button and message:list.

To listen to everything (without being specific), you can use an asterisk. This for example:

// start/whatsapp.ts

import WhatsApp from '@ioc:Adonis/Addons/WhatsApp'

WhatsApp.on('message:*', (message) => {
  // listen to any messages
})

The message variable we are sending (callback) is an object, I'll give you an example, you can see the type here.

{
  "from": 6281234567890,
  "sender": "People",
  "wamid": "wamid.xxxx",
  "data": {
    "body": "Lorem ipsum dolor sit amet"
  },
  "timestamp": 1678440781,
  "type": "text"
}

For other types of messages, it's more or less the same, only the body part might be different. For more details, we can refer to the official documentation of Meta, from the documentation, on the data object I cast entry[0].changes[0].value.messages[0] and enter the message type, if text then entry[0].changes[0].value.messages[0].text and so on.

To listen to the status of a message, whether it was sent, received or read, you can use the status:sent, status:delivered and status:read events, then in the callback, I send variables like the following:

// start/whatsapp.ts

import WhatsApp from '@ioc:Adonis/Addons/WhatsApp'

WhatsApp.on('status:*', (message) => {
  // {"from": 6281234567890, "wamid": "wamid.xxxxx", "timestamp": 1678440781, "status": "read"}
})

To send messages or reply to messages, you still use the same singleton. You can call it from the preload file (in this case start/whatsapp.ts or something else), or via the controller.

// app/Controllers/Http/ExampleController.ts

import WhatsApp from '@ioc:Adonis/Addons/WhatsApp'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class ExampleController {
  public async example(ctx: HttpContextContract) {
    const { message } = ctx.request.only(['message'])
    await WhatsApp.sendText(6281234567890, message)
    return { success: true }
  }
}

Everything is in the autocomplete, so for sending images you can use the sendImage method, for sending documents using sendDocument and so on, with the parameters I have set.

Maybe that's all. If there is something you want to ask, please submit it in the comments, and if there are problems, you can open an issue in this repository. Thanks!