feat(messages): add mark-read to mark threads as read - #110
Merged
nickknissen merged 4 commits intoSep 26, 2026
Merged
Conversation
…ollow API version changes
nickknissen
approved these changes
Sep 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The client could read messages but not mark them as read, so a thread stayed
unread in Aula however it was handled elsewhere.
Aula keeps one read marker per thread: the ID of the last message read. Its
web client sets it with
messaging.setLastReadMessagewhen a thread isopened. This adds the same call.
Changes:
AulaApiClient.mark_thread_read(thread_id)finds the newest message of thethread (a
Message,MessageEdited,MessageDeletedorAutoReply, thesame types the web client accepts) and moves the marker there. A thread can
start with events such as a recipient change, so it keeps paging until a
message turns up, and returns
False, without writing, when the thread hasnone.
for the
{"status": {"code": 0}}envelope, not just the HTTP status. Afterthe write it reads the thread again and requires
lastReadMessageIdto bethe message that was sent, so a call Aula ignored is not reported as done.
always sent as null, so the thread must show
mailBoxOwner.mailBoxOwnerTypeinstitutionProfile. A common or OTP inbox, or an answer with no owner, anull or a malformed one, raises
ValueErrorbefore anything is written.version negotiated by an earlier request is followed by the paging and the
confirmation.
more pages, it raises
ThreadScanLimitErrorrather than answering "nothingto mark". A thread that holds only events, with no more pages, is returned
unmarked and makes the CLI exit 1. The marker targets the newest message
found while reading; messages arriving afterward may remain unread
(documented in the docstring and README).
aula mark-read THREAD_ID...marks each thread given and prints one lineper thread (
--output jsongives[{"thread_id": ..., "marked": ...}]).A thread that fails is reported on stderr and does not stop the rest; the
exit code is 1 when any thread was not marked.
Tests:
tests/test_api_client.py, with realHttpResponseobjects so the statuschecks run: marker on the newest message and the request sent; events
skipped; a message found on the second page and on the last permitted one;
page cap exhausted with and without more pages; a deleted and an auto-reply
message; a version bump between the first request and the later ones; a
thread with no message writes nothing; API error inside a 200, malformed
bodies, HTTP 500 and a network error all raise; an unconfirmed marker
raises; nine kinds of missing or wrong mailbox owner are refused.
tests/test_cli.py: several threads, a failing or refused thread followedby a marked one, a thread with nothing to mark (exit code 1), valid JSON on
stdout with the errors on stderr when all, some or none fail, a missing
argument.
ruff format --checkandruff checkclean.
the
aula messages --unreadlist. One of them ends in a recipient-changeevent, and the marker went on the message before it.
Known limits:
code and can still reach stdout under
--output json, as for every othercommand.
is tried and prints no results array.