#!/bin/bash
# keet-bot.sh — Polls Keet for new messages and alerts via file
# A Claude Code session can then read the inbox and respond
# Usage: ./keet-bot.sh [roomId]
ROOM_ID="${1:-ar5jd5tc3od5hbxxg6818pw9ikpgeq39y8ybgonyu9n179cdz8po}"
PORT=3117
LOG="/tmp/keet-bot.log"
INBOX="/tmp/keet-inbox"
MY_MEMBER_ID="z9i4wpf3pmp3cwhh9nnwysbwxcgx1f8sminypcc63esbi8ih9iby"
LAST_SEQ_FILE="/tmp/keet-bot-lastseq"
POLL_INTERVAL=1
log() {
local ts
ts="$(date '+%Y-%m-%d %H:%M:%S')"
echo "[$ts] $*" | tee -a "$LOG"
}
poll() {
log "=== keet-bot started (polling mode) ==="
log "Room: $ROOM_ID"
log "Inbox: $INBOX"
# Get current latest seq to skip history
local init_data
init_data=$(curl -s "http://localhost:${PORT}/rpc/messages/${ROOM_ID}?limit=1" 2>/dev/null)
local last_seq
last_seq=$(echo "$init_data" | python3 -c "
import json, sys
try:
data = json.load(sys.stdin)
msgs = data.get('data', [])
if msgs: print(msgs[-1].get('seq', 0))
else: print(0)
except: print(0)
" 2>/dev/null)
echo "$last_seq" > "$LAST_SEQ_FILE"
: > "$INBOX" # clear inbox
log "Starting from seq $last_seq"
log "--- live ---"
while true; do
sleep "$POLL_INTERVAL"
local saved_seq
saved_seq=$(cat "$LAST_SEQ_FILE" 2>/dev/null || echo "0")
local result
result=$(curl -s "http://localhost:${PORT}/rpc/messages/${ROOM_ID}?limit=10" 2>/dev/null)
[ -z "$result" ] && continue
# Find new messages from others (process substitution avoids subshell)
while IFS=$'\t' read -r type seq name text; do
if [ "$type" = "MSG" ]; then
local ts
ts="$(date '+%H:%M')"
log ">> $name: $text"
echo "[$ts] $name: $text" >> "$INBOX"
elif [ "$type" = "SEQ" ]; then
echo "$seq" > "$LAST_SEQ_FILE"
fi
done < <(python3 -c "
import json, sys
try:
data = json.loads(sys.argv[1])
last_seq = int(sys.argv[2])
my_id = sys.argv[3]
msgs = data.get('data', [])
max_seq = last_seq
for m in msgs:
seq = m.get('seq', 0)
if seq > max_seq: max_seq = seq
if seq <= last_seq: continue
member_id = m.get('memberId', '')
if member_id == my_id: continue
name = m.get('name') or member_id[:8]
text = m.get('text', '')
system = m.get('system')
if system or not text: continue
print(f'MSG\t{seq}\t{name}\t{text}')
print(f'SEQ\t{max_seq}')
except:
pass
" "$result" "$saved_seq" "$MY_MEMBER_ID" 2>/dev/null)
done
}
poll