Send Message 1.0.0: one PIN, one place to send from; Slack 1.3.0 and ProdCom 1.4.0 become messaging providers

A new send-message module owns everything a dashboard sends: the PIN
(switchable off in admin), the unlock tokens, the Send message and Quick
replies tiles, the quick replies and quick emojis. It opens no upstream
connection of its own — it finds every module declaring
provides: ["messaging"] through the shell's module list and hands each
message to that module's POST /messaging/send over loopback, so Slack keeps
its one Slack connection and ProdCom its one ProdCom connection. Providers
check the browser's unlock token with GET /verify over loopback before
touching their upstream, so no browser on the network can post as the
location without having entered the PIN here.

Slack 1.3.0 is view-only plus reactions: the Sending group, PIN, send tiles
and quick replies are gone; it serves the messaging descriptor (channels as
recipients) and its reactions ride on the Send Message unlock. A layout's
old Send message / Quick replies tiles draw nothing until removed.

ProdCom 1.4.0 serves the descriptor as identities — only channels with
typingEnabled, since typed text goes out *as* a channel — and posts with
POST /api/v1/channels/{id}/send. Its tile is a click-to-target like Slack's
(accent stripe along the bottom), and typed entries carry a keyboard mark.

The tiles: click any Slack or ProdCom transcript to point sends there; a
Send as menu (only for platforms with identities, hidden otherwise) picks
the ProdCom channel to speak as; the choice is saved with the tile so named
layouts remember it. Wording follows the role — "Send message to #ops…" /
"Send message to ProdCom as FOH…". The PIN pad's dots ride on a real
numeric input so a phone's keyboard appears. Outcome is an icon beside
Send (check / blocked, five seconds, sentence as tooltip). A pill on the
box's bottom edge trades box height for rows of quick-emoji keys, a row
at a time; the single row scrolls sideways on a narrow tile with Send
pinned in place.

