Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mattermost Viewer Avatars

Read receipts that feel like people, not surveillance.

Latest release CI License

See who has actually seen your Mattermost message—at a glance. Tiny viewer avatars appear naturally beneath your post and update live as teammates read it. Hover over them for the full list, names, and viewing times.

No noisy checkmarks. No text being covered. Just a quiet, human answer to: “Has anyone seen this yet?”

Viewer Avatars in Mattermost

What it feels like

  • Alive: avatars appear in real time while the conversation is open.
  • Compact: up to 10 tiny faces stay beside the message; a small + shows when more viewers are available.
  • Useful on hover: see larger avatars, names, and the time each person first viewed the post.
  • Out of the way: receipts sit after the message instead of covering its first characters.
  • Works where you talk: channels, direct messages, grouped posts, and the right-hand thread sidebar are supported.

Nothing appears until another person views your message, and you are never counted as a viewer of your own post.

Install in a minute

  1. Download the plugin archive from the latest release. Choose the asset named com.github.core3750x.viewer-avatars-*.tar.gz—not GitHub's source-code archives.
  2. Open System Console → Plugin Management in Mattermost.
  3. Upload the archive and enable Viewer Avatars.
  4. Hard-refresh any open Mattermost tabs.

That is it. Mattermost 9.1 or newer is required. By default, receipts expire after 90 days; an administrator can change the retention period under System Console → Plugins → Viewer Avatars.

Privacy by design

Viewer Avatars is deliberately stricter than a simple “page was open” signal:

  • a view counts only when at least 55% of the post is visible in the foreground browser tab;
  • only channel members can record a view;
  • only the post author can request that post's viewer list;
  • live updates are delivered only to the author's Mattermost sessions;
  • receipt data is deleted together with the post;
  • receipt data expires automatically after the configured retention period;
  • the normal message view loads at most 10 viewer IDs and profiles per post;
  • larger viewer lists are loaded in pages only while their popover is open.

The plugin stores only the viewer's Mattermost user ID and first-view timestamp in Mattermost's own plugin KV store. It has no external service, analytics, or third-party tracking.

Development and architecture

Requirements

  • Go 1.23.9 or newer
  • Node.js 20 or newer
  • npm

Run the checks

go test ./...
npm --prefix webapp ci
npm --prefix webapp test
npm --prefix webapp run typecheck
npm --prefix webapp run build

Build an installable bundle

./scripts/build.sh

The multi-platform archive is written to dist/.

The server exposes authenticated batch endpoints for recording views and loading viewer summaries and pages. Posts with up to 10 viewers occupy one KV entry. Larger receipts are promoted into 32 deterministic, sparse shards. Writes are coalesced briefly, deduplicated, and stored with atomic compare-and-set plus expiry, reducing hot-key contention in a high-availability Mattermost deployment.

The webapp observes rendered posts with IntersectionObserver, reads Mattermost's Redux state for post and profile metadata, and mounts avatar stacks through React portals. Its post caches are bounded, WebSocket events contain only the new viewer, and the full popover list is paginated and virtualized. Closing the popover releases the loaded pages and profiles.

License

Apache License 2.0

About

Live read receipts for Mattermost, shown as viewer avatars beneath each message.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages