Download the PHP package mdestafadilah/sikuwa without Composer

On this page you can find all versions of the php package mdestafadilah/sikuwa. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package sikuwa

WhatsApp Unofficial SDK (SIKUWA)

SDK PHP untuk beberapa gateway WhatsApp unofficial. Tujuannya satu antarmuka yang sama untuk banyak gateway, sehingga penggantian provider atau otomatis pilih provider tidak mengubah kode pemanggil.

Rilis stabil Total unduhan PHP

Namespace Sikuwa\Whatsapp\, PSR-4, dibangun di atas Guzzle 7, membutuhkan PHP 8.1+.

Gateway yang didukung

Gateway Jenis Basis Tautan
Fonnte Berbayar (cloud) — https://fonnte.com/
OpenWA Self-hosted Node.js https://github.com/rmyndharis/OpenWA
ApiMe Self-hosted Go / WhatsMeow https://github.com/open-apime/apime
Evolution API Self-hosted Node.js / Baileys https://github.com/evolution-foundation/evolution-api
Wuzapi Self-hosted Go / WhatsMeow https://github.com/asternic/wuzapi
Wwebjs Self-hosted Node.js / whatsapp-web.js https://github.com/avoylenko/wwebjs-api
Waxum Self-hosted Rust / whatsapp-rust https://github.com/imtaqin/waxum

Instalasi

Butuh PHP 8.1+ dan ext-mbstring; Guzzle 7 ikut terpasang sebagai dependensi.

Untuk mengikuti main alih-alih rilis stabil:

Kalau butuh fork sendiri atau commit tertentu, daftarkan repositori GitHub-nya:

Pemakaian

Opsi yang dikosongkan akan dicari di environment (WHATSAPP_*), jadi di aplikasi CodeIgniter cukup new Client() tanpa argumen apa pun:

Bentuk pesan

Satu bentuk yang sama untuk semua gateway:

Untuk pengiriman massal, kirim list dari array seperti itu:

Nomor boleh ditulis dalam format apa pun yang lazim di Indonesia (0812…, +62 812…, 62812…) — SDK menormalkannya sendiri. JID grup (…@g.us) dan WID (…@c.us) diteruskan apa adanya.

delay dihitung dalam detik dan opsional: jeda sebelum pesan dikirim (Fonnte, Evolution API) atau jeda antar pesan pada pengiriman berurutan. Bila tidak diisi, nilainya diambil dari pacing; kalau pacing pun mati, tiap gateway memakai bawaannya sendiri — Fonnte 2 detik, OpenWA 3 detik, sisanya tanpa jeda.

Kirim gambar & berkas

Dua method terpisah, satu bentuk pesan yang sama untuk semua gateway:

Kunci Wajib Keterangan
destination ya Sama seperti sendMessage()
image / file ya Isi berkasnya. media diterima sebagai alias untuk keduanya
filename tidak Nama yang dilihat penerima. Kosong = disusun dari jenis berkasnya (lampiran.png)
caption tidak Teks yang menyertai berkas

Isi image/file boleh salah satu dari tiga bentuk; SDK yang menyesuaikannya ke bentuk yang diminta tiap gateway:

Yang menentukan sebuah berkas dikirim sebagai gambar atau dokumen adalah jenis berkasnya, bukan method yang dipanggil: sendFile() dengan PNG tetap terkirim sebagai gambar, dan sendImage() dengan PDF tetap terkirim sebagai dokumen.

Tiap gateway menempuh jalur yang berbeda, dan itu memang sifat gateway-nya:

