propresenter-php/doc/api/messages.md
Thorsten Bus 9e3e719806 feat(library): add readers + writers for all ProPresenter global libraries and theme bundles
Add full IO support for every global ProPresenter library file plus
theme folders, and extend the existing Labels/Macros readers with
exporters and editable accessors so every supported document is now a
round-trippable, mutable object.

New library readers/writers (each: FileReader, FileWriter, Library
wrapper, element wrapper where applicable, CLI tool, tests, doc/api/*.md):

- Groups          (ProGroupsDocument)        + GroupDefinition
- ClearGroups     (ClearGroupsDocument)      + ClearGroupDefinition
- CCLI            (CCLIDocument)
- Messages        (MessageDocument)          + Message
- Timers          (TimersDocument + Clock)   + Timer
- Stage           (Stage.Document)           + StageLayout
- Workspace       (ProPresenterWorkspace)    + Screen
- Props           (PropDocument)             + Prop
- TestPatterns    (TestPatternDocument)
- Calendar        (new CalendarDocument)     + CalendarEvent
- KeyMappings     (new KeyMappingsDocument)  + KeyMapping
- CommunicationDevices (JSON file)           + CommunicationDevice
- Theme bundles   (Template.Document folder + Assets/) + ThemeBundle/Slide/Asset

Extensions to existing modules:

- LabelsFileWriter; Label and LabelLibrary gain setters, addLabel,
  removeLabel, setColor / setColorHex helpers
- MacrosFileWriter; Macro/MacroCollection/MacroLibrary gain UUID, name,
  color, image_type, image_data, trigger_on_startup setters plus
  add/remove for macros and collections

Two new minimal proto schemas were defined for documents that lacked
upstream definitions:

- proto/calendar.proto   - CalendarDocument with Event entries, raw
  bytes for the action/macro sub-messages so the schema can evolve
- proto/keyMappings.proto - KeyMappingsDocument with ApplicationInfo
  and a forward-looking Mapping message (sample only carries the info)

The Theme file turned out to be a regular Rv\Data\Template\Document, so
no new proto was required for theme content; ThemeBundle layers folder
+ Assets/ handling on top in the same spirit as PresentationBundle.

GroupDefinition is intentionally distinct from the existing Group class
(which wraps song-level CueGroup) to avoid breaking song APIs.

Verified with the full PHPUnit suite: 370 tests, 9200 assertions, all
green; LSP diagnostics clean across src/. The unmodified reference
samples for Labels, Groups, ClearGroups, TestPatterns, Calendar and
KeyMappings round-trip byte-for-byte; the others round-trip with the
same byte length (PHP protobuf is not canonically deterministic but
re-write-after-write stabilises).

doc/INDEX.md, doc/keywords.md and AGENTS.md updated so every new module
is discoverable from the top level.
2026-05-03 21:40:09 +02:00

2.8 KiB

Messages Library API

PHP module for reading and writing the global ProPresenter Messages file (raw protobuf, no extension) and exposing each message definition.

Quick Reference

use ProPresenter\Parser\MessagesFileReader;
use ProPresenter\Parser\MessagesFileWriter;

$library = MessagesFileReader::read('/path/to/Messages');

foreach ($library->getMessages() as $message) {
    $message->getTitle();
    $message->getUuid();
    $message->getMessageText();
}

$library->addMessage('Lobby Notice', '11111111-1111-1111-1111-111111111111');
MessagesFileWriter::write($library, '/path/to/Messages');

File Layout

The Messages file is the protobuf-serialised MessageDocument:

Field Type Description
application_info ApplicationInfo ProPresenter metadata
messages repeated Message Message definitions in document order

Reading

$library = MessagesFileReader::read('/Users/me/.../Messages');

Throws InvalidArgumentException for missing files and RuntimeException for empty / unreadable files.


MessageLibrary

$library->getMessages();                    // Message[]
$library->count();                          // int
$library->getMessageByUuid($uuid);          // ?Message (case-insensitive)
$library->getMessageByName($title);         // ?Message (case-sensitive title)
$library->addMessage($title, $uuid);        // Message
$library->removeMessage($uuid);             // bool
$library->getApplicationInfo();             // ?\Rv\Data\ApplicationInfo
$library->getDocument();                    // \Rv\Data\MessageDocument

Message

$message->getUuid();
$message->setUuid($uuid);
$message->getTitle();
$message->setTitle($title);
$message->getTimeToRemove();
$message->setTimeToRemove($seconds);
$message->isVisibleOnNetwork();
$message->setVisibleOnNetwork(true);
$message->getMessageText();
$message->setMessageText($text);
$message->getClearType();
$message->setClearType($enumValue);
$message->getTokens();      // raw repeated Token protos
$message->getProto();       // \Rv\Data\Message

CLI Tool

php bin/parse-messages.php /path/to/Messages

Key Files

File Purpose
src/MessageLibrary.php Document wrapper with title / UUID indexes
src/Message.php Single message wrapper
src/MessagesFileReader.php Reads the Messages file
src/MessagesFileWriter.php Writes the Messages file
bin/parse-messages.php CLI summary tool
generated/Rv/Data/MessageDocument.php Generated document class

Scope Notes

Tokens and token values are preserved as raw generated protobuf objects. The wrapper exposes them for advanced callers but does not interpret template rendering semantics.