Kirim WhatsApp dengan API KirimWA.id dan PHP

7 min read

Kirim WhatsApp dengan API KirimWA.id dan PHP
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 PHP.

Versi PHP yang digunakan pada tulisan adalah PHP 7.4 dan tidak menggunakan antarmuka tampilan HTML. Tetapi akan menggunakan command line interface (CLI). Pada tulisan ini kita tidak akan menggunakan pustaka pihak ketiga seperti Guzzle tetapi fungsi built-in dari PHP untuk melakukan HTTP request yaitu file_get_contents().

Baca Juga
Kirim WhatsApp dengan API KirimWA.id dan cURL
Kirim WhatsApp dengan API KirimWA.id dan Node.js

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:

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 php-api-kirimwa.

$ mkdir php-api-kirimwa
$ cd php-api-kirimwa

Buat sebuah file baru bernama functions.php pada direktori yang dibuat diatas. Salin isi dari functions.php yang ada di bawah ini.

<?php

/**
 * Make a request to API KirimWA.id
 *
 * @param Array $params
 * @return Array
 * @throws Exception
 */
function apiKirimWaRequest(array $params) {
  $httpStreamOptions = [
    'method' => $params['method'] ?? 'GET',
    'header' => [
      'Content-Type: application/json',
      'Authorization: Bearer ' . ($params['token'] ?? '')
    ],
    'timeout' => 15,
    'ignore_errors' => true
  ];

  if ($httpStreamOptions['method'] === 'POST') {
    $httpStreamOptions['header'][] = sprintf('Content-Length: %d', strlen($params['payload'] ?? ''));
    $httpStreamOptions['content'] = $params['payload'];
  }

  // Join the headers using CRLF
  $httpStreamOptions['header'] = implode("\r\n", $httpStreamOptions['header']) . "\r\n";

  $stream = stream_context_create(['http' => $httpStreamOptions]);
  $response = file_get_contents($params['url'], false, $stream);

  // Headers response are created magically and injected into
  // variable named $http_response_header
  $httpStatus = $http_response_header[0];

  preg_match('#HTTP/[\d\.]+\s(\d{3})#i', $httpStatus, $matches);

  if (! isset($matches[1])) {
    throw new Exception('Can not fetch HTTP response header.');
  }

  $statusCode = (int)$matches[1];
  if ($statusCode >= 200 && $statusCode < 300) {
    return ['body' => $response, 'statusCode' => $statusCode, 'headers' => $http_response_header];
  }

  throw new Exception($response, $statusCode);
}

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.php untuk menambahkan sebuah device. Berikut ini adalah kode PHP yang digunakan.

<?php
require './functions.php';

try {
  $baseApiUrl = getenv('API_BASEURL') ? getenv('API_BASEURL') : 'https://api.kirimwa.id/v1';
  $reqParams = [
    'token' => getenv('API_TOKEN'),
    'url' => $baseApiUrl . '/devices',
    'method' => 'POST',
    'payload' => json_encode([
      'device_id' => getenv('DEVICE_ID')
    ])
  ];

  $response = apiKirimWaRequest($reqParams);
  echo $response['body'];
} catch (Exception $e) {
  print_r($e);
}

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 \
php add-device.php

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.php. Isi dari file tersebut adalah seperti dibawah ini.

<?php
require './functions.php';

try {
  $query = http_build_query(['device_id' => getenv('DEVICE_ID')]);
  $baseApiUrl = getenv('API_BASEURL') ? getenv('API_BASEURL') : 'https://api.kirimwa.id/v1';
  $reqParams = [
    'token' => getenv('API_TOKEN'),
    'url' => sprintf('%s/qr?%s', $baseApiUrl, $query)
  ];

  $response = apiKirimWaRequest($reqParams);
  echo $response['body'];
} catch (Exception $e) {
  print_r($e);
}

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

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

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.php dan salin kode dibawah ini.

<?php
require './functions.php';

try {
  $baseApiUrl = getenv('API_BASEURL') ? getenv('API_BASEURL') : 'https://api.kirimwa.id/v1';
  $reqParams = [
    'token' => getenv('API_TOKEN'),
    'url' => $baseApiUrl . '/messages',
    'method' => 'POST',
    'payload' => json_encode([
      'message' => getenv('MESSAGE'),
      'phone_number' => getenv('PHONE_NUMBER'),
      'message_type' => getenv('MESSAGE_TYPE') ? getenv('MESSAGE_TYPE') : 'text',
      'device_id' => getenv('DEVICE_ID')
    ])
  ];

  $response = apiKirimWaRequest($reqParams);
  echo $response['body'];
} catch (Exception $e) {
  print_r($e);
}

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 \
php send-message.php

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.

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.php 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 \
php send-message.php

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.php kemudian salin kode dibawah ini.

<?php
require './functions.php';

try {
  $baseApiUrl = getenv('API_BASEURL') ? getenv('API_BASEURL') : 'https://api.kirimwa.id/v1';
  $reqParams = [
    'token' => getenv('API_TOKEN'),
    'url' => sprintf('%s/messages/%s', $baseApiUrl, getenv('MESSAGE_ID'))
  ];

  $response = apiKirimWaRequest($reqParams);
  echo $response['body'];
} catch (Exception $e) {
  print_r($e);
}

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

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

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
  }
}

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'
}

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

Buat sebuah file dengan nama index.php dan berikut isinya.

<?php

// Dump all data that being sent via POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('HTTP/1.1 400 Bad Request');
    echo json_encode(['message' => 'nothing to do']);
    exit(0);
}

$body = file_get_contents('php://input');

// Log output to STDERR
$output = ['body' => json_decode($body)];
file_put_contents('php://stderr', print_r($output, $return = true));

header('HTTP/1.1 200 OK');

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

$ php 0.0.0.0:3001 -t api-kirimwa-webhook/

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.php pada direktori php-api-kirimwa.

<?php
require './functions.php';

try {
  $baseApiUrl = getenv('API_BASEURL') ? getenv('API_BASEURL') : 'https://api.kirimwa.id/v1';
  $reqParams = [
    'token' => getenv('API_TOKEN'),
    'url' => $baseApiUrl . '/webhooks',
    'method' => 'POST',
    'payload' => json_encode([
      'webhook_url' => getenv('WEBHOOK_URL')
    ])
  ];

  $response = apiKirimWaRequest($reqParams);
  echo $response['body'];
} catch (Exception $e) {
  print_r($e);
}

Untuk menambahkan webhook eksekusi script tersebut dengan environment variable WEBHOOK_URL.

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

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 \
php send-message.php
{
  "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 PHP yang berjalan harusnya muncul log pada terminal yang berisi data yang dikirimkan oleh API KirimWA.id.

Array
(
    [body] => stdClass Object
        (
            [id] => kwid-b930ab810bb44b31909083fcfad
            [status] => success
            [message] => Message has been sent.
            [webhook_type] => send_message_response
            [payload] => stdClass Object
                (
                    [message] => Tes webhook pada API KirimWA.id
                    [phone_number] => 6281234567890
                    [device_id] => iphone-x-pro
                    [message_type] => text
                    [caption] =>
                )

            [created_at] => 2021-07-29T00:37:28.727Z
            [server_time] => 2021-07-29T00:37:28.765Z
        )

)

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