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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ This repository provides:
| [`faq-bot`](./faq-bot) | Auto-replies to inbound WhatsApp messages from configurable FAQ keyword/regex rules. | 0.1.6 | stable |
| [`group-translate`](./group-translate) | Auto-translates group messages between participants' languages via a LibreTranslate backend. Configure in-chat with /tr commands. Admin-gated; disabled until enabled. | 1.0.5 | stable |
| [`gsheets-logger`](./gsheets-logger) | Logs WhatsApp message events to a Google Sheet via a service account. | 0.2.3 | stable |
| [`http-action`](./http-action) | Triggers safe REST API requests from WhatsApp commands and renders JSON responses back to chat. | 0.1.0 | development |
| [`http-action`](./http-action) | Triggers safe REST API requests from WhatsApp commands and renders JSON responses back to chat. | 0.1.0 | beta |
| [`supabase-otp-hook`](./supabase-otp-hook) | Deliver Supabase Auth phone OTPs over WhatsApp. | 0.1.0 | beta |
| [`typebot-connector`](./typebot-connector) | Runs a Typebot flow as the brain of a WhatsApp bot: inbound messages drive a Typebot chat session via the live Chat API, and the bot's replies — text, media, and numbered-choice inputs — are sent back to WhatsApp. Auto-starts every chat, handles file-upload steps, and resets when the flow ends or after an idle timeout. Runs sandboxed in the plugin worker; no public URL or webhook required. | 0.1.0 | beta |
| [`voice-transcription`](./voice-transcription) | Transcribes inbound WhatsApp voice notes to text via an OpenAI-compatible speech-to-text backend (self-hosted Speaches/faster-whisper or hosted Groq/OpenAI) and delivers a `message.transcription` event to your webhook — so bots and AI can read and reply to audio. Off the message-delivery path; disabled until enabled. | 1.0.1 | beta |
Expand Down
2 changes: 1 addition & 1 deletion http-action/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
| **Identifier** | `http-action` |
| **Version** | 0.1.0 |
| **Released** | 2026-07-11 |
| **Status** | development |
| **Status** | beta |
| **Author** | Yudhi Armyndharis |
| **License** | MIT |
| **Type** | `extension` |
Expand Down
23 changes: 23 additions & 0 deletions http-action/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,26 @@ test('send failure leaves the message un-marked: a redelivery after the cooldown
assert.equal(sendCalls.length, 1); // retried send succeeded
assert.equal(await hasSeen(storage, 's1', 'm1'), true); // marked only after the successful send
});

// ---- sentinel (DoD §7): the auth token is used in the header but never reaches logs or the reply ----
test('sentinel: the auth token is sent in the header yet never appears in logs or the reply', async () => {
const SECRET = 'SENTINEL-do-not-leak-9f3k2';
const logged: unknown[] = [];
const sendCalls: { env: unknown }[] = [];
let capturedHeaders: Record<string, string> | undefined;
const cfg = cfgWith({ authType: 'bearer', authToken: SECRET });
const d: HandleDeps = {
cfg, storage: fakeStore(), cooldown: new Map(), now: () => 1000,
fetch: async (_u, init) => { capturedHeaders = init?.headers; throw new Error('upstream failure'); },
conversations: { send: async (env: unknown) => { sendCalls.push({ env }); } },
logger: {
log: (m: string) => logged.push(m),
warn: (m: string, e?: unknown) => logged.push([m, e]),
error: (m: string, e?: unknown) => logged.push([m, e]),
},
};
await handleMessage(d, 's1', msg('cek X'));
assert.ok(capturedHeaders?.Authorization?.includes(SECRET), 'sanity: secret is in the request header (used, not absent)');
const haystack = `${JSON.stringify(logged)}${JSON.stringify(sendCalls)}`;
assert.ok(!haystack.includes(SECRET), 'auth token must never appear in logs or the reply');
});
2 changes: 1 addition & 1 deletion http-action/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"homepage": "https://github.com/rmyndharis/OpenWA-plugins/tree/main/http-action",
"repository": "https://github.com/rmyndharis/OpenWA-plugins",
"keywords": ["api", "rest", "automation", "connector", "whatsapp", "openwa"],
"status": "development",
"status": "beta",
"minOpenWAVersion": "0.8.7",
"sdkVersion": "1",
"provides": ["api-automation", "rest-connector", "dynamic-reply"],
Expand Down
2 changes: 1 addition & 1 deletion plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@
"name": "HTTP Action Bot",
"version": "0.1.0",
"type": "extension",
"status": "development",
"status": "beta",
"description": "Triggers safe REST API requests from WhatsApp commands and renders JSON responses back to chat.",
"author": "Yudhi Armyndharis <yudhi@rmyndharis.com>",
"license": "MIT",
Expand Down
Loading