Kirim WhatsApp dengan API KirimWA.id dan Node.js

8 min read

Disclaimer
Saya bekerja di AWS, semua opini adalah dari saya pribadi. (I work for AWS, my opinions are my own.)
Kirim WhatsApp dengan API KirimWA.id
API KirimWA.id – Unoffical WhatsApp API Gateway

TeknoCerdas.com – Salam cerdas untuk kita semua. API KirimWA.id adalah layanan unofficial WhatsApp API Gateway untuk mengirimkan pesan WhatsApp dengan melalui HTTP. Pada artikel ini akan ditunjukkan cara kirim WhatsApp dengan API KirimWA.id dan Node.js.

Node.js adalah Javascript runtime berbasis Chrome V8. Dengan Node.js Javascript dapat dijalankan diluar lingkungan browser. Pada tulisan ini tidak dibahas bagaimana menginstall Node.js. Untuk mengikuti tulisan ini sebaiknya gunakan Node.js versi LTS terakhir. Dapat didownload pada laman resmi Node.js di https://nodejs.org/en/download/.

Baca Juga
Kirim WhatsApp dengan API KirimWA.id dan cURL
Kirim WhatsApp dengan API KirimWA.id dan PHP

Saat artikel ini ditulis API KirimWA.id masih dalam status developer preview. Sehingga untuk mendapatkan API Token anda harus mendaftar di https://developer.kirimwa.id/ terlebih dahulu dan menunggu persetujuan secara manual. Setelah disetujui anda dapat menggunakan layanan API KirimWA.id.

Fitur-fitur dari API KirimWA.id diantaranya:

  • API berbasis REST sehingga mudah digunakan
  • Mengirim pesan teks dan gambar
  • Webhook untuk notifikasi pemrosesan pesan
  • Mendukung pengelolaan lebih dari satu nomor atau device

Langkah-langkah untuk mengirimkan pesan adalah:

Pustaka yang digunakan untuk melakukan pemanggilan API adalah pustaka bawaan dari Node.js yaitu https.

0. Membuat Fungsi untuk API KirimWA.id

Fungsi ini digunakan untuk melakukan HTTP request ke server api.kirimwa.id dan mengirimkan beberapa parameter yang dibutuhkan seperti API Token.

Buat sebuah direktori baru bernama nodejs-api-kirimwa.

$ mkdir nodejs-api-kirimwa
$ cd nodejs-api-kirimwa

Buat sebuah file baru bernama functions.js pada direktori yang dibuat diatas. Isi file functions.js terlihat seperti berikut.

const https = require('https');

/**
 * Make a request to API KirimWA.id
 *
 * @param Object params
 * @return Promise
 */
