101 lines
3.0 KiB
Bash
Executable File
101 lines
3.0 KiB
Bash
Executable File
#!/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
|