Initial commit: OpenClaw ops workspace

This commit is contained in:
2026-03-28 00:15:47 +00:00
commit f1aeaeefb5
42 changed files with 4297 additions and 0 deletions

100
scripts/gmail-unread-poll.sh Executable file
View File

@@ -0,0 +1,100 @@
#!/usr/bin/env bash
set -euo pipefail
STATE_DIR="${STATE_DIR:-/home/node/.openclaw/workspace/state}"
STATE_FILE="${STATE_FILE:-$STATE_DIR/gmail-unread-state.json}"
ACCOUNT="${ACCOUNT:-claw@ben.io}"
MAX_RESULTS="${MAX_RESULTS:-10}"
OPENCLAW_BIN="${OPENCLAW_BIN:-openclaw}"
CHANNEL="${CHANNEL:-discord}"
DEST="${DEST:-channel:1467247377743347953}"
ACCOUNT_ID="${ACCOUNT_ID:-default}"
mkdir -p "$STATE_DIR"
TMP_LIST=$(mktemp)
trap 'rm -f "$TMP_LIST"' EXIT
if ! gws gmail users messages list --params "{\"userId\":\"me\",\"maxResults\":$MAX_RESULTS,\"q\":\"is:unread\"}" --format json > "$TMP_LIST" 2>/dev/null; then
echo "gmail-unread-poll: failed to query Gmail unread messages" >&2
exit 1
fi
CURRENT_IDS=$(node -e '
const fs = require("fs");
const data = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
const ids = (data.messages || []).map(m => m.id).sort();
process.stdout.write(JSON.stringify(ids));
' "$TMP_LIST")
if [[ -f "$STATE_FILE" ]]; then
PREV_IDS=$(node -e '
const fs = require("fs");
const p = process.argv[1];
const data = JSON.parse(fs.readFileSync(p, "utf8"));
process.stdout.write(JSON.stringify((data.unreadIds || []).sort()));
' "$STATE_FILE")
else
PREV_IDS='[]'
fi
if [[ "$CURRENT_IDS" == "$PREV_IDS" ]]; then
exit 0
fi
NEW_IDS=$(node -e '
const prev = new Set(JSON.parse(process.argv[1]));
const curr = JSON.parse(process.argv[2]);
process.stdout.write(JSON.stringify(curr.filter(id => !prev.has(id))));
' "$PREV_IDS" "$CURRENT_IDS")
NEW_COUNT=$(node -e 'const a = JSON.parse(process.argv[1]); process.stdout.write(String(a.length));' "$NEW_IDS")
TOTAL_UNREAD=$(node -e 'const a = JSON.parse(process.argv[1]); process.stdout.write(String(a.length));' "$CURRENT_IDS")
if [[ "$NEW_COUNT" -gt 0 ]]; then
SUMMARY=$(node - <<'NODE' "$NEW_IDS"
const ids = JSON.parse(process.argv[2]);
console.log(`claw@ben.io: ${ids.length} new unread mail(s)`);
NODE
)
DETAILS=()
while IFS= read -r id; do
[[ -z "$id" ]] && continue
JSON=$(gws gmail +read --message-id "$id" --format json 2>/dev/null || true)
if [[ -n "$JSON" ]]; then
LINE=$(node -e '
const fs = require("fs");
const data = JSON.parse(fs.readFileSync(0, "utf8"));
const from = data.from?.email || data.from?.name || "unknown";
const subject = data.subject || "(no subject)";
process.stdout.write(`- ${from} — ${subject}`);
' <<<"$JSON")
DETAILS+=("$LINE")
fi
done < <(node -e 'for (const id of JSON.parse(process.argv[1])) console.log(id)' "$NEW_IDS")
MSG="$SUMMARY
Total unread: $TOTAL_UNREAD"
if [[ ${#DETAILS[@]} -gt 0 ]]; then
MSG+="
$(printf '%s
' "${DETAILS[@]}")"
fi
"$OPENCLAW_BIN" message send \
--account "$ACCOUNT_ID" \
--channel "$CHANNEL" \
--target "$DEST" \
--message "$MSG" >/dev/null 2>&1 || {
echo "gmail-unread-poll: failed to send notification" >&2
exit 1
}
fi
node - <<'NODE' "$STATE_FILE" "$CURRENT_IDS"
const fs = require('fs');
const path = process.argv[2];
const unreadIds = JSON.parse(process.argv[3]);
fs.writeFileSync(path, JSON.stringify({ unreadIds, updatedAt: new Date().toISOString() }, null, 2));
NODE