Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions after-hours/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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).
Expand Down
7 changes: 7 additions & 0 deletions chat-flow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 22 additions & 4 deletions chatwoot-adapter/README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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 |
Expand Down
6 changes: 6 additions & 0 deletions faq-bot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions group-translate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 13 additions & 5 deletions http-action/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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) |
<!-- END DETAILS -->
Expand Down Expand Up @@ -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.<path>` (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
Expand Down Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions http-action/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down
2 changes: 1 addition & 1 deletion plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@
"whatsapp",
"openwa"
],
"minOpenWAVersion": null,
"minOpenWAVersion": "0.8.7",
"testedOpenWAVersion": null,
"releasedAt": "2026-07-11",
"repoPath": "http-action",
Expand Down
43 changes: 24 additions & 19 deletions supabase-otp-hook/README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -46,25 +50,11 @@ sandboxed handler async from the ingress worker (retry + DLQ). The handler parse
sms: { otp } }`, normalizes the phone to `<digits>@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
Expand Down Expand Up @@ -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 |
Expand Down
113 changes: 92 additions & 21 deletions typebot-connector/README.md
Original file line number Diff line number Diff line change
@@ -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

<!-- BEGIN DETAILS (generated by scripts/catalog.mjs — do not edit by hand) -->
| Field | Value |
Expand All @@ -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) |
<!-- END DETAILS -->

## 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: <ADMIN_API_KEY>" -F "file=@typebot-connector.zip"

curl -X PUT "https://your-openwa-host/plugins/typebot-connector/config" \
-H "X-API-Key: <ADMIN_API_KEY>" -H "Content-Type: application/json" \
-d '{ "config": { "apiHost": "https://typebot.io", "publicId": "<public-id>" } }'

curl -X POST "https://your-openwa-host/plugins/typebot-connector/enable" \
-H "X-API-Key: <ADMIN_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.
Loading