From 562632f2ed974b82de630dcc13c717030f75e7ef Mon Sep 17 00:00:00 2001 From: Yudhi Armyndharis Date: Sun, 12 Jul 2026 07:41:30 +0700 Subject: [PATCH] docs: standardize all plugin READMEs to PLUGIN-STANDARD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring every plugin README into line with PLUGIN-STANDARD.md — the badge row (type / license / OpenWA compatibility), a blockquote tagline, and the full required section set (Details, Features, behavior, Setup, Install, Configuration, Compatibility, Security, Changelog, License). A heading-only glance had masked several gaps; this pass reads each README in full and closes them. - typebot-connector: full rewrite — previously only a Details block, "How it works", "Setup", and "Notes & limits". Added badges, tagline, Features, Install, Configuration, Compatibility, Security, Changelog, License. - chatwoot-adapter: added the badge row, blockquote tagline, and an Install section. - supabase-otp-hook: added the badge row and blockquote tagline; reordered Setup before Install. - after-hours: added a Security section and a Setup section. - chat-flow, faq-bot, group-translate, http-action: added a Setup section. - http-action: set minOpenWAVersion 0.8.7 (allowConfigHosts + conversation:send) so the OpenWA badge carries a real value; testedOpenWAVersion left unset (still development). Catalog regenerated. catalog:check, typecheck, and the full test suite (395) all pass. --- after-hours/README.md | 13 +++++ chat-flow/README.md | 7 +++ chatwoot-adapter/README.md | 26 +++++++-- faq-bot/README.md | 6 ++ group-translate/README.md | 8 +++ http-action/README.md | 18 ++++-- http-action/manifest.json | 1 + plugins.json | 2 +- supabase-otp-hook/README.md | 43 ++++++++------ typebot-connector/README.md | 113 +++++++++++++++++++++++++++++------- 10 files changed, 187 insertions(+), 50 deletions(-) diff --git a/after-hours/README.md b/after-hours/README.md index eb99d2e..9b4318b 100644 --- a/after-hours/README.md +++ b/after-hours/README.md @@ -45,6 +45,13 @@ absent day is also closed. Times are 24-hour, `open < close` (same-day): "thu": "09:00-17:00", "fri": "09:00-17:00", "sat": "09:00-13:00", "sun": null } ``` +## Setup + +1. Have OpenWA **≥ 0.6.2** running with a logged-in WhatsApp session. +2. Install and enable the plugin (see [Install](#install)). +3. Set your weekly schedule, timezone, and away message (see [Configuration](#configuration)) — the + schedule is interpreted in your `timezone` via `Intl`, independent of the host clock. + ## Install ```bash @@ -79,6 +86,12 @@ and upload it in the dashboard **Plugins → Install** (or the **Catalog** tab). Targets OpenWA **≥ 0.6.2** (sandboxed runtime with `Intl` timezone data and `onConfigChange` forwarding, so schedule edits apply live without a re-enable). +## Security + +The plugin declares only `messages:send` and makes no outbound network calls. The away message is the +operator's `awayMessage` config (operator-trusted text); a quoted reply is throttled to once per chat per +`cooldownSec`, so a customer sending several after-hours messages isn't spammed. + ## Changelog See [CHANGELOG.md](./CHANGELOG.md). diff --git a/chat-flow/README.md b/chat-flow/README.md index 824796b..a79d81f 100644 --- a/chat-flow/README.md +++ b/chat-flow/README.md @@ -63,6 +63,13 @@ user types, e.g. `"1"`), the reply `text`, and optional nested `options` (a subm Editing the tree by hand is optional — the plugin ships a **visual flow editor** the dashboard opens in a sandboxed frame. A reply that doesn't match any option re-sends the current menu. +## Setup + +1. Have OpenWA **≥ 0.7.0** running with a logged-in WhatsApp session. +2. Install and enable the plugin (see [Install](#install)). +3. Design your menu tree — via the built-in visual editor or the JSON config + (see [Configuration](#configuration)). + ## Install ```bash diff --git a/chatwoot-adapter/README.md b/chatwoot-adapter/README.md index 726e6d9..11374aa 100644 --- a/chatwoot-adapter/README.md +++ b/chatwoot-adapter/README.md @@ -1,9 +1,12 @@ # Chatwoot Adapter -Two-way sync between a WhatsApp session (via OpenWA) and a [Chatwoot](https://www.chatwoot.com/) inbox, plus -human handover. Relays WhatsApp messages into Chatwoot, sends agent replies back to WhatsApp, and — when a -human agent takes a chat over in Chatwoot — silences other OpenWA bots on that chat while continuing to -mirror it. Runs sandboxed in the plugin worker; no server, no extra port. +> Two-way sync between a WhatsApp session (via OpenWA) and a [Chatwoot](https://www.chatwoot.com/) inbox, +> with human handover — relay WhatsApp into Chatwoot, send agent replies back, and silence other OpenWA +> bots on that chat while a human agent is in control. + +![type: extension](https://img.shields.io/badge/type-extension-blue.svg) +![license: MIT](https://img.shields.io/badge/license-MIT-green.svg) +![built for OpenWA](https://img.shields.io/badge/OpenWA-%E2%89%A5%200.8.7-25D366.svg) ## Details @@ -56,6 +59,21 @@ sees it. Copy the **ingress URL** it shows: `{BASE_URL}/api/ingress/chatwoot-adapter/{instanceId}/chatwoot`. 4. **Chatwoot — set the webhook URL** to the ingress URL from step 3. +## Install + +**Option A — dashboard.** Download `chatwoot-adapter.zip` from the [Releases page](https://github.com/rmyndharis/OpenWA-plugins/releases), then dashboard → Plugins → Install → upload. + +**Option B — CLI.** + +```bash +node package.mjs chatwoot-adapter # build the zip +curl -X POST "$OPENWA/api/plugins/install" \ + -H "Authorization: Bearer $ADMIN_KEY" \ + -F "file=@chatwoot-adapter.zip" +curl -X POST "$OPENWA/api/plugins/chatwoot-adapter/enable" \ + -H "Authorization: Bearer $ADMIN_KEY" +``` + ## Configuration | Key | Type | Required | Description | diff --git a/faq-bot/README.md b/faq-bot/README.md index cbe0208..dfc682d 100644 --- a/faq-bot/README.md +++ b/faq-bot/README.md @@ -48,6 +48,12 @@ ] ``` +## Setup + +1. Have OpenWA **≥ 0.6.1** running with a logged-in WhatsApp session. +2. Install and enable the plugin (see [Install](#install)). +3. Add your FAQ rules (see [Configuration](#configuration)). + ## Install ```bash diff --git a/group-translate/README.md b/group-translate/README.md index fe5ea70..f96f196 100644 --- a/group-translate/README.md +++ b/group-translate/README.md @@ -50,6 +50,14 @@ Default prefix `/tr` (configurable). Read-only commands are open; the rest are a | `/tr ignore` · `/tr unignore [@user]` | admin | Skip / resume translating a participant | | `/tr grant` · `/tr revoke [@user]` | admin | Delegate / remove control to a non-admin participant | +## Setup + +1. **Run a LibreTranslate instance.** The plugin calls its `/translate` endpoint over `ctx.net.fetch`. + Add the instance's `host:port` to the manifest `net.allow` before packaging, and — if it's on + `localhost`/a private host — also set `SSRF_ALLOWED_HOSTS` on the OpenWA host (see [Security](#security)). +2. Have OpenWA **≥ 0.7.0** running with a logged-in WhatsApp session for the group(s) you want to translate. +3. Install and enable the plugin (see [Install](#install)), then have a group admin run `/tr on`. + ## Install ```bash diff --git a/http-action/README.md b/http-action/README.md index 3ef58bf..bf68d7c 100644 --- a/http-action/README.md +++ b/http-action/README.md @@ -5,7 +5,7 @@ ![type: extension](https://img.shields.io/badge/type-extension-blue.svg) ![license: MIT](https://img.shields.io/badge/license-MIT-green.svg) -![status: development](https://img.shields.io/badge/status-development-orange.svg) +![built for OpenWA](https://img.shields.io/badge/OpenWA-%E2%89%A5%200.8.7-25D366.svg) ## Details @@ -19,7 +19,7 @@ | **Author** | Yudhi Armyndharis | | **License** | MIT | | **Type** | `extension` | -| **Requires OpenWA** | ≥ null (tested null) | +| **Requires OpenWA** | ≥ 0.8.7 (tested null) | | **Keywords** | api, rest, automation, connector, whatsapp, openwa | | **Repository** | [OpenWA-plugins/http-action](https://github.com/rmyndharis/OpenWA-plugins/tree/main/http-action) | @@ -59,6 +59,13 @@ Template variables: `args.0`, `args.1`, … plus `message.id`, `message.body`, `chat.id`, `sender.id`, `sender.phone`, `sender.name`, `session.id`, and `response.` (the parsed JSON body). +## Setup + +1. Have an **HTTPS API** you want to call from WhatsApp — its origin goes in `baseUrl`. +2. Have OpenWA **≥ 0.8.7** running with a logged-in WhatsApp session. +3. Install and enable the plugin (see [Install](#install)), then define your actions + (see [Configuration](#configuration)). + ## Install ```bash @@ -93,9 +100,10 @@ and upload it in the dashboard **Plugins → Install** (or the **Catalog** tab). ## Compatibility -Status is **development**. `minOpenWAVersion` / `testedOpenWAVersion` are not yet set — the plugin needs -install and runtime testing on a real OpenWA instance before being marked `beta`. Live config edits apply -on the next inbound message (config is re-read per event). +Status is **development**. It targets OpenWA **≥ 0.8.7** (`allowConfigHosts` + `conversation:send`); +`testedOpenWAVersion` is not yet set — the plugin needs install and runtime testing on a real OpenWA +instance before being marked `beta`. Live config edits apply on the next inbound message (config is +re-read per event). ## Security diff --git a/http-action/manifest.json b/http-action/manifest.json index 4dbf630..8c2bd3f 100644 --- a/http-action/manifest.json +++ b/http-action/manifest.json @@ -11,6 +11,7 @@ "repository": "https://github.com/rmyndharis/OpenWA-plugins", "keywords": ["api", "rest", "automation", "connector", "whatsapp", "openwa"], "status": "development", + "minOpenWAVersion": "0.8.7", "sdkVersion": "1", "provides": ["api-automation", "rest-connector", "dynamic-reply"], "permissions": ["net:fetch", "conversation:send"], diff --git a/plugins.json b/plugins.json index e325ede..a1e20d9 100644 --- a/plugins.json +++ b/plugins.json @@ -1019,7 +1019,7 @@ "whatsapp", "openwa" ], - "minOpenWAVersion": null, + "minOpenWAVersion": "0.8.7", "testedOpenWAVersion": null, "releasedAt": "2026-07-11", "repoPath": "http-action", diff --git a/supabase-otp-hook/README.md b/supabase-otp-hook/README.md index 090cfcc..967e0f2 100644 --- a/supabase-otp-hook/README.md +++ b/supabase-otp-hook/README.md @@ -1,8 +1,12 @@ # Supabase Auth OTP → WhatsApp -Deliver Supabase Auth phone OTPs over WhatsApp. Supabase's [Send SMS hook](https://supabase.com/docs/guides/auth/auth-hooks/send-sms-hook) -POSTs `{ user: { phone }, sms: { otp } }` signed with [Standard Webhooks](https://www.standardwebhooks.com/); -the host verifies the signature and the plugin sends the OTP via an OpenWA WhatsApp session. +> Deliver Supabase Auth phone OTPs over WhatsApp. Supabase's Send SMS hook (Standard Webhooks-signed) is +> verified host-side, and the plugin sends the OTP via an OpenWA WhatsApp session — with synchronous +> feedback to Supabase (401 on a bad signature, 503 on a dead session, 200 on accept). + +![type: extension](https://img.shields.io/badge/type-extension-blue.svg) +![license: MIT](https://img.shields.io/badge/license-MIT-green.svg) +![built for OpenWA](https://img.shields.io/badge/OpenWA-%E2%89%A5%200.8.16-25D366.svg) ## Details @@ -46,25 +50,11 @@ sandboxed handler async from the ingress worker (retry + DLQ). The handler parse sms: { otp } }`, normalizes the phone to `@c.us`, and fires the WhatsApp send in the background to stay within the worker's 5 s dispatch budget. -## Install - -**Option A — dashboard.** Download `supabase-otp-hook.zip` from the [Releases page](https://github.com/maplerichie/OpenWA-plugins/releases), then dashboard → Plugins → Install → upload. - -**Option B — CLI.** - -```bash -node package.mjs supabase-otp-hook # build the zip -curl -X POST "$OPENWA/api/plugins/install" \ - -H "Authorization: Bearer $ADMIN_KEY" \ - -F "file=@supabase-otp-hook.zip" -curl -X POST "$OPENWA/api/plugins/supabase-otp-hook/enable" \ - -H "Authorization: Bearer $ADMIN_KEY" -``` - ## Setup Requires OpenWA v0.8.16+ (the `standard-webhooks` signature scheme and the `response`/preflight -ingress contract) with a logged-in WhatsApp session, and a Supabase project with phone auth. +ingress contract) with a logged-in WhatsApp session, and a Supabase project with phone auth. **Install +and enable the plugin first** (see [Install](#install) below), then wire the connection: Wiring order: OpenWA mints the **ingress URL** → paste into Supabase → Supabase generates the **webhook secret** → paste it back into OpenWA **as the instance secret** (the host uses it to verify @@ -106,6 +96,21 @@ curl -X PATCH "$OPENWA/api/integration/plugins/supabase-otp-hook/instances/defau **6. Test.** Trigger a phone-OTP sign-in. Supabase receives 200 and the OTP arrives in WhatsApp. A dead WhatsApp session yields 503 (visible to Supabase); a bad signature yields 401. +## Install + +**Option A — dashboard.** Download `supabase-otp-hook.zip` from the [Releases page](https://github.com/maplerichie/OpenWA-plugins/releases), then dashboard → Plugins → Install → upload. + +**Option B — CLI.** + +```bash +node package.mjs supabase-otp-hook # build the zip +curl -X POST "$OPENWA/api/plugins/install" \ + -H "Authorization: Bearer $ADMIN_KEY" \ + -F "file=@supabase-otp-hook.zip" +curl -X POST "$OPENWA/api/plugins/supabase-otp-hook/enable" \ + -H "Authorization: Bearer $ADMIN_KEY" +``` + ## Configuration | Key | Type | Required | Description | diff --git a/typebot-connector/README.md b/typebot-connector/README.md index 1937aa9..cfa36c8 100644 --- a/typebot-connector/README.md +++ b/typebot-connector/README.md @@ -1,7 +1,13 @@ # Typebot Connector -Run a [Typebot](https://typebot.io) flow as the brain of a WhatsApp bot. Inbound WhatsApp messages drive a -Typebot chat session; the bot's replies (text, media, and menu choices) are sent back to WhatsApp. +> Run a [Typebot](https://typebot.io) flow as the brain of a WhatsApp bot — inbound messages drive a +> Typebot chat session, and the bot's text, media, and numbered-choice replies come back to WhatsApp. + +![type: extension](https://img.shields.io/badge/type-extension-blue.svg) +![license: MIT](https://img.shields.io/badge/license-MIT-green.svg) +![built for OpenWA](https://img.shields.io/badge/OpenWA-%E2%89%A5%200.8.2-25D366.svg) + +## Details | Field | Value | @@ -18,33 +24,98 @@ Typebot chat session; the bot's replies (text, media, and menu choices) are sent | **Repository** | [OpenWA-plugins/typebot-connector](https://github.com/rmyndharis/OpenWA-plugins/tree/main/typebot-connector) | -## How it works +## Features + +- **Typebot as the brain** — the first message in a chat starts a Typebot session (`startChat`); each + later message advances it (`continueChat`). Typebot holds the session state; this plugin stores only + the session id and what the bot is waiting for. +- **Rich replies back to WhatsApp** — text bubbles are converted to WhatsApp formatting; image, video, + and audio bubbles are sent as media; a `choice` step is shown as a numbered list and the contact's + numeric reply is mapped back to the option. +- **Typed inputs validated by Typebot** — email, number, date, … are re-asked on a bad value. A file + input step accepts a photo/file the contact sends and uploads it to Typebot. +- **Auto-reset** — the session resets when the flow ends or after the idle timeout, so the next message + starts fresh. +- **No public URL or webhook** — runs sandboxed in the plugin worker and polls Typebot's live Chat API + over the host's SSRF-guarded `ctx.net.fetch`. -- The first message in a chat starts a Typebot session (`startChat`); each later message advances it - (`continueChat`). Typebot holds the session state; this plugin stores only the session id and what the - bot is waiting for. -- Text bubbles are converted to WhatsApp formatting; image/video/audio bubbles are sent as media; a - `choice` step is shown as a numbered list and your numeric reply is mapped back to the option. -- Typed inputs (email, number, date, …) are validated by Typebot — a bad value is re-asked. A `file input` - step accepts a photo/file you send and uploads it to Typebot. -- The session resets when the flow ends or after the idle timeout. +## What it does + +On each inbound message in scope, the plugin resumes (or starts) the contact's Typebot session, sends +the message to Typebot's Chat API, and renders the bot's reply bubbles back into WhatsApp — text as +formatted messages, media bubbles as media, and a `choice` step as a numbered list whose numeric reply +is mapped back to the chosen option. Session state lives in Typebot; the plugin persists only the +session id and the bot's expected next input. A chat resets when the flow ends or after the idle +timeout. ## Setup 1. In Typebot, build and **publish** your bot, then copy its **public ID** from the Share settings. - (Optional: define flow variables named `waNumber`, `waName`, `waChatId` to receive the contact's details.) -2. Install and enable this plugin for your WhatsApp session in OpenWA. -3. Configure: + (Optional: define flow variables named `waNumber`, `waName`, `waChatId` to receive the contact's + details.) +2. Install and enable this plugin for your WhatsApp session in OpenWA (see [Install](#install)). +3. Configure (see [Configuration](#configuration)): - **Typebot host URL** — `https://typebot.io` for Cloud, or your self-hosted URL. - **Typebot public ID** — from step 1. - **API token** — only for a restricted/preview bot; leave empty otherwise. - - Optional: turn off **Respond in group chats**, adjust the **idle reset**, or set a **media/upload host** - (only for older self-hosted Typebot with a separate file-storage host). + - Optional: turn off **Respond in group chats**, adjust the **idle reset**, or set a **media/upload + host** (only for older self-hosted Typebot with a separate file-storage host). 4. Message the WhatsApp number — the flow starts automatically. -## Notes & limits +## Install + +```bash +node package.mjs typebot-connector # produces typebot-connector.zip at the repo root + +curl -X POST "https://your-openwa-host/plugins/install" \ + -H "X-API-Key: " -F "file=@typebot-connector.zip" + +curl -X PUT "https://your-openwa-host/plugins/typebot-connector/config" \ + -H "X-API-Key: " -H "Content-Type: application/json" \ + -d '{ "config": { "apiHost": "https://typebot.io", "publicId": "" } }' + +curl -X POST "https://your-openwa-host/plugins/typebot-connector/enable" \ + -H "X-API-Key: " +``` + +Or download the packaged `.zip` from [Releases](https://github.com/rmyndharis/OpenWA-plugins/releases) +and upload it in the dashboard **Plugins → Install** (or the **Catalog** tab). + +## Configuration + +| Key | Required | Default | Description | +| --- | -------- | ------- | ----------- | +| `apiHost` | yes | `https://typebot.io` | Public `https` URL of your Typebot (Cloud or public-domain self-hosted). Its host is auto-added to the outbound allowlist. Private/LAN hosts are not supported. | +| `publicId` | yes | — | The published bot's public identifier (from its Share settings). The bot must be published. | +| `apiToken` | no | — | Only for a restricted or preview bot. Leave empty for a public published bot. Stored as a secret. | +| `respondInGroups` | no | `true` | Run the flow in group chats too. Each sender in a group gets their own flow; replies are quoted. | +| `sessionTimeoutMinutes` | no | `30` | If a chat is idle this long, the next message starts a fresh flow. | +| `passContactVariables` | no | `true` | Send the contact's number/name/chat id to the flow as prefilled variables `waNumber`, `waName`, `waChatId`. | +| `mediaHost` | no | — | Only for older self-hosted Typebot that uploads files to a separate S3/MinIO host. Leave empty for Typebot main (same-origin upload proxy). | + +## Compatibility + +- Targets OpenWA **≥ 0.8.2** — uses the live Typebot Chat API over `ctx.net.fetch` + (`allowConfigHosts` resolves `apiHost`/`mediaHost` from config) and `ctx.conversations.send` for + outbound media/voice. +- **Auto-starts every chat in scope** (including groups by default). Don't run another auto-reply / + menu / FAQ plugin on the same session — they will conflict. +- `payment` steps and non-renderable embeds can't be shown on WhatsApp and get a short fallback + message. Streaming AI blocks are resolved server-side into normal text bubbles. + +## Security + +- **Outbound HTTP is allow-listed.** Calls go through the host's SSRF-guarded `ctx.net.fetch`; only + the configured `apiHost` (and `mediaHost`, if set) are reachable, and private/loopback addresses + stay blocked. No public URL or inbound webhook is required. +- The `apiToken` is stored as a secret and sent only to your Typebot host (and only when set). +- Bot replies originate from your Typebot flow (operator-trusted content); the plugin forwards them as + outbound messages and declares `conversation:send` + `net:fetch`. + +## Changelog + +See [CHANGELOG.md](./CHANGELOG.md). + +## License -- Auto-starts **every** chat in scope (including groups by default). Don't run another auto-reply plugin on - the same session. -- `payment` steps and non-renderable embeds can't be shown on WhatsApp and get a short fallback message. -- Streaming AI blocks are resolved server-side into normal text bubbles. +[MIT](../LICENSE) © Yudhi Armyndharis & OpenWA Contributors.