rmyndharis--openwa
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
194 行
8.2 KiB
Markdown
194 行
8.2 KiB
Markdown
# OpenWA SDKs
|
|
|
|
Official client libraries for the [OpenWA](https://github.com/rmyndharis/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`](javascript/) | dual ESM/CJS, bundled types |
|
|
| Python | [`rmyndharis-openwa`](python/) | sync (httpx), PEP 561 typed |
|
|
| PHP | [`rmyndharis/openwa`](php/) | sync (Guzzle, PHP 8.1+) |
|
|
| Java | [`com.rmyndharis:openwa`](java/) | 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
|
|
|
|
```bash
|
|
npm install @rmyndharis/openwa
|
|
```
|
|
|
|
```typescript
|
|
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`:
|
|
|
|
```typescript
|
|
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
|
|
|
|
```bash
|
|
pip install rmyndharis-openwa
|
|
```
|
|
|
|
```python
|
|
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
|
|
|
|
```bash
|
|
composer require rmyndharis/openwa
|
|
```
|
|
|
|
```php
|
|
<?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
|
|
|
|
```xml
|
|
<dependency>
|
|
<groupId>com.rmyndharis</groupId>
|
|
<artifactId>openwa</artifactId>
|
|
<version>0.1.1</version>
|
|
</dependency>
|
|
```
|
|
|
|
```java
|
|
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`](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
|
|
|
|
```bash
|
|
# 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.
|