@laburen/openclaw-plugin-whatsapp-api 0.6.1 → 0.7.0
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.
- package/index.js +27 -2
- package/package.json +1 -1
- package/src/scripts/setup.sh +34 -11
package/index.js
CHANGED
|
@@ -1431,8 +1431,27 @@ const LABUREN_WEB_APP_CONFIG_KEY = "LABUREN_WEB_APP_URL";
|
|
|
1431
1431
|
const USER_PHONE_CONFIG_KEY = "userPhoneNumber";
|
|
1432
1432
|
const LABUREN_API_KEY_CONFIG_KEY = "laburenApiKey";
|
|
1433
1433
|
const USAGE_PATH = "/api/usage";
|
|
1434
|
-
const USAGE_FEATURE = "openclaw_run";
|
|
1435
1434
|
const POST_TIMEOUT_MS = 3e3;
|
|
1435
|
+
/**
|
|
1436
|
+
* OpenClaw classifies each run by `trigger`. Only `user` (and `manual` admin
|
|
1437
|
+
* actions) should be billed as real product usage. Background runs initiated
|
|
1438
|
+
* by the runtime (`heartbeat`) or by scheduled jobs (`cron`, `memory`,
|
|
1439
|
+
* `overflow`) must be reported under a separate feature so the backend can
|
|
1440
|
+
* apply a different billing policy.
|
|
1441
|
+
*
|
|
1442
|
+
* Without this mapping every heartbeat and every duplicated wa-api cron tick
|
|
1443
|
+
* (which both fire every 30m) was charged to the user as `openclaw_run`,
|
|
1444
|
+
* draining credits without any real interaction.
|
|
1445
|
+
*/
|
|
1446
|
+
function resolveFeatureFromTrigger(trigger) {
|
|
1447
|
+
switch (trigger) {
|
|
1448
|
+
case "heartbeat":
|
|
1449
|
+
case "cron":
|
|
1450
|
+
case "memory":
|
|
1451
|
+
case "overflow": return "heartbeat_run";
|
|
1452
|
+
default: return "openclaw_run";
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1436
1455
|
function resolveUsageIngestUrl() {
|
|
1437
1456
|
let baseRaw;
|
|
1438
1457
|
try {
|
|
@@ -1490,7 +1509,7 @@ async function handleForwardLlmUsage(event, ctx) {
|
|
|
1490
1509
|
const cacheWrite = usage.cacheWrite ?? 0;
|
|
1491
1510
|
const total = usage.total ?? input + output + cacheRead + cacheWrite;
|
|
1492
1511
|
const body = {
|
|
1493
|
-
feature:
|
|
1512
|
+
feature: resolveFeatureFromTrigger(ctx.trigger),
|
|
1494
1513
|
runId: event.runId,
|
|
1495
1514
|
sessionId: event.sessionId,
|
|
1496
1515
|
userPhoneNumber,
|
|
@@ -1682,6 +1701,12 @@ const plugin = {
|
|
|
1682
1701
|
id: "whatsapp-api",
|
|
1683
1702
|
name: "WhatsApp API",
|
|
1684
1703
|
description: "WhatsApp API channel plugin with inbound webhook and direct Meta outbound",
|
|
1704
|
+
/**
|
|
1705
|
+
* Called by OpenClaw when the plugin loads: publishes the channel, wires the
|
|
1706
|
+
* global plugin API holder, then registers pipeline hooks and plugin services.
|
|
1707
|
+
*
|
|
1708
|
+
* @param api - Plugin API injected by the host (config, runtime, registration helpers)
|
|
1709
|
+
*/
|
|
1685
1710
|
register(api) {
|
|
1686
1711
|
setPluginApi(api);
|
|
1687
1712
|
api.registerChannel({ plugin: createWhatsAppApiChannel(api) });
|
package/package.json
CHANGED
package/src/scripts/setup.sh
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
# Run once per OpenClaw instance.
|
|
4
4
|
#
|
|
5
5
|
# Usage:
|
|
6
|
-
# bash setup.sh → installs the cron
|
|
7
|
-
# bash setup.sh --uninstall → removes the cron
|
|
6
|
+
# bash setup.sh → installs the cron (cleans up duplicates first)
|
|
7
|
+
# bash setup.sh --uninstall → removes all instances of the cron
|
|
8
8
|
|
|
9
9
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
10
|
CHECK_SCRIPT="$SCRIPT_DIR/check.sh"
|
|
@@ -18,22 +18,45 @@ for arg in "$@"; do
|
|
|
18
18
|
esac
|
|
19
19
|
done
|
|
20
20
|
|
|
21
|
+
# List all job IDs that match $JOB_NAME. Uses `awk` instead of `jq` because the
|
|
22
|
+
# openclaw container image does not include jq (the previous version of this
|
|
23
|
+
# script silently failed the existence check, which caused duplicate crons to
|
|
24
|
+
# accumulate on every plugin boot — one debit per duplicate, per tick).
|
|
25
|
+
list_existing_ids() {
|
|
26
|
+
openclaw cron list 2>/dev/null \
|
|
27
|
+
| awk -v name="$JOB_NAME" 'index($0, name) {print $1}'
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
if [ "$UNINSTALL" = "true" ]; then
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
REMOVED=0
|
|
32
|
+
while read -r id; do
|
|
33
|
+
[ -z "$id" ] && continue
|
|
34
|
+
if openclaw cron rm "$id" >/dev/null 2>&1; then
|
|
35
|
+
echo "[$JOB_NAME] Cron job removed (id: $id)."
|
|
36
|
+
REMOVED=$((REMOVED + 1))
|
|
37
|
+
fi
|
|
38
|
+
done < <(list_existing_ids)
|
|
39
|
+
if [ "$REMOVED" -eq 0 ]; then
|
|
27
40
|
echo "[$JOB_NAME] No cron job found to remove."
|
|
28
41
|
fi
|
|
29
42
|
exit 0
|
|
30
43
|
fi
|
|
31
44
|
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
# Count existing instances. If zero → install. If one → idempotent skip.
|
|
46
|
+
# If more than one → cleanup duplicates and reinstall one (self-heal).
|
|
47
|
+
EXISTING_IDS=$(list_existing_ids)
|
|
48
|
+
EXISTING_COUNT=$(printf '%s\n' "$EXISTING_IDS" | awk 'NF' | wc -l)
|
|
49
|
+
|
|
50
|
+
if [ "$EXISTING_COUNT" -eq 1 ]; then
|
|
51
|
+
echo "[$JOB_NAME] Already installed (id: $EXISTING_IDS). Skipping."
|
|
36
52
|
exit 0
|
|
53
|
+
elif [ "$EXISTING_COUNT" -gt 1 ]; then
|
|
54
|
+
echo "[$JOB_NAME] Found $EXISTING_COUNT duplicate instance(s). Cleaning up before reinstall..."
|
|
55
|
+
while read -r id; do
|
|
56
|
+
[ -z "$id" ] && continue
|
|
57
|
+
openclaw cron rm "$id" >/dev/null 2>&1 \
|
|
58
|
+
&& echo "[$JOB_NAME] Removed duplicate id: $id"
|
|
59
|
+
done < <(printf '%s\n' "$EXISTING_IDS")
|
|
37
60
|
fi
|
|
38
61
|
|
|
39
62
|
chmod +x "$CHECK_SCRIPT"
|