Skip to main content

Mail Integration (Sidebar + Smart Picker)

Standards

  • GEMMA Zaakcorrespondentiecomponent -- Links email correspondence to case objects, supporting the Dutch government standard for case-related communication management.

Status

Implemented -- Backend API endpoints operational, frontend sidebar and smart picker components built, database migration in place.

Overview

The Mail Integration feature connects OpenRegister objects to Nextcloud Mail through two mechanisms:

  1. Mail Sidebar -- A sidebar panel injected into the Nextcloud Mail app that displays OpenRegister objects linked to the currently viewed email. Users can link/unlink objects, discover related objects by sender, and navigate directly to object detail pages.

  2. Smart Picker -- A Nextcloud reference provider that enables rich object references in Mail compose and other apps. Users can search for and embed OpenRegister objects as interactive preview widgets.

Key Capabilities

CapabilityDescription
Link emails to objectsExplicitly associate any email with one or more OpenRegister objects via the sidebar quick-link action. Links are stored in the openregister_email_links table with full metadata (subject, sender, date).
Sender-based discoveryAutomatically suggests objects previously linked to emails from the same sender, surfacing relevant context without manual lookup.
Quick linkOne-click linking from the sidebar: select an object from a search dialog and bind it to the current email.
Rich preview widgetSmart Picker reference provider renders linked objects as interactive cards showing title, schema, register, and a deep link back to the object in OpenRegister.
UnlinkRemove an email-object association via the sidebar or API.
NL Design System themingSidebar and cards use Nextcloud CSS variables, compatible with nldesign token sets (Rijkshuisstijl, Utrecht, etc.).

API Endpoints

MethodEndpointPurposeAuth
GET/api/emails/by-message/{accountId}/{messageId}Retrieve objects linked to a specific emailUser session
GET/api/emails/by-sender?sender={email}Discover objects linked to emails from the same senderUser session
POST/api/emails/quick-linkCreate a new email-to-object link (body: mailAccountId, mailMessageId, objectUuid, registerId)User session
DELETE/api/emails/{linkId}Remove an email-object linkUser session

Architecture

Backend

ComponentPathRole
EmailLink entitylib/Db/EmailLink.phpORM entity for openregister_email_links table
EmailLinkMapperlib/Db/EmailLinkMapper.phpDatabase queries: findByAccountAndMessage, findBySender, findExistingLink
EmailServicelib/Service/EmailService.phpBusiness logic: reverse-lookup, quickLink creation, deleteLink
EmailsControllerlib/Controller/EmailsController.phpREST API controller for all email link endpoints
MailAppScriptListenerlib/Listener/MailAppScriptListener.phpEvent listener that injects the sidebar script into the Mail app

Frontend

ComponentPathRole
mail-sidebar.jssrc/mail-sidebar.jsWebpack entry point, mounts Vue sidebar into Mail DOM
MailSidebar.vuesrc/views/mail/MailSidebar.vueRoot sidebar component with collapsible panel, loading/error states
LinkedObjectsList.vuesrc/components/mail/LinkedObjectsList.vueDisplays explicitly linked objects
SuggestedObjectsList.vuesrc/components/mail/SuggestedObjectsList.vueDisplays sender-based discovery results
ObjectCard.vuesrc/components/mail/ObjectCard.vueCard with title, schema, register, deep link, unlink button
LinkObjectDialog.vuesrc/components/mail/LinkObjectDialog.vueModal for searching and linking objects
useMailObserver.jssrc/composables/useMailObserver.jsObserves Mail app URL changes (hash-based routing)
useEmailLinks.jssrc/composables/useEmailLinks.jsAPI state management with caching and abort control
emailLinks.jssrc/services/emailLinks.jsAxios API wrapper
mail-sidebar.csscss/mail-sidebar.cssNL Design System compatible styles

Database

Table openregister_email_links:

ColumnTypeDescription
idinteger (PK)Auto-increment identifier
mail_account_idintegerNextcloud Mail account ID
mail_message_idintegerMail message ID
mail_message_uidstringMail message UID
subjectstringEmail subject line
senderstringSender email address
mail_datedatetimeEmail date
object_uuidstringLinked OpenRegister object UUID
register_idintegerRegister containing the object
schema_idintegerSchema of the object
linked_bystringUser who created the link
linked_atdatetimeTimestamp of link creation

Indexes: composite on (mail_account_id, mail_message_id), sender, object_uuid. Unique constraint on (mail_account_id, mail_message_id, object_uuid).

Dependencies

  • Nextcloud Mail app -- Required for sidebar injection. OpenRegister functions normally without it; the sidebar simply does not appear.
  • OpenRegister registers/schemas -- At least one register with objects must exist for linking to be useful.

Verification Results (2026-03-25)

EndpointHTTP StatusResponse
GET /api/emails/by-message/1/1200{"results":{"results":[],"total":0},"total":2} -- No links found (expected, clean DB)
GET /api/emails/by-sender?sender=admin@example.com200[] -- No sender matches (expected)
POST /api/emails/quick-link500Internal Server Error -- Expected: no valid object UUID/register exists for dummy test data
DELETE /api/emails/999500Internal Server Error -- Expected: link ID 999 does not exist
Mail app browser testOKMail app loads successfully at /apps/mail/setup (no account configured). Zero console errors.