The module guide documents the provider contract and the page bus
(window.proddashMessaging + proddash:messaging:* events) the tiles share;
the ProdCom mock gained the send route.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Waters Church
2026-10-05 13:55:55 -04:00
co-authored by Claude Fable 5.1
parent 3b81efcb51
commit 1274360ee6
15 changed files with 3409 additions and 1528 deletions
+47 -22
View File
@@ -318,7 +318,13 @@ below. Nothing is installed without someone clicking.
- **ProdCom** — live transcript stream with in-place updates of in-progress
speech, channel colors, per-tile channel visibility toggles and group
presets, timestamps, text size, a top-down / bottom-up direction toggle
and jump-to-latest in the title bar.
and jump-to-latest in the title bar. Text typed into a channel (from a
dashboard, or ProdCom's own box) is marked with a keyboard; an automation's
with a bolt. The module also offers its channels to **Send Message** as
identities: a click anywhere in the transcript points that module's tiles
at ProdCom (the tile's bottom edge lights up in the accent color), and the
channel the text goes out *as* is picked from their Send as menu — only
channels ProdCom lets text be typed onto are offered.
Admin config: ProdCom server (host : port), API key.
Tile settings: channel icons, direction and timestamps.
- **ProPresenter** — what's live and what's next, with slide progress,
@@ -406,29 +412,47 @@ below. Nothing is installed without someone clicking.
has signed up for are hidden until you ask for them — that list comes from
the service type, since Planning Center only returns a team once somebody
is on it.
- **Slack** — live transcripts of this location's Slack channels, plus
PIN-protected sending as the location. The + picker lists one transcript
tile per configured channel, titled `#channel`, and two send surfaces (one
of each per dashboard): **Send message**, a free-text box with the admin's
quick emojis one press away, and **Quick replies**, a grid of preset
buttons. Both post to the channel of whichever transcript was clicked last
— its bottom edge lights up in the accent color — and to the first
configured channel until one is clicked. Messages arrive with avatars,
names and times, Slack's inline formatting and the workspace's custom
emoji; a right-click on one opens the reaction menu, and text size and
jump-to-latest sit in the title bar. Nothing leaves the machine until the
PIN is entered: one PIN unlocks every Slack tile on that dashboard page
until the auto-lock idles out, a reload asks again, and the lock button on
a send tile's title bar ends it early.
Admin config is in four groups: **Slack account** (the location account's
- **Slack** — live transcripts of this location's Slack channels. The +
picker lists one transcript tile per configured channel, titled
`#channel`. Messages arrive with avatars, names and times, Slack's inline
formatting and the workspace's custom emoji; text size and jump-to-latest
sit in the title bar. Sending is the **Send Message** module's: a click
anywhere in a transcript points its tiles at that channel (the bottom
edge lights up in the accent color), and a message then leaves through
this module's one Slack connection, as the location. A right-click on a
message opens the reaction menu, which rides on the same unlock — with
the page locked, or no Send message tile on it, it says so instead of
reacting. This module has no PIN, send tile or quick replies of its own.
Admin config is in three groups: **Slack account** (the location account's
User OAuth Token — `xoxp-…`, so messages are literally from the campus —
or a bot token plus "Send as"), **Channels** (the joined channels to
follow, one transcript tile each), **Transcript** (refresh interval,
messages kept, thread replies) and **Sending** (the switch on the group's
title row, a 4–8 digit PIN, auto-lock minutes, quick replies one per line
as `Label | Message` — add `| #channel` to bind one to a channel — and up
to eight quick emojis).
follow, one transcript tile and one Send Message destination each) and
**Transcript** (refresh interval, messages kept, thread replies).
Tile settings: avatars, timestamps, names and channel notices.
- **Send Message** — the one place a dashboard sends from, whatever the
platform. Two tiles, one of each per dashboard: **Send message**, a
free-text box with the admin's quick emojis one press away, and **Quick
replies**, a grid of preset buttons. Both go wherever the operator last
pointed them with a click on a Slack or ProdCom transcript. A platform
whose destinations are identities rather than recipients — ProdCom, where
typed text goes out *as* a channel — also gets a **Send as** menu in the
title bar listing those identities; the menu exists only while such a
platform is installed, and Slack's channels are never in it. The choice is
saved with the tile, so a named layout remembers it; the transcript it
points at carries the accent stripe. The module
owns no connection of its own — it finds every installed module that
offers messaging and hands the message to it over loopback — and it owns
the PIN: nothing leaves the machine until it is entered on one of its
tiles, one entry unlocks every messaging tile on that dashboard page
(Slack's reaction menu included) until the auto-lock idles out, a reload
asks again, and the lock button ends it early. The PIN pad takes taps, a
keyboard, or a phone's — tapping the dots raises it. The PIN can be
switched off for a booth that doesn't need one.
Admin config: **PIN** (the switch on the group's title row, 4–8 digits,
auto-lock minutes) and **Presets** (quick replies one per line as
`Label | Message` — add `| slack:#channel` or `| prodcom:Channel` to bind
one to a destination — and up to eight quick emojis).
Tile settings: quick emojis on the Send message tile.
- **Resi Cues** — how long until the next Resi cue point, for a campus
running video from another site. The tile is one number, as large as it
will go: the countdown to the next cue, its name above it, and the playhead
@@ -484,7 +508,8 @@ below. Nothing is installed without someone clicking.
reference for module authors.
To develop modules against mocks instead of real gear:
`node tools/prodcom-mock.js` (ProdCom on `127.0.0.1:24480`),
`node tools/prodcom-mock.js` (ProdCom on `127.0.0.1:24480`, including the
send route the Send Message module uses),
`node band-lineup-display/tmp/pp-mock.js 1599` (ProPresenter slides on
`127.0.0.1:1599`), `node tools/pp-timers-mock.js 1600` (ProPresenter
timers + timecode on `127.0.0.1:1600`), `node tools/pco-mock.js`