Files
wehub-resource-sync 4ce4204b6c
CI / Lint (push) Failing after 2s
CI / Build (push) Has been skipped
SDK CI / PHP SDK (push) Failing after 1s
Split PHP SDK / PHP SDK tests (push) Failing after 1s
CI / Test (push) Failing after 1s
CI / Dashboard (push) Failing after 0s
SDK CI / JavaScript SDK (push) Failing after 0s
SDK CI / Python SDK (push) Failing after 2s
SDK CI / Java SDK (push) Failing after 1s
Split PHP SDK / Mirror sdk/php -> rmyndharis/openwa-php (push) Has been skipped
CI / Test (PostgreSQL migrations) (push) Failing after 7m47s
CI / Docker Build (push) Has been skipped
chore: import upstream snapshot with attribution
2026-07-13 12:24:08 +08:00
..

OpenWA SDKs

Official client libraries for the OpenWA WhatsApp API Gateway.

All four SDKs are hand-written against the exact API surface (paths, DTOs, response shapes) and unit-tested with mocked HTTP transports that assert on the precise request URL, method, and body — so drift is caught at test time. The wire types live in a dedicated module (types.ts / types.py / model/) so they can later be regenerated by an OpenAPI codegen pass without touching the hand-written resource methods.

Language Package Notes
JavaScript / TypeScript @rmyndharis/openwa dual ESM/CJS, bundled types
Python rmyndharis-openwa sync (httpx), PEP 561 typed
PHP rmyndharis/openwa sync (Guzzle, PHP 8.1+)
Java com.rmyndharis:openwa sync (java.net.http + Gson, Java 17)

Coverage

All three SDKs expose the same fluent resource surface:

Resource Methods
sessions list, get, create, delete, start, stop, forceKill, getQrCode, requestPairingCode, stats
messages list, sendText, sendImage/Video/Audio/Document/Sticker, sendLocation, sendContact, sendTemplate, reply, forward, react, delete, history, reactions, sendBulk, batchStatus, cancelBatch
contacts list, get, check, profilePicture, phone, block, unblock
groups list, get, create, add/remove/promote/demoteParticipants, setSubject, setDescription, leave, inviteCode, revokeInviteCode
webhooks list, get, create, update, delete, test
chats list, markRead, markUnread, delete, sendState
labels list, get, forChat, addToChat, removeFromChat (WhatsApp Business)
channels list, get, messages, subscribe, unsubscribe (Newsletters)
catalog info, products, product, sendProduct, sendCatalog (WhatsApp Business)
status list, fromContact, sendText, sendImage, sendVideo, delete (Stories)
templates list, get, create, update, delete
health check, live, ready

⚠️ Endpoints requiring an OPERATOR-level API key are noted in the inline docs. Operator-only modules (docker, metrics, infra, plugins, mcp) are intentionally not exposed in the SDK; all user-facing resources are.

JavaScript / TypeScript

npm install @rmyndharis/openwa
import { OpenWAClient } from '@rmyndharis/openwa';

const client = new OpenWAClient({
  baseUrl: 'http://localhost:2785',
  apiKey: 'owa_k1_…',
});

await client.sessions.start('my-session');
const result = await client.messages.sendText('my-session', {
  chatId: '628123456789@c.us',
  text: 'Hello from the OpenWA SDK!',
});
console.log(result.messageId);

Errors are typed — branch with instanceof:

import { OpenWANotFoundError, OpenWAConflictError } from '@rmyndharis/openwa';
try {
  await client.messages.sendText(/* … */);
} catch (e) {
  if (e instanceof OpenWAConflictError) {
    /* engine not ready (409) */
  }
}

Requires Node 18+ (uses the global fetch). Pass a custom fetch to the client constructor to intercept or observability-wrap requests.

Python

pip install rmyndharis-openwa
from openwa import OpenWAClient, OpenWANotFoundError

client = OpenWAClient(
    base_url="http://localhost:2785",
    api_key="owa_k1_…",
)

client.sessions.start("my-session")
result = client.messages.send_text("my-session", {
    "chatId": "628123456789@c.us",
    "text": "Hello from the OpenWA Python SDK!",
})
print(result["messageId"])

Pass transport=httpx.MockTransport(handler) for testing — no global monkey-patching required.

PHP

composer require rmyndharis/openwa
<?php
use OpenWA\Client;

$client = new Client([
    'baseUrl' => 'http://localhost:2785',
    'apiKey'  => 'owa_k1_…',
]);

$client->sessions->start('my-session');
$result = $client->messages->sendText('my-session', [
    'chatId' => '628123456789@c.us',
    'text'   => 'Hello from the OpenWA PHP SDK!',
]);
echo $result['messageId'];

Requires PHP 8.1+ and Guzzle 7. For testing, inject a Guzzle client whose handler is a MockHandler — no global state, no network.

Java

<dependency>
  <groupId>com.rmyndharis</groupId>
  <artifactId>openwa</artifactId>
  <version>0.1.1</version>
</dependency>
import com.rmyndharis.openwa.OpenWAClient;
import com.rmyndharis.openwa.model.MessageResponse;
import com.rmyndharis.openwa.model.SendTextRequest;

OpenWAClient client = new OpenWAClient("http://localhost:2785", "owa_k1_…");

client.sessions.start("my-session");
MessageResponse result = client.messages.sendText("my-session",
    SendTextRequest.builder()
        .chatId("628123456789@c.us")
        .text("Hello from the OpenWA Java SDK!")
        .build());
System.out.println(result.messageId());

Requires Java 17+. Errors are a typed, unchecked hierarchy — branch with instanceof OpenWANotFoundError / OpenWAConflictError. For testing, inject a custom HttpTransport that records the request — no network. See java/README.md for the full guide.

Reliability & security

  • Use HTTPS in production. The API key is sent as X-API-Key on every request and is bearer-equivalent — never send it over plaintext http:// outside local development.
  • No automatic retries. A failed request raises/throws immediately; wrap calls in your own backoff if you need retries (especially for 429). The injectable transport (fetch / transport / httpClient) is the extension point for retry or observability middleware.
  • Redirects are never followed. A 3xx surfaces to the caller rather than being followed, so the API key is never re-sent to a redirect target.
  • Default per-request timeout is 30s (configurable). Path segments (chat / message ids) are percent-encoded; a base-URL path prefix (e.g. behind a proxy at /v1) is preserved.

Development

# JavaScript
cd sdk/javascript && npm test && npm run build && npm run smoke
# Python
cd sdk/python && python -m pytest -q
# PHP
cd sdk/php && composer install && ./vendor/bin/phpunit
# Java
cd sdk/java && mvn -B verify

Each test suite mocks the HTTP layer and asserts on the exact path, so the regression that originally shipped a broken messages/text path (the real path is messages/send-text) can never recur silently.