Gateway Gambar Berkas Bentuk isi
Fonnte POST /send POST /send multipart, byte mentah — atau kolom url bila sumbernya URL
OpenWA POST /api/sessions/{id}/messages/send-image …/send-document JSON, base64 telanjang + mimetype terpisah
ApiMe POST /api/instances/{id}/messages/media …/messages/document multipart, byte mentah
Evolution API POST /message/sendMedia/{instance} sama, mediatype=document JSON, base64 telanjang atau URL
Wuzapi POST /chat/send/image POST /chat/send/document JSON, data URI (wajib)
Wwebjs POST /client/sendMessage/{id} sama, contentType=MessageMedia JSON, base64 telanjang — atau MessageMediaFromURL bila sumbernya URL
Waxum POST /api/v1/sessions/{id}/messages/image …/messages/document JSON, {data, mimetype} — atau {url} bila sumbernya URL

Enam hal yang mudah menjebak, dan sudah ditangani SDK:

Indikator "sedang mengetik"

Balasan yang muncul seketika mudah dikenali sebagai robot. sendTyping() membuat WhatsApp menampilkan "sedang mengetik…" lebih dulu:

Kunci Wajib Keterangan
destination ya Sama seperti sendMessage()
state tidak composing (bawaan), paused, atau recording
duration ya, kecuali paused Lama indikator ditampilkan, dalam detik

state boleh memakai istilah gateway mana pun; SDK memetakannya ke kosakata di atas — typing menjadi composing, stop menjadi paused, audio menjadi recording. Jadi kode yang sama jalan di semua gateway.

duration wajib saat menampilkan indikator, dan itu bukan sekadar formalitas: Fonnte menuntutnya di sisi server, sedangkan Evolution API menahan indikator selama durasi itu lalu menghapusnya sendiri. Dengan durasi 0 keduanya tidak menampilkan apa pun — dan itu gagal tanpa pesan apa-apa, jadi SDK menolaknya lebih dulu dengan ConfigurationException.

Gateway Endpoint Keadaan duration
Fonnte POST /typing ketik atau berhenti (stop) dipakai; wajib
OpenWA POST /api/sessions/{id}/chats/typing typing | recording | paused diabaikan
ApiMe POST /api/instances/{id}/whatsapp/presence composing | recording | paused diabaikan
Evolution API POST /chat/sendPresence/{instance} composing | recording | paused dipakai, satuan milidetik
Wuzapi POST /chat/presence composing + Media: audio | paused diabaikan
Wwebjs POST /chat/sendStateTyping · …/sendStateRecording · …/clearState endpoint berbeda per keadaan diabaikan; indikatornya bertahan ~25 detik di server
Waxum POST /api/v1/sessions/{id}/chatstate/send composing | recording | paused diabaikan

Lima hal yang mudah menjebak, dan sudah ditangani SDK:

Jeda antar pesan (pacing)

Mengirim beruntun dengan jeda yang seragam mudah dikenali sebagai robot. Pacing menyusun jeda dari tiga bagian, dan ketiganya bisa dipakai sendiri-sendiri maupun bersamaan:

Kunci Arti
WHATSAPP_PACING_CYCLE Daftar jeda tetap yang dipakai bergiliran, detik. 0,30 berarti pesan ke-1 tanpa jeda, ke-2 jeda 30 detik, ke-3 tanpa jeda, dan seterusnya
WHATSAPP_PACING_INTERVAL Jitter acak yang ditambahkan ke tiap jeda siklus, detik. 20-30 berarti setiap jeda ditambah 20–30 detik acak
WHATSAPP_PACING_LONG_CHARS Ambang pesan panjang, dalam karakter. Bawaannya 300
WHATSAPP_PACING_LONG_FACTOR Berapa kali jeda dilipatkan untuk pesan sepanjang itu. Bawaannya 3

Jadi jeda sebelum pesan ke-i adalah (siklus[i % jumlah siklus] + jitter) × pengali pesan panjang. Dengan 0,30 + 20-30 + ambang bawaan 300 karakter, jedanya berurutan 20–30, 50–60, 20–30, … detik untuk pesan pendek, dan 60–90, 150–180, 60–90, … detik untuk pesan 300 karakter ke atas.

