انتقل إلى المحتوى

Notifications and email

Vistilla has two ways of telling people things:

  1. In-app notifications: the activity bell. Always on.
  2. Email: only for messages someone is waiting for, sent immediately.

In-app notifications

Rows in notifications are written when the event happens. For comments, replies and mentions they are part of the same transaction as the comment. resolved and watched notices are written separately; a failed watched notice is only logged and never fails the view.

Kind Written by Sent to
comment a new comment (also from guests on a share link) the video's owner, unless they wrote it
reply a reply the parent comment's author
thread a reply everyone else who has replied in the same thread ("also replied")
mention an @mention the person mentioned; only team or workspace members are accepted
resolved resolving a comment the comment's author; one per comment (resolving again replaces it), and taken back if the comment is reopened before it was read
reaction an emoji reaction on a comment (members; body = the emoji) the comment's author, unless they reacted themselves; one unread notice per person per comment, replaced on a new emoji and removed when the reaction is taken back
video_reaction an emoji reaction on a video (members; body = the emoji) the video's owner, unless they reacted themselves; one unread notice per person per video, replaced on a new emoji and removed when the reaction is taken back
member_joined accepting an invitation whoever sent it
watched a viewer passing 3 seconds, or finishing the video's owner, once per viewer (watched_notices)

For one comment, each person gets at most one notification: a mention, else a reply to them, else a reply in a thread they are in, else a comment on their video. Nobody is told about their own actions.

The bell

The bell shows how many unread notices there are, counting only those whose video and comment still exist: a notice about a deleted comment, or a video in the bin, is neither counted nor listed (and comes back if the video is restored). A notice is read when:

  • it is clicked in the list (website and app);
  • Mark all read is pressed;
  • the video it is about is opened: opening a video marks every notice about its comments read, as they are on the screen. watched notices stay, since who watched is not on that page.

The count is asked for again when the page or app comes back into view, and every minute while it is in view.

  • GET /api/notifications lists them, with the actor's name or the guest's name and the comment text.
  • POST /api/notifications/read marks them read.

Email

Email is sent immediately, while the person waits, by delivery::send_now. It is used for:

Email Subject
Sign-up code 123456 is your Vistilla code
Team invitation {inviter} invited you to {workspace} on Vistilla
Video shared by email {name} shared "{title}" with you
Password reset Reset your Vistilla password

If sending fails, the person is told on the spot. For example, the sign-up page says the code could not be emailed.

The design (mail.rs)

Every email is a Mail { heading, lines, quote, action, code, note }, rendered twice:

  • HTML: a single white card with rounded corners on a soft teal background, everything centred:
    • the Vistilla logo over the card, drawn with table cells and colour to match web/assets/logo.svg (the dark screen with its pale play mark, a border triangle rather than a character a phone would turn into an emoji, and the line of time with its orange knob, on the pale teal tile) rather than as a picture: mail clients hold pictures from an unknown sender back, Gmail among them, and this always shows;
    • a heading and a short line;
    • either one pill-shaped teal button (the bare link is in the plain text twin) or a large code;
    • the small print below the card, and the site's address (Vistilla · …), so the reader knows which instance wrote to them.

The invitation is kept to the essentials: Join {workspace}, who invited them to which team, Accept invitation, and when it expires.

It is built from tables and inline styles, which is what email clients reliably support. - Plain text: the same words, for clients that show no HTML.

Mail transports

The first one configured wins:

  1. SMTP (VISTILLA_SMTP_HOST): through lettre, with STARTTLS by default.
  2. Brevo (VISTILLA_BREVO_API_KEY): Brevo's HTTPS email API, for hosts that block SMTP ports.
  3. Webhook relay (VISTILLA_MAIL_WEBHOOK_URL):

    • Vistilla POSTs {to, subject, text, html, name, secret} as JSON;
    • the relay must answer {"ok": true}.

    scripts/mail-relay.gs is such a relay as a Google Apps Script, which sends from a Gmail account with MailApp.sendEmail (about 100 emails a day on a free account). The hosted instance uses this, and its emails come from vistilla.sylergy@gmail.com.

With no transport configured, nothing is emailed:

  • sign-up codes are written to the server log instead;
  • a password reset tells the person to ask the operator. The operator can run vistilla-api passwd.