3.4 KiB
LoBBS Machine API
For rich clients and agents over DM. Command names and player behavior are in the daily user guide. Field numbers and hook behavior are in LoBBS internals.
Why a machine mode
The plain-text reply is written for a person on a phone. A mail row reads [2]*@ben: see you at the trailhead (3h ago). The index, the * unread mark, the truncated preview, the relative time, and the {p n/t} footer exist for eyes, and plugins can rewrite them through display_human. A client that scrapes that line breaks whenever the wording changes.
A machine reply is the same result set before rendering. That mail row arrives as separate fields: the row id, the read flag, the created time in Unix seconds, and the preview, next to the title line a person would see. A client reads the fields it knows and ignores the rest.
The request id exists because the mesh is not a socket. DMs arrive seconds or minutes late, some never arrive, and they can arrive out of order. A client with several requests in flight matches each reply to its request by the echoed id. A person typing by hand does not need that, so the id is optional, and its presence is what selects machine mode.
There is no second API. Every command a person can type, a client can send with an id, and the same handler answers both. A new command works from a client the day it ships.
Paging uses the same cached reply for both. Each page is its own request with its own id, so a client that loses page 2 asks for page 2 again instead of re-running the command. [n:max] tells it how many DMs to collect before it parses.
Requests
Put a number and a space after / on a command to get a machine reply. The number only works when a space follows it (/42 login, not /42login). Without a leading id, replies use plain text and {p i/n} footers on the same cached result set.
Run the command first, then request further pages without re-running it.
/42 mail list
<42>ok [1:2]
…payload…
/43 p2
<43>ok [2:2]
…payload…
Reply shape
Each DM is 200 bytes or less, header included.
| Case | Header | Body |
|---|---|---|
| Success, one page | <id>ok newline |
LoScalar record lines |
| Success, multiple pages | <id>ok [n:max] newline |
Slice of the document |
| Error | <id> |
One sentence, no ok |
The [n:max] marker is separate from the request id. Use a fresh id on each page request (/43 p2, /44 p3). The reply echoes the id from that page request. Stop when n == max.
Success bodies are the cached result set encoded as LoScalar lines (number:value|number:value), one record per line. Concatenate page bodies in order, then split on newlines. Pages may cut through the middle of a line. Reassemble the full document before parsing records.
Paging
Human paging: /p2 after /mail list.
Machine paging: /43 p2 with a new id each page.
The node caches your last successful reply for about five minutes (reset on each page read). A new successful command replaces the cache. Errors do not change it. Payloads larger than 8 KiB are not cached. Page 1 is sent and /p2 replies No cached reply.. Past the end: No such page.