function apiKirimWaRequest(params)
{
  return new Promise((resolve, reject) => {
    let responseBody = '';
    const options = {
      method: params.method || 'GET',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${params.token}`
      }
    }

    if (params.method === 'POST') {
      options.headers['Content-Length'] = params.payload.length;
    }

    const req = https.request(params.url, options, function(res) {
      res.on('data', function concatBody(chunk) {
        responseBody += chunk;
      });

      res.on('end', () => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve({ body: responseBody, response: res });
          return;
        }

        // Non 2XX response
        reject({ body: responseBody, response: res });
      });
    });

    if (params.method === 'POST') {
      req.write(params.payload);
    }

    req.end();
  }); // Promise
}

module.exports.apiKirimWaRequest = apiKirimWaRequest;

1. Tambahkan Device

Untuk menambahkan device digunakan API endpoint POST /v1/devices. Device adalah perangkat yang terasosiasi dengan nomor WhatsApp yang akan digunakan untuk mengirimkan pesan.

Buat sebuah file baru dengan nama add-device.js untuk menambahkan sebuah device. Berikut ini adalah kode Javascript yang digunakan.

const { apiKirimWaRequest } = require('./functions');

(async function() {
  const apiBaseUrl = process.env.API_BASEURL || 'https://api.kirimwa.id/v1';
  const url = new URL(apiBaseUrl + '/devices');
  const reqParams = {
    token: process.env.API_TOKEN,
    url: url,
    method: 'POST',
    payload: JSON.stringify({
        device_id: process.env.DEVICE_ID
    })
  };

  try {
    const { body, response } = await apiKirimWaRequest(reqParams);
    console.log(body);
  } catch (error) {
    console.error('Something went wrong', {
      body: error.body,
      statusCode: error.response.statusCode
    });
  }
})();

Anda dapat menamakan device id sesuai keinginan. Dalam contoh saya namakan ID nya adalah iphone-x-pro. Untuk menjalankan suplai API Token dan device ID dari environment.

$ API_TOKEN=YOUR_API_TOKEN \
DEVICE_ID=iphone-x-pro \
node add-device.js

Jika sukses maka server akan mengembalikan kode HTTP 201 Created.

{
  "id": "iphone-x-pro",
  "status": "disconnected",
  "created_at": "2021-07-09T15:11:53.657Z",
  "meta": {
    "location": "https://api.kirimwa.id/v1/devices/iphone-x-pro"
  }
}

2. Pairing Device Melalui Scan QR Code

Setelah device ditambahkan langkah berikutnya adalah melakukan pairing atau menghubungkan device tersebut ke API KirimWA.id agar terkoneksi. Endpoint yang digunakan adalah GET /v1/qr dengan query string parameter device_id.

Buat sebuah file baru bernama scan-qr.js. Isi dari file tersebut adalah seperti dibawah ini.

const { apiKirimWaRequest } = require('./functions');

(async function() {
  const deviceId = process.env.DEVICE_ID;
  const apiBaseUrl = process.env.API_BASEURL || 'https://api.kirimwa.id/v1';
  const url = new URL(apiBaseUrl + '/qr');
  url.searchParams.set('device_id', deviceId);

  const reqParams = {
    token: process.env.API_TOKEN,
    url: url
  };

  try {
    const { body, response } = await apiKirimWaRequest(reqParams);
    console.log(body);
  } catch (error) {
    console.error('Something went wrong', {
      body: error.body,
      statusCode: error.response.statusCode
    });
  }
})();

Gunakan device_id yang dibuat pada step sebelumnya untuk menampilkan QR code.

$ API_TOKEN=YOUR_API_TOKEN \
DEVICE_ID=iphone-x-pro \
node scan-qr.js

Jika sukses server akan mengembalikan JSON dengan dua atribut yaitu qr_code dan image_url.

{
  "qr_code": "1@U2tS5Q1elzj6Y7IAKDurwvja47SQz8bvW24fb43r3n+gPC4PN1iSNlGLizlfGsrHSD/M6ym6/aYiYw==,xXlcsqVquva7/1c2g8wAZkWdnk2el5tHWh7MWUW2UTc=,v+P3exsbB1W62wX3Vn4dcC==",
  "image_url": "https://api.kirimwa.id/v1/qr/show?qrcode=1%40U2tS5Q1elzj6Y7IAKDurwvja47SQz8bvW24fb43r3n%2BgPC4PN1iSNlGLizlfGsrHSD%2FM6ym6%2FaYiYw%3D%3D%2CxXlcsqVquva7%2F1c2g8wAZkWdnk2el5tHWh7MWUW2UTc%3D%2Cv%2BP3exsbB1W62wX3Vn4dcC%3D%3D&device_id=iphone-x-pro"
}

Yang harus dilakukan adalah segera copy-paste URL yang ada pada atribut image_url pada browser untuk memunculkan gambar QR code. Setelah itu scan QR code tersebut dengan perangkat yang ingin dikoneksikan dengan API KirimWA.id.

3. Mengirim Pesan Teks

Setelah pairing device, untuk mengirim pesan WhatsApp akan digunakan endpoint POST /v1/messages. API KirimWA.id mendukung dua tipe pesan yaitu teks dan gambar.

Berikut adalah contoh untuk mengirim sebuah pesan WhatsApp dengan format teks. Atribut yang digunakan adalah message_type dengan nilai text. Atribut phone_number digunakan untuk nomor tujuan dan message digunakan untuk isi dari pesan yang akan dikirimkan.

Setiap pengiriman terasosiasi dengan sebuah device_id. Gunakan device_id yang telah ditambahkan sebelumnya.

Buat sebuah file baru bernama send-message.js dan salin kode dibawah ini.

const { apiKirimWaRequest } = require('./functions');

(async function() {
  const deviceId = process.env.DEVICE_ID;
  const apiBaseUrl = process.env.API_BASEURL || 'https://api.kirimwa.id/v1';
  const url = new URL(apiBaseUrl + '/messages');
  const message = {
    message: process.env.MESSAGE,
    phone_number: process.env.PHONE_NUMBER,
    message_type: process.env.MESSAGE_TYPE || 'text',
    device_id: process.env.DEVICE_ID
  }

  const reqParams = {
    token: process.env.API_TOKEN,
    url: url,
    method: 'POST',
    payload: JSON.stringify(message)
  };

  try {
    const { body, response } = await apiKirimWaRequest(reqParams);
    console.log(body);
  } catch (error) {
    console.error('Something went wrong', {
      body: error.body,
      statusCode: error.response.statusCode
    });
  }
})();

Kemudian jalankan perintah berikut untuk mengirim pesan teks ke nomor WhatsApp tertentu.

$ API_TOKEN=YOUR_API_TOKEN \
DEVICE_ID="iphone-x-pro" \
PHONE_NUMBER=6281234567890 \
MESSAGE="Halo ini adalah pesan dari api.kirimwa.id" \
MESSAGE_TYPE=text \
node send-message.js

Pengiriman pada API KirimWA.id bersifat asynchronous dan akan diproses beberapa saat kemudian. Oleh karena itu respon yang didapat ketika mengirim pesan adalah id dari message yang dikirimkan.

Berikut contoh respon dari request sebelumnya.

{
  "id": "kwid-426564a5db7940288dc9fddb845",
  "status": "pending",
  "message": "Message is pending and waiting to be processed.",
  "meta": {
    "location": "https://api.kirimwa.id/v1/messages/kwid-426564a5db7940288dc9fddb845"
  }
}

Dalam terlihat statusnya adalah pending karena ketika respon dikembalikan pemrosesan belum dilakukan. Untuk mengecek status pemrosesan pesan dapat digunakan id dari pesan tersebut.

3.1. Mengirim Pesan Gambar

Tidak ada perbedaan endpoint yang digunakan untuk pengiriman gambar. Yang perlu diubah saat pengiriman adalah atribut message_type dan message.

Nilai atribut message_type untuk gambar harus bernilai image. Sedangkan untuk nilai dari message adalah URL dari gambar.

Kita dapat menggunakan script yang sama yaitu send-message.js untuk mengirim pesan gambar. Karena script tersebut menerima parameter pesan dan tipe dari environment variabel.

$ API_TOKEN=YOUR_API_TOKEN \
DEVICE_ID="iphone-x-pro" \
PHONE_NUMBER=6281234567890 \
MESSAGE="https://rioastamal.net/portfolio/img/rioastamal.jpg" \
MESSAGE_TYPE=image \
node send-message.js

4. Cek Status Pengiriman Pesan

Endpoint yang digunakan untuk mengecek status dari pesan adalah GET /v1/messages/MESSAGE_ID dimana MESSAGE_ID adalah id dari pesan hasil dari pemanggilan endpoint POST /v1/messages.

Respon akan berisi status dari pemrosesan pada atribut status yang dapat berisi pending, success atau fail. Jika masih pending berarti pesan tersebut masih belum diproses.

Buat sebuah file baru bernama view-message.js kemudian salin kode dibawah ini.

const { apiKirimWaRequest } = require('./functions');

(async function() {
  const messageId = process.env.MESSAGE_ID;
  const apiBaseUrl = process.env.API_BASEURL || 'https://api.kirimwa.id/v1';
  const url = new URL(apiBaseUrl + '/messages/' + messageId);

  const reqParams = {
    token: process.env.API_TOKEN,
    url: url
  };

  try {
    const { body, response } = await apiKirimWaRequest(reqParams);
    console.log(body);
  } catch (error) {
    console.error('Something went wrong', {
      body: error.body,
      statusCode: error.response.statusCode
    });
  }
})();

Jalankan script diatas dengan memberikan parameter id dari pesan pada environment variable MESSAGE_ID.

$ API_TOKEN=YOUR_API_TOKEN \
MESSAGE_ID= kwid-426564a5db7940288dc9fddb812 \
node view-message.js

Respon yang dikembalikan adalah status pengiriman dan payload yang dikirim ketika pesan dikirim.

{
  "id": "kwid-426564a5db7940288dc9fddb812",
  "message": "Message has been sent.",
  "status": "success",
  "created_at": "2021-07-10T00:16:10.373Z",
  "payload": {
    "message": "Halo ini adalah pesan dari api.kirimwa.id",
    "phone_number": "6281234567890",
    "device_id": "iphone-x-pro",
    "message_type": "text",
    "caption": null
  }
}

5. Menambahkan Webhook

Dengan menambahkan webhook maka aplikasi anda akan mendapatkan informasi tentang perubahan status dari pengiriman pesan tanpa harus menghubungi server API KirimWA.id.

Ketika sebuah status pemrosesan pesan berubah dari pending ke success atau fail maka API KirimWA.id akan mengirimkan notifikasi ke aplikasi anda lewat URL webhook yang ditambahkan.

Berikut ini adalah contoh data yang dikirimkan pada sebuah webhook lewat HTTP POST.

{
  id: 'kwid-426564a5db7940288dc9fddb812',
  webhook_type: 'send_message_response',
  status: 'success',
  message: 'Message has been sent.',
  payload: {
    message: 'Halo ini adalah pesan dari api.kirimwa.id',
    phone_number: '6281234567890',
    device_id: 'asus-zenfone-1',
    message_type: 'text',
    caption: null
  },
  created_at: '2021-07-10T00:16:10.373Z',
  server_time: '2021-07-19T13:35:00.078Z'
}

5.1. Membuat Script Penerima Webhook

Berikut ini adalah contoh script sederhana yang akan menerima webhook yang dikirimkan oleh API KirimWA.id. Apa yang dilakukan script ini hanyalah melakukan dump data yang dikirimkan.

Pada contoh kali ini saya juga akan menggunakan Node.js untuk menerima Webhook dari API KirimWA.id. Buat sebuah direktori dengan nama api-kirimwa-webhook.

$ mkdir api-kirimwa-webhook
$ cd api-kirimwa-webhook

Install Express framework.

$ npm install express

Buat sebuah file dengan nama main.js dan berikut isinya.

const express = require('express');
const app = express();

app.use(express.json());
app.post('/webhook', function(req, res) {
    console.log({ '$body' : req.body });
    console.log({ '$headers' : req.headers });
    res.status(process.env.APP_STATUS_CODE).send({
        message: 'OK.'
    });
});

app.listen(3001, function() {
  console.log(`Example app listening at http://localhost:3001`);
});

Jalankan webhook tersebut yang akan running pada port 3001. Kita akan mengembalikan HTTP 200 OK kepada API KirimWA.id.

$ APP_STATUS_CODE=200 node main.js
Example app listening at http://localhost:3001

5.2. Expose Webhook ke Internet

Saat melakukan testing webhook ke server biasanya kita akan develop dulu di localhost sebelum diupload ke server. Agar API KirimWA.id dapat menghubungi alamat Webhook URL yang dibuat maka ia harus bisa diakses lewat internet. Cara paling mudah untuk membuat localhost diakses dari internet adalah menggunakan layanan seperti ngrok atau Cloudflare Tunnel.

Baca Juga
Mengakses localhost dari Internet dengan SSH Tunneling

Pada contoh ini saya menggunakan Cloudflare Tunnel untuk melakukan expose localhost webhook ke Internet. Saya akan melakukan mapping domain webhooks.teknocerdas.com ke localhost port 3001.

$ cloudflared tunnel --hostname webhooks.teknocerdas.com --url http://localhost:3001

Harusnya sekarang localhost port 3001 bisa diakses dari internet dengan domain https://webhooks.teknocerdas.com.

5.3. Menambahkan Webhook

Langkah berikutnya adalah menambahkan webhook pada API KirimWA.id agar jika proses pengiriman selesai maka webhook yang kita buat akan dipanggil.

Endpoint yang digunakan untuk menambahkan webhook adalah POST /v1/webhooks. Buat file baru bernama add-webhook.js pada direktori nodejs-api-kirimwa.

const { apiKirimWaRequest } = require('./functions');

(async function() {
  const apiBaseUrl = process.env.API_BASEURL || 'https://api.kirimwa.id/v1';
  const url = new URL(apiBaseUrl + '/webhooks');
  const reqParams = {
    token: process.env.API_TOKEN,
    url: url,
    method: 'POST',
    payload: JSON.stringify({
        webhook_url: process.env.WEBHOOK_URL
    })
  };

  try {
    const { body, response } = await apiKirimWaRequest(reqParams);
    console.log(body);
  } catch (error) {
    console.error('Something went wrong', {
      body: error.body,
      statusCode: error.response.statusCode
    });
  }
})();

Untuk menambahkan webhook eksekusi script tersebut dengan environment variable WEBHOOK_URL.

$ API_TOKEN=YOUR_API_TOKEN \
WEBHOOK_URL=https://webhooks.teknocerdas.com/webhook \
node add-webhook.js

Respon yang dikembalikan jika sukses seperti di bawah.

{
  "id": "whu-YOUR@EMAIL",
  "status": "active",
  "data": "https://webhooks.teknocerdas.com/webhook",
  "created_at": "2021-06-20T17:17:06.333Z",
  "meta": {
    "location": "https://api.kirimwa.id/v1/webhooks"
  }
}

5.4. Tes Webhook

Untuk melakukan tes webhook maka perlu dilakukan pengiriman pesan baru. Jika berhasil harusnya server pada webhooks.teknocerdas.com akan menerima kiriman data lewat HTTP POST yang isinya adalah pesan yang dikirimkan dan status pengirimannya.

$ API_TOKEN=YOUR_API_TOKEN \
DEVICE_ID="iphone-x-pro" \
PHONE_NUMBER=6281234567890 \
MESSAGE="Halo ini adalah pesan dari api.kirimwa.id" \
MESSAGE_TYPE=text \
node send-message.js
{
  "id": "kwid-b930ab810bb44b31909083fcfad",
  "status": "pending",
  "message": "Message is pending and waiting to be processed.",
  "meta": {
    "location": "https://api.kirimwa.id/v1/messages/kwid-b930ab810bb44b31909083fcfad"
  }
}

Cek output pada aplikasi Node.js yang berjalan harusnya muncul log pada terminal yang berisi data yang dikirimkan oleh API KirimWA.id.

{
  '$body': {
    id: 'kwid-b930ab810bb44b31909083fcfad',
    status: 'success',
    message: 'Message has been sent.',
    webhook_type: 'send_message_response',
    payload: {
      message: 'Tes webhook pada API KirimWA.id',
      phone_number: '6281234567890',
      device_id: 'iphone-x-pro',
      message_type: 'text',
      caption: null
    },
    created_at: '2021-07-29T00:37:28.727Z',
    server_time: '2021-07-29T00:37:28.765Z'
  }
}
{
  '$headers': {
    'user-agent': 'API KirimWA/1.0',
    'content-type': 'application/json',
    'content-length': '387',
    host: 'localhost:3001',
    connection: 'close'
  }
}

Terlihat bahwa data berhasil ditangkap oleh aplikasi Node.js yang dibuat. Pada aplikasi yang anda buat mungkin perlu menyimpan log setiap pesan yang dikirim dan statusnya.