@laburen/openclaw-plugin-whatsapp-api 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +12 -11
  2. package/index.js +24 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -7,17 +7,6 @@ WhatsApp Cloud API channel for OpenClaw: your router receives Meta webhooks and
7
7
  ```bash
8
8
  openclaw plugins install @laburen/openclaw-plugin-whatsapp-api
9
9
  ```
10
-
11
- If you install from a local folder instead, copy the package into your OpenClaw extensions root and enable it in config (same plugin id: `whatsapp-api`).
12
-
13
- ## Context window reminder (cron scripts)
14
-
15
- The plugin stores the last inbound message so **`check.sh`** can remind the user before Meta’s 24-hour window ends. Run **`setup.sh`** by path (no `cd` needed—the script resolves `check.sh` next to itself):
16
-
17
- ```bash
18
- bash ~/.openclaw/extensions/whatsapp-api/src/scripts/setup.sh
19
- ```
20
-
21
10
  ## Setup
22
11
 
23
12
  1. In [Meta for Developers](https://developers.facebook.com/), create or open an app with **WhatsApp** product enabled and note your **Phone number ID** and a long-lived **System User** or **Temporary** access token with `whatsapp_business_messaging` (and webhook permissions as required by your setup).
@@ -55,6 +44,18 @@ openclaw gateway restart
55
44
 
56
45
  - Transient failures (`429`, `5xx`, timeouts) are retried according to `maxRetries`, `retryBackoffMs`, and `requestTimeoutMs`.
57
46
 
47
+ ### WhatsApp 24-hour context window (reminder)
48
+
49
+ WhatsApp Cloud API lets you send **session** messages (normal replies) only within about **24 hours** of the user’s last inbound message. After that window, outbound traffic is limited to **approved templates** until the user writes again.
50
+
51
+ This plugin can nudge you before the window closes:
52
+
53
+ 1. **Snapshot on inbound:** For each user message handled by the channel, a hook writes `<OpenClaw state dir>/whatsapp-api/last-inbound-message.json` with `from`, `content`, `timestamp`, channel/account/conversation ids when present, and **`notified: false`**. That reset means a new user message clears any previous “we already warned” state.
54
+ 2. **Cron from the host:** On service start, the plugin runs `setup.sh` (shipped under `src/scripts/` in the npm package). The script registers an OpenClaw cron job that periodically invokes `check.sh` via the exec tool (see the job’s description in `setup.sh`).
55
+ 3. **`check.sh` behavior:** It reads the JSON file, skips if missing or `notified` is already `true`, and compares elapsed time since `timestamp` to a threshold (default **23 hours**). If the threshold is met, it runs `openclaw message send` to the user’s phone (parsed from `from`) with a configurable warning text, then sets **`notified: true`** in the same file so the warning is not sent again until the next inbound message.
56
+
57
+ Useful environment variables for the scripts: `OPENCLAW_DIR` (defaults to `/home/<user>/.openclaw`), `THRESHOLD_MINUTES`, `WARNING_MESSAGE`, and `EVERY` for the cron interval when installing (default `30m`). To remove the job: `bash /path/to/node_modules/@laburen/openclaw-plugin-whatsapp-api/src/scripts/setup.sh --uninstall` (adjust path to your install).
58
+
58
59
  **Inbound webhook (from your router to OpenClaw)**
59
60
 
60
61
  | Item | Detail |
package/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import fs, { mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { tmpdir } from "node:os";
4
+ import { spawn } from "node:child_process";
5
+ import { fileURLToPath } from "node:url";
4
6
  //#region src/core/accounts.ts
5
7
  const CHANNEL_ID$1 = "whatsapp-api";
6
8
  const DEFAULT_WEBHOOK_PATH = "/webhook/whatsapp-api";
@@ -1388,7 +1390,7 @@ async function writeLastInboundMessage(stateDir, data) {
1388
1390
  /**
1389
1391
  * SPDX-License-Identifier: MIT
1390
1392
  *
1391
- * Persist last inbound message snapshot (used by background services).
1393
+ * Persist last inbound message snapshot for `check.sh` / cron window alerts.
1392
1394
  */
1393
1395
  const log$2 = waLogger("message-received/persist-last-inbound");
1394
1396
  async function handlePersistLastInbound(event, ctx) {
@@ -1430,17 +1432,33 @@ function registerAllPluginHooks(api) {
1430
1432
  //#endregion
1431
1433
  //#region src/services/context-window-check/register.ts
1432
1434
  const log$1 = waLogger("context-window-check");
1433
- /**
1434
- * Registers the `whatsapp-api` plugin service (state dir wiring; see `start` for
1435
- * the commented in-process poll vs OpenClaw cron + scripts, described in the
1436
- * module comment above).
1437
- */
1435
+ const SETUP_SH = path.join(path.dirname(fileURLToPath(import.meta.url)), "src", "scripts", "setup.sh");
1436
+ function runSetupSh() {
1437
+ return new Promise((resolve, reject) => {
1438
+ const child = spawn("bash", [SETUP_SH], {
1439
+ stdio: "inherit",
1440
+ env: process.env
1441
+ });
1442
+ child.on("error", reject);
1443
+ child.on("close", (code, signal) => {
1444
+ if (code === 0) resolve();
1445
+ else reject(/* @__PURE__ */ new Error(`setup.sh exited with code ${code ?? signal}`));
1446
+ });
1447
+ });
1448
+ }
1449
+ /** Registers the `whatsapp-api` plugin service (state dir + cron setup). */
1438
1450
  function registerContextWindowCheckService(api) {
1439
1451
  api.registerService({
1440
1452
  id: "whatsapp-api",
1441
1453
  start: async (ctx) => {
1442
1454
  setPluginServiceStateDir(ctx.stateDir);
1443
1455
  log$1.info("service started");
1456
+ try {
1457
+ await runSetupSh();
1458
+ log$1.info("setup.sh finished");
1459
+ } catch (error) {
1460
+ log$1.error("setup.sh failed", { error: String(error) });
1461
+ }
1444
1462
  },
1445
1463
  stop: async (_ctx) => {
1446
1464
  setPluginServiceStateDir(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laburen/openclaw-plugin-whatsapp-api",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "WhatsApp API channel plugin for OpenClaw",
6
6
  "main": "index.js",