diff options
Diffstat (limited to 'api/chat/poll.php')
| -rw-r--r-- | api/chat/poll.php | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/api/chat/poll.php b/api/chat/poll.php new file mode 100644 index 0000000..601beca --- /dev/null +++ b/api/chat/poll.php @@ -0,0 +1,27 @@ +<?php +// api/chat/poll.php — read back the caller's own thread. The thread comes from the +// token, never from a query parameter: no id to guess, no IDOR, no listing. +// Contract: _docs/chat-contract.md +require_once __DIR__ . '/lib.php'; +// Note: poll is deliberately NOT rate limited. A 30 s poller is 120 GETs/hour; +// sharing the write window would make the client throttle itself into silence. + +$token = chat_token(); +$thread = chat_thread($token); +$since = isset($_GET['since']) ? (int)$_GET['since'] : 0; // epoch seconds, numeric + +$all = chat_read($thread); +$messages = $since > 0 + ? array_values(array_filter($all, fn($m) => (int)($m['epoch'] ?? 0) > $since)) + : $all; +$lastAll = $all ? end($all) : null; + +json_response([ + 'success' => true, + 'thread' => $thread, + 'messages' => array_slice($messages, -50), + // `awaiting` replaces `unread`: the server keeps no read state, so an unread + // counter could never clear. Who spoke last is knowable. + 'awaiting' => (bool)($lastAll && ($lastAll['author'] ?? '') !== 'hermes'), + 'cursor' => $lastAll ? (int)($lastAll['epoch'] ?? 0) : 0, +]); |