fix: skip matrix avatar upload when icon unchanged

matrix-avatar-sync ran on every boot (RemainAfterExit=false + path
trigger), uploading a fresh PNG each time. Every upload mints a new
mxc:// URI, which triggers a profile state event in every joined room
— resulting in timeline spam even when the avatar hasn't changed.

Fix: before uploading, compute sha256sum of /etc/hyperhive/icon.svg
and compare against the last-synced hash stored in
$HYPERHIVE_STATE_DIR/matrix-avatar-icon-hash. Skip the upload if the
hash matches. Write the hash after a successful avatar_url PUT so
subsequent boots are no-ops until the icon file changes.

Hash file lives in the agent's state dir — survives restart, cleared
on purge (so purge + re-provision gets a fresh upload). Delete to force
re-upload manually.

Closes #1231
This commit is contained in:
atlas 2026-06-03 23:21:14 +02:00 committed by mara
commit 644519f358

View file

@ -1246,6 +1246,20 @@ in
echo "matrix-avatar-sync: no matrix-token at $TOKEN_FILE; skipping"
exit 0
fi
# Hash-based idempotency: skip the upload if the icon hasn't
# changed since the last successful sync. Every upload mints a
# new mxc:// URI which triggers a profile state event in every
# joined room — uploading the same bytes again produces timeline
# spam without changing the visible avatar. The hash file lives
# in $HYPERHIVE_STATE_DIR (survives restart, wiped on purge so
# purge + re-provision gets a fresh upload). Delete to force
# re-upload.
HASH_FILE="$HYPERHIVE_STATE_DIR/matrix-avatar-icon-hash"
CURRENT_HASH=$(sha256sum "$ICON" | cut -d' ' -f1)
if [ -f "$HASH_FILE" ] && [ "$(cat "$HASH_FILE" 2>/dev/null)" = "$CURRENT_HASH" ]; then
echo "matrix-avatar-sync: icon unchanged (hash matches); skipping"
exit 0
fi
TOKEN=$(cat "$TOKEN_FILE")
# Local tuwunel reachable on shared host netns at the
# default matrix-spec port. Override via
@ -1293,6 +1307,9 @@ in
-o /dev/null -w "%{http_code}" 2>/dev/null || true)
if [ "$CODE" = "200" ]; then
echo "matrix-avatar-sync: avatar set on $USER_ID"
# Persist hash so subsequent runs skip the upload when the
# icon hasn't changed.
echo "$CURRENT_HASH" > "$HASH_FILE"
else
echo "matrix-avatar-sync: avatar PUT returned HTTP $CODE skipping (non-fatal)"
fi