Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

OpenWA SDKs

Official client libraries for the OpenWA WhatsApp API Gateway.

All three 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) 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+)

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.

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

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.