Pesan panjang sengaja ditunggu lebih lama: mengirim teks panjang beruntun lebih mencurigakan daripada mengirim pesan pendek, dan pesan panjang juga lebih lama "dibaca". Panjangnya dihitung dalam karakter, bukan byte — 250 huruf beraksen tetap dianggap pesan pendek. Aturannya bisa dimatikan dengan WHATSAPP_PACING_LONG_CHARS=0, atau dinetralkan dengan WHATSAPP_PACING_LONG_FACTOR=1.

Bawaannya mati: selama kedua kunci pertama kosong, tiap gateway memakai jeda bawaannya sendiri seperti sebelumnya. Ini disengaja — mengirim banyak pesan menahan proses pemanggil selama total jeda itu, jadi pacing harus dinyalakan dengan sadar.

Untuk satu panggilan saja, sertakan kuncinya bersama pesan. Yang disebutkan saja yang ditimpa; sisanya tetap diambil dari .env:

delay pada satu pesan tetap menang atas pacing untuk pesan itu — termasuk 'delay' => 0, yang berarti "pesan ini tanpa jeda". Pesan pertama tidak pernah ditunggu: jeda sebelum pengiriman pertama adalah urusan pemanggil, bukan SDK.

Siapa yang benar-benar mengerjakan jedanya berbeda per gateway, dan itu memang sifat gateway-nya:

Gateway Jeda dikerjakan oleh
Fonnte Server, lewat kolom delay tiap pesan
OpenWA Server, lewat delayBetweenMessages — satu angka untuk seluruh batch, diambil dari jeda sebelum pesan kedua
Evolution API Server, lewat kolom delay payload (dalam milidetik)
ApiMe, Wuzapi, Wwebjs SDK, dengan sleep() di antara request

Karena jedanya dititipkan ke server, Fonnte, OpenWA, dan Evolution API tidak menahan klien dua kali. OpenWA juga menambahkan pengacakan di sisinya sendiri (randomizeDelay).

Indikator mengetik otomatis

sendTyping() di atas eksplisit — pemanggil yang memanggilnya. Kalau ingin indikatornya muncul sendiri di setiap send(), nyalakan WHATSAPP_TYPING dan SDK yang mengurusnya: ia menampilkan "sedang mengetik…" untuk tujuan itu, lalu menunggu selama indikatornya tampil sebelum pesannya dikirim.

Lamanya mengikuti panjang pesan, sama seperti pacing. Pesan 300 karakter yang "diketik" dalam satu detik sama tidak wajarnya dengan "Halo" yang diketipkan sepuluh detik:

Kunci Arti
WHATSAPP_TYPING Saklar on/off. Bawaannya mati
WHATSAPP_TYPING_SPEED Kecepatan ketik, dalam karakter per detik. Bawaannya 15
WHATSAPP_TYPING_MIN Lama tampil paling singkat, detik. Bawaannya 2
WHATSAPP_TYPING_MAX Lama tampil paling lama, detik. Bawaannya 20

Dengan bawaannya, 10 karakter menjadi 2 detik, 60 karakter 4 detik, 150 karakter 10 detik, dan 300 karakter ke atas berhenti di 20 detik.

Bawaannya mati karena fitur ini menyisipkan satu request tambahan ke jalur kirim dan menahan pemanggil selama durasinya. Hanya saklarnya yang menyalakan — mengisi WHATSAPP_TYPING_SPEED saja di .env tidak mengubah apa pun.

Untuk satu panggilan saja, sertakan kunci typing. Berbeda dari .env yang jadi saklar global, menulis kunci ini di dalam array pesan sudah berarti permintaan — jadi ia menyalakan fiturnya tanpa perlu WHATSAPP_TYPING:

Kuncinya boleh juga ditaruh di tiap pesan dalam pengiriman massal, jadi satu pesan bisa dibiarkan tanpa indikator sementara yang lain memakainya:

Siapa yang benar-benar menunggu berbeda per gateway, dan itu memang sifat gateway-nya:

Gateway Yang terjadi
Evolution API Servernya sudah menunggu dan menghapus indikatornya sendiri, jadi SDK tidak menunggu lagi — kalau tidak, pemanggil menunggu dua kali
ApiMe, Wuzapi, OpenWA, Fonnte, Wwebjs, Waxum Indikator hanya menyimpan status, jadi SDK yang menghabiskan durasinya

Tiga hal yang mudah menjebak, dan sudah ditangani SDK:

Dua gaya pemanggilan

send() melempar exception kalau gagal; notify() mengembalikan string dan tidak pernah melempar.

Memilih gateway

WHATSAPP_PROVIDER menerima nama gateway (tidak peka huruf besar/kecil) atau Auto. Mode Auto mengundi hanya di antara gateway yang WHATSAPP_TOKEN_<Provider>-nya terisi, sehingga undian tidak pernah jatuh ke gateway yang belum dikonfigurasi.

provider() mengembalikan instance baru setiap dipanggil. Untuk Auto itu berarti undiannya diulang — panggil sekali lalu simpan hasilnya kalau beberapa pesan harus lewat gateway yang sama.

Sesi

Selain mengirim pesan, SDK bisa membuat dan memeriksa sesi WhatsApp lewat antarmuka yang sama di semua gateway:

Gateway menyebutnya berbeda-beda — OpenWA dan Wwebjs "session", ApiMe dan Evolution API "instance", wuzapi dan Fonnte "device" — tetapi semuanya mengembalikan Sikuwa\Whatsapp\Session yang sama:

Properti Isi
$provider Nama gateway, mis. OpenWA
$id Id sesi menurut gateway
$status Status apa adanya dari gateway, mis. CONNECTED atau open
$connected Apakah sesi siap mengirim pesan
$qr QR sebagai data URI, bila ada
$token Kredensial yang baru diterbitkan gateway, bila ada
$phoneNumber / $profileName Identitas yang tersambung, bila ada
$raw Amplop asli gateway, apa adanya

isConnected(), hasQr(), toArray(), dan toJson() tersedia sebagai penolong; (string) $session menghasilkan ringkasan siap log, mis. OpenWA: CONNECTED (sess-1). Nilai yang tidak disediakan gateway dibiarkan kosong, tidak ditebak.

$token berisi kredensial yang diterbitkan saat sesi dibuat — token perangkat Fonnte, atau hash.apikey Evolution API. Itulah yang diisi ke WHATSAPP_TOKEN supaya pesan bisa dikirim lewat sesi tersebut. Baik $token maupun $raw sengaja tidak ikut di toArray()/toJson(), karena keluaran itu biasanya berakhir di log atau response HTTP.

Nama sesi diambil dari $options bila diberikan, selain itu dari konfigurasi — WHATSAPP_SESSION_<Provider> / WHATSAPP_INSTANCE_<Provider> lebih dulu, baru WHATSAPP_SESSION / WHATSAPP_INSTANCE — jadi createSession() tanpa argumen tetap masuk akal di aplikasi yang kredensialnya sudah ada di .env. Fonnte adalah pengecualian: createSession() di sana memang menuntut name dan device, karena perangkat baru butuh nomor yang belum pernah dipakai.

QR sesi

Sesi yang belum tersambung bisa dimintai QR-nya lewat showQr(). Hasilnya Session yang sama, dengan $qr terisi:

$qr selalu data URI penuh atau string kosong, walaupun gateway tidak sepakat soal bentuknya: Fonnte mengirim base64 PNG telanjang di url, OpenWA dan wuzapi mengirim data URI yang sudah lengkap, Evolution API mengirim base64 di base64. Perangkaiannya dikerjakan Support\Qr::dataUri(), jadi pemanggil tidak perlu tahu bedanya.

Sesi yang sudah tersambung tidak punya QR. Gateway yang mengatakannya terus terang dilaporkan sebagai isConnected() === true dengan hasQr() === false, bukan sebagai exception:

Gateway Jawaban saat sudah tersambung
Evolution API {"instance":{"state":"open"}}
Fonnte {"status":false,"reason":"device already connect"}
Wuzapi error already logged in
OpenWA HTTP 400 — sebabnya bercampur dengan sesi yang belum qr_ready, jadi tetap dilempar
Wwebjs JSON qr code not ready or already scanned — dibedakan dengan membaca status sesi
Waxum {"qr_codes":[],"status":"logged_in"} — dibedakan dari isi qr_codes dan status sesinya

Karena itu showQr() aman dipanggil tanpa memeriksa checkSession() lebih dulu:

Catatan per gateway:

Gateway Membuat sesi Memeriksa sesi QR sesi
OpenWA POST /api/sessions — id, name, config GET /api/sessions/{id} GET /api/sessions/{id}/qr
ApiMe POST /api/instances — name, webhook_url, webhook_secret GET /api/instances/{id} GET /api/instances/{id}/qr
Evolution API POST /instance/create — instanceName, qrcode, webhook GET /instance/connectionState/{instance} GET /instance/connect/{instance}
Wuzapi POST /session/connect — subscribe, immediate GET /session/status GET /session/qr
Fonnte POST /add-device — name, device, autoread POST /get-devices POST /qr
Wwebjs POST /session/start/{id} — id, webhookUrl GET /session/status/{id} GET /session/qr/{id}/image
Waxum POST /api/v1/sessions — id, name, webhook, device GET /api/v1/sessions/{id}/status GET /api/v1/sessions/{id}/qr

Catatan:

Konfigurasi

Lihat .env.example. Ringkasnya:

Kunci Keterangan
WA_NOTIFICATION Penanda notifikasi aktif. SDK tidak menegakkannya; tersedia lewat $client->enabled()
WHATSAPP_PROVIDER Auto atau nama gateway
WHATSAPP_TOKEN_<Provider> Token per gateway. Inilah yang dihitung mode Auto
WHATSAPP_TOKEN Token umum, dipakai bila token khusus gateway tidak ada. Tidak dihitung mode Auto
WHATSAPP_URL_<Provider> Base URL per gateway. Ini yang sebaiknya dipakai untuk self-hosted
WHATSAPP_URL Base URL cadangan bila kunci per-provider kosong. Diabaikan Fonnte
WHATSAPP_SESSION_<Provider> Id session per gateway. Ini yang sebaiknya dipakai bila beberapa gateway butuh session berbeda
WHATSAPP_SESSION Id session cadangan bila kunci per-provider kosong
WHATSAPP_INSTANCE_<Provider> Id/nama instance per gateway
WHATSAPP_INSTANCE Id/nama instance cadangan bila kunci per-provider kosong
WHATSAPP_ACCOUNT_TOKEN Khusus Fonnte Device API (add-device, get-devices). Bukan token perangkat
WHATSAPP_TIMEOUT Batas waktu request, detik (1–60, default 10)
WHATSAPP_PACING_CYCLE Jeda tetap yang dipakai bergiliran antar pesan, detik. Mis. 0,30. Kosong = pacing mati
WHATSAPP_PACING_INTERVAL Jitter acak yang ditambahkan ke tiap jeda siklus, detik. Mis. 20-30
WHATSAPP_PACING_LONG_CHARS Ambang pesan panjang, karakter (default 300). 0 = aturannya dimatikan
WHATSAPP_PACING_LONG_FACTOR Pengali jeda untuk pesan panjang (default 3). 1 = tidak ada pengalian
WHATSAPP_TYPING Munculkan indikator "sedang mengetik" sendiri sebelum mengirim. Kosong = mati
WHATSAPP_TYPING_SPEED Kecepatan ketik, karakter per detik (default 15)
WHATSAPP_TYPING_MIN Lama indikator tampil paling singkat, detik (default 2)
WHATSAPP_TYPING_MAX Lama indikator tampil paling lama, detik (default 20)

URL per gateway

Satu WHATSAPP_URL bersama tidak cukup kalau Anda memakai lebih dari satu gateway self-hosted: nilainya berlaku untuk provider apa pun yang sedang aktif, jadi URL OpenWA akan ikut terpakai Wuzapi. Pakai kunci per-provider:

Setara lewat opsi konstruktor: ['urls' => ['OpenWA' => 'https://wa-1.internal']].

Urutan pembacaannya: kunci per-provider → url yang diberikan eksplisit → WHATSAPP_URL → default provider. Kunci per-provider sengaja tidak jatuh ke WHATSAPP_URL, sama seperti WHATSAPP_TOKEN_<Provider> yang tidak jatuh ke WHATSAPP_TOKEN.

Nilai default bila semuanya dikosongkan: OpenWA https://openwa.whatsapp.com, ApiMe https://api-me.whatsapp.com, Evolution API https://evolution-api.whatsapp.com, Wuzapi https://wuzapi.whatsapp.com, Wwebjs https://wwebjs.whatsapp.com, Waxum https://waxum.whatsapp.com. Fonnte punya endpoint tetap sendiri.

Session per gateway

Alasan yang sama berlaku untuk session: satu WHATSAPP_SESSION bersama akan dipakai OpenWA, Wwebjs, dan Waxum sekaligus, sehingga tiga gateway tidak bisa memakai nama session yang berbeda — padahal ketiganya sering berjalan berdampingan dan tidak boleh berbagi session. Pakai kunci per-provider:

Urutan pembacaannya sama seperti token dan URL: kunci per-provider → nilai session/instance yang diberikan eksplisit → WHATSAPP_SESSION / WHATSAPP_INSTANCE. Kunci per-provider sengaja tidak jatuh ke kunci bersama. Tiap gateway membaca kuncinya sendiri, jadi WHATSAPP_SESSION_OpenWA tidak akan pernah terpakai oleh Wwebjs atau Waxum.

Nama provider ditulis apa adanya mengikuti kunci per-provider yang sudah ada (WHATSAPP_SESSION_OpenWA), bukan diubah menjadi huruf besar.

Catatan per gateway

Error

Semua error melempar subclass dari Sikuwa\Whatsapp\Exceptions\WhatsappException:

Kelas Kapan
ConfigurationException Token/URL/session/instance belum diisi, atau bentuk pesan salah. Tidak akan sembuh kalau diulang
UnknownProviderException Nama gateway tidak dikenali
ApiException Gateway menjawab tapi menolak. Membawa getStatus(), getBody(), getErrorKind()
AuthException 401 — token ditolak
ForbiddenException 403 — token kurang hak (mis. bukan instance token di ApiMe)
NotFoundException 404 — instance/session tidak ditemukan, atau perangkat Fonnte yang dicari tidak ada di akun
ConflictException 409 — masih ada pengiriman dengan Idempotency-Key yang sama
RateLimitException 429 — satu-satunya status yang aman diretry
ServiceUnavailableException 503 — sesi WhatsApp belum siap, tidak ada pesan terkirim
TimeoutException Request melewati WHATSAPP_TIMEOUT

Pengiriman massal ke gateway tanpa endpoint batch (ApiMe, Evolution API, wuzapi, Wwebjs) mengirim satu per satu. Kegagalan satu nomor tidak menghentikan sisanya; semuanya dikumpulkan lalu dilempar sebagai satu ApiException, jadi pemanggil melihat gambaran lengkapnya:

Pengujian

Tidak ada jaringan yang tersentuh: test menyuntikkan klien Guzzle ber-handler MockHandler lewat opsi httpClient, sehingga tidak perlu monkey-patching global.

Butuh satu gateway saja?

Kalau hanya memakai satu gateway, SDK ini berlebihan. Gunakan langsung SDK PHP OpenWA yang sudah teruji.

Feature

Kredit

Terinspirasi dari SDK PHP OpenWA.


All versions of sikuwa with dependencies

PHP Build Version
Package Version
Requires php Version >=8.1
ext-mbstring Version *
guzzlehttp/guzzle Version ^7.9
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package mdestafadilah/sikuwa contains the following files

Loading the files please wait ...