Skip to content

Latest commit

 

History

History
471 lines (358 loc) · 30.3 KB

File metadata and controls

471 lines (358 loc) · 30.3 KB

Development Guide — NC Connector for Outlook

This document is a newcomer-friendly guide for building, debugging, and extending NC Connector for Outlook (Outlook classic COM add-in).

Contents

Project purpose

The add-in connects Outlook classic to a Nextcloud server and provides:

  • Nextcloud Talk from calendar appointments (room creation, lobby, participant sync, moderator delegation)
  • Nextcloud sharing from the mail compose window (upload + link share + HTML block insertion)
  • Central backend email signatures for matching Outlook sender accounts
  • Internet Free/Busy (IFB) via a local HTTP endpoint that proxies requests to Nextcloud

Release 3.0.4 delta summary

This release is a targeted safety update for Talk appointment cleanup:

  • Saved appointment deletion no longer deletes remote Talk rooms unless TalkDeleteRoomOnEventDelete or locked backend policy talk_delete_room_on_event_delete explicitly enables it.
  • Runtime subscription detection now requires X-NCTALK-TOKEN; generic Talk URLs in Location or URL fields are not used as a deletion source.
  • Cleanup for newly created appointments that are discarded before saving remains active and separate from the saved-event opt-in.
  • Talk metadata is persisted locally as Outlook X-NCTALK-* UserProperties/MAPI fields. The add-in does not patch server-side calendar .ics objects.

Quick start

Prerequisites

  • Windows 10/11
  • Outlook classic (x64 or x86)
  • .NET Framework 4.7.2 (target framework)
  • MSBuild (e.g. Visual Studio Build Tools)
  • .NET SDK (used by WiX v4 build via dotnet)

Build MSI (recommended)

cd "C:\\path\\to\\nc4ol-3.0.4"

# Optional: reference assemblies (only if needed)
nuget install Microsoft.NETFramework.ReferenceAssemblies.net472 -OutputDirectory packages
$env:FrameworkPathOverride = "$PWD\\packages\\Microsoft.NETFramework.ReferenceAssemblies.net472\\build\\.NETFramework\\v4.7.2"

.\build.ps1 -Configuration Release

If WiX ICE validation is not available on the build host (for example WIX0217 in restricted environments), use:

.\build.ps1 -Configuration Release -SkipIceValidation

Output:

  • dist\\NCConnectorForOutlook-<version>.msi

Install & run locally

  1. Install the MSI (administrator rights required):
    • msiexec /i dist\\NCConnectorForOutlook-<version>.msi
  2. Start Outlook
  3. Ribbon:
    • Calendar/appointment: NC Connector → Insert Talk link
    • Mail compose: NC Connector → Insert Nextcloud share
  4. Open NC Connector → Settings and configure server URL + credentials.

Repository structure

Top-level:

  • src/ — the COM add-in (WinForms UI + service layer)
  • installer/ — WiX v4 MSI project (files + registry + URLACL)
  • docs/ — admin/development documentation
  • VENDOR.md — bundled third-party sanitizer/runtime dependency notices and licenses
  • assets/ — branding images used in README/screenshots
  • dist/ — build output (MSI)

Key code locations:

  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.cs — entry point, ribbon XML, Outlook event wiring, orchestration
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.Lifecycle.cs — add-in bootstrap/teardown lifecycle (OnConnection, shutdown/disconnect)
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.Hooks.cs — dedicated Outlook event hook/unhook wiring helpers
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.Logging.cs — category-specific runtime logging helpers
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.PolicyTemplates.cs — backend policy + Talk template/language resolver helpers
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.SubscriptionEnsure.cs — deferred appointment-subscription ensure and Outlook event-restriction handling
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.MailComposeSubscription.cs — compose subscription core state + lifecycle entry points (Dispose, identity, shared helpers)
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.MailComposeSubscription.AttachmentFlow.cs — compose attachment interception/evaluation/share-launch flow
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.MailComposeSubscription.Signature.cs — backend email-signature policy application for the matching Outlook sender account
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.MailComposeSubscription.SendCleanup.cs — send/close cleanup lifecycle + separate-password dispatch handling
  • src/NcTalkOutlookAddIn/NextcloudTalkAddIn.AppointmentSubscription.cs — appointment runtime subscription lifecycle
  • src/NcTalkOutlookAddIn/Controllers/SettingsWorkflowController.cs — settings open/save/revert orchestration
  • src/NcTalkOutlookAddIn/Controllers/FileLinkLaunchController.cs — FileLink ribbon launch + wizard orchestration
  • src/NcTalkOutlookAddIn/Controllers/TalkRibbonController.cs — Talk ribbon flow orchestration (auth gate, wizard, room create/replace)
  • src/NcTalkOutlookAddIn/Controllers/TalkAppointmentController.cs — appointment lifecycle orchestration for Talk room metadata/sync
  • src/NcTalkOutlookAddIn/Controllers/ComposeShareLifecycleController.cs — compose share cleanup + separate-password dispatch flow
  • src/NcTalkOutlookAddIn/Controllers/EmailSignaturePlainTextController.cs — plain-text compose signature insertion/cleanup through Outlook WordEditor signature bookmarks
  • src/NcTalkOutlookAddIn/Controllers/TalkDescriptionTemplateController.cs — Talk template/body block rendering
  • src/NcTalkOutlookAddIn/Controllers/OutlookRecipientResolverController.cs — SMTP and attendee recipient resolution
  • src/NcTalkOutlookAddIn/Controllers/MailComposeSubscriptionRegistryController.cs — compose-subscription registry lifecycle
  • src/NcTalkOutlookAddIn/Controllers/MailInteropController.cs — shared mail/inspector interop helpers
  • src/NcTalkOutlookAddIn/Models/SeparatePasswordDispatchEntry.cs — shared model for separate password follow-up dispatch queue entries
  • src/NcTalkOutlookAddIn/Services/ — Nextcloud HTTP integrations (Talk, sharing, IFB, login flow)
    • Services/NcHttpClient.cs is the shared request executor for auth headers, OCS headers, timeout/decompression, and optional fresh-connection mode.
    • All runtime HTTP calls (Talk, share/DAV, IFB, login flow, moderator avatar fetch) are routed through NcHttpClient.
    • Services/EmailSignaturePolicyService.cs resolves backend email-signature policy values against local settings and lock state.
  • src/NcTalkOutlookAddIn/UI/ — WinForms dialogs and wizards
    • UI/ScaledForm.cs is the shared DPI-scaling base for forms that use logical pixel layout helpers.
  • src/NcTalkOutlookAddIn/Settings/ — persisted settings model + storage
  • src/NcTalkOutlookAddIn/Utilities/ — logging, theming, i18n, small shared helpers
  • src/NcTalkOutlookAddIn/Utilities/HtmlTemplateSanitizer.cs — centralized sanitizer for backend-provided share/talk HTML templates
  • src/NcTalkOutlookAddIn/Utilities/HtmlToPlainTextConverter.cs — DOM-based HTML-to-plain-text rendering for plain-text email signatures
  • src/NcTalkOutlookAddIn/Utilities/NcJson.cs — centralized JSON payload normalization (PrepareJsonPayload), dictionary/string/int helpers, and OCS error extraction
  • src/NcTalkOutlookAddIn/Utilities/DeferredAppointmentEnsureState.cs — encapsulated pending-key tracking + throttled logging state for deferred appointment ensure
  • src/NcTalkOutlookAddIn/Utilities/PictureConverter.cs — shared Image -> IPictureDisp conversion helper for ribbon icons

Central email signature flow (mail compose)

The compose subscription checks backend policy for the central email signature after a compose window opens and when Outlook changes sender-related properties.

Runtime contract:

  • Backend signature insertion requires an active backend policy for the email_signature domain, an active assigned seat, non-empty policy.email_signature.email_signature_template, and policy.email_signature.user_email.
  • Missing policy.email_signature support disables only central signatures and surfaces a backend update hint; Share/Talk policy domains remain independent.
  • The effective Outlook sender identity must match policy.email_signature.user_email; other identities are left untouched. A SentOnBehalfOfName/From override for shared mailboxes or delegated Exchange identities takes precedence over SendUsingAccount and must resolve to the same SMTP address. If the sender identity cannot be resolved exactly, signature processing fails closed.
  • Local settings EmailSignatureOnCompose, EmailSignatureOnReply, and EmailSignatureOnForward can disable insertion for the corresponding compose type unless the backend locks the value.
  • For HTML/RTF compose, the matching sender account owns the initial signature slot in replies and forwards. Outlook-native or third-party signatures captured at compose open are removed only when the quoted-message boundary is structurally identifiable; otherwise the quoted message and separator are preserved.
  • For plain-text compose, Outlook's body format is preserved. The sanitized backend HTML is rendered to plain text and inserted through Outlook's WordEditor signature slot (_MailAutoSig) or the NC Connector managed Word bookmark. Plain-text processing does not parse reply headers and does not rewrite MailItem.Body.
  • When compose signature policy is inactive or the sender does not match, NC Connector removes only its own marked HTML block or managed plain-text Word bookmark from the current compose item. It does not remove Outlook-native or third-party signature content.
  • Backend signature HTML is sanitized through HtmlTemplateSanitizer with the same fail-closed policy used by sharing and Talk templates.
  • HTML/RTF signatures are written as marked HTML blocks so later policy/sender changes can update or remove only NC Connector-owned content. Plain-text signatures are tracked with the managed Word bookmark for the open compose session.
  • Signature processing only runs for unsent Outlook compose items. Opening a received or already sent message for reading must never modify its body.
  • Inline replies are tracked through Outlook's Explorer.InlineResponse event and written through Explorer.ActiveInlineResponseWordEditor; inspector compose windows use MailItem.HTMLBody for HTML/RTF and WordEditor for plain text. Inline signature insertion uses Outlook's active inline Word selection so quoted content and embedded images are preserved. Inline Word imports use a UTF-8 BOM HTML document so non-ASCII signature text is preserved.
  • The HTML/RTF managed signature replaces the compose signature slot before the quoted message boundary, keeps two empty paragraphs above the signature for the sender's own text, and keeps one empty paragraph between the signature and the reply/forward separator. Text-only header markers such as From: or Von: are never used as raw cut positions.

Architecture

Main building blocks

  • COM add-in lifecycle
    • NextcloudTalkAddIn.OnConnection(...) loads settings, enables logging (optional), initializes IFB, and wires Outlook events.
  • Workflow controllers
    • SettingsWorkflowController, FileLinkLaunchController, and TalkRibbonController own ribbon-triggered UI/runtime workflows.
    • NextcloudTalkAddIn.cs remains the COM/ribbon/event composition root and delegates feature flows to controllers.
    • TalkRibbonController and FileLinkLaunchController prefetch backend policy + password policy in parallel before opening wizards, while still fetching fresh runtime policy data on every entry.
    • Lifecycle, policy/template resolution, and deferred subscription ensure are split into dedicated partial files to keep the root orchestration class maintainable.
  • Service layer
    • Services/TalkService.cs calls the Talk OCS API.
    • Services/FileLinkService.cs uploads via WebDAV and creates shares via OCS.
    • Services/FreeBusyServer.cs hosts the local IFB HTTP endpoint.
    • Services/FreeBusyManager.cs updates Outlook registry keys to point to the local IFB endpoint.
  • UI
    • UI/SettingsForm.cs configures base URL, authentication, sharing defaults, IFB, and debug logging.
    • UI/TalkLinkForm.cs is the Talk wizard.
    • UI/FileLinkWizardForm.cs is the sharing wizard.
    • UI/BrandedHeader.cs is the shared header banner control and provides AttachToParent(...) for consistent form header setup.
    • UI/ScaledForm.cs centralizes ScaleLogical(...) so form-level DPI wrappers are not duplicated.
  • Shared utilities
    • Utilities/BrowserLauncher.cs centralizes shell target starts (URLs, files, directories).
    • Utilities/SizeFormatting.cs centralizes MB display formatting.
    • Utilities/ComInteropScope.cs centralizes COM release/final-release patterns.
    • Utilities/PasswordGenerationHelper.cs centralizes password-policy min-length resolution, server-policy generation fallback, and shared minimum-length validation for Talk/FileLink forms.
    • Utilities/HtmlTemplateSanitizer.cs applies a Thunderbird-aligned HTML policy for backend templates and fails closed if sanitization cannot be applied.

End-to-end flows

Talk link flow (appointments)

  1. User clicks Insert Talk link in an appointment.
  2. UI/TalkLinkForm.cs collects: title, password, lobby, listable flag, room type, participant sync options, optional delegation target.
  3. Controllers/TalkRibbonController.cs prefetches backend policy status and password policy in parallel (Task.WhenAll) before opening the wizard.
  4. Services/TalkService.cs creates the room via OCS.
  5. Controllers/TalkAppointmentController.ApplyRoomToAppointment(...) (invoked by NextcloudTalkAddIn) updates the appointment:
    • Location (Talk URL)
    • a localized plain-text body block (incl. password and help URL)
    • persisted metadata as Outlook UserProperties (including X-NCTALK-* keys)
    • backend-provided custom Talk templates are sanitized before rendering (no raw HTML fallback)
    • talk appointment HTML is passed through an explicit compatibility transform (HtmlTemplateSanitizer.PrepareTalkAppointmentHtmlForOutlookRtfBridge(...)) before insert
    • appointment HTML insert uses the HTML->RTF bridge (MailItem.HTMLBody -> AppointmentItem.RTFBody), not AppointmentItem.HTMLBody and not HTMLEditor.body.innerHTML
  6. A runtime subscription is registered for the appointment (AppointmentSubscription in NextcloudTalkAddIn.AppointmentSubscription.cs):
    • Write (save): updates lobby timer on time changes, updates room description, syncs participants, applies delegation
    • If Outlook exposes the final changed start time only shortly after Write, a short deferred post-write verification retries the lobby update with the newly observed start time on the same opened appointment instead of broad calendar scanning.
    • Close (discard without saving): deletes the room to avoid orphans (best-effort)
    • BeforeDelete: queues room deletion in the background only when saved-event deletion is opted in (TalkDeleteRoomOnEventDelete or locked backend talk_delete_room_on_event_delete) and the appointment has X-NCTALK-TOKEN; URL/location parsing is not a deletion source

Talk appointment-safe HTML subset (backend custom templates)

For stable rendering in Outlook appointment bodies (Word/RTF pipeline), backend Talk templates should stay within this subset:

  • Table-first layout (table, tbody, tr, td) for structure.
  • Inline styles are allowed, but NC Connector strips known Word-unreliable declarations for appointment rendering:
    • display:flex|grid, flex*, grid*, border-radius*, overflow*, object-fit, user-select (vendor-prefixed variants included).
  • Color/alignment fallback is injected automatically during appointment compatibility transform:
    • style=color -> <font color=...>
    • style=background-color -> bgcolor
    • style=text-align -> align
    • style=vertical-align -> valign
  • Anchor color hardening: link color is additionally wrapped as <a><font color=...>...</font></a> where needed.
  • Unsupported/unsafe tags/attributes are still removed by the sanitizer (fail-closed policy).

Sharing flow (mail compose)

  1. User clicks Insert Nextcloud share while composing an email.
  2. UI/FileLinkWizardForm.cs collects sharing settings and the file/folder selection.
  3. Controllers/FileLinkLaunchController.cs prefetches backend policy status and password policy in parallel (Task.WhenAll) before opening the wizard.
  4. Services/FileLinkService.cs performs WebDAV upload, creates the public share via OCS (label on create), then updates mutable metadata like note via the documented OCS update arguments.
    • Files up to 20 MB use a direct WebDAV PUT.
    • Larger files use Nextcloud chunked upload v2 under /remote.php/dav/uploads/<user>/<upload-id> and are assembled with MOVE .file to the final DAV path.
  5. Utilities/FileLinkHtmlBuilder.cs generates the HTML block (header + link + password + permissions + expiration date).
    • backend-provided custom share templates are sanitized via HtmlTemplateSanitizer and fail closed on sanitizer errors.
  6. NextcloudTalkAddIn.InsertHtmlIntoMail(...) inserts the HTML into the message body (delegated to Controllers/MailInteropController.cs).

Compose runtime parity additions in NextcloudTalkAddIn.cs (MailComposeSubscription) with lifecycle logic delegated to Controllers/ComposeShareLifecycleController:

  • Debounced attachment evaluation (ComposeAttachmentEvalDebounceMs) after compose attachment changes.
  • Attachment automation modes:
    • always route attachments into NC sharing flow, or
    • threshold mode with a two-action prompt (Share with NC Connector / Remove last selected attachments).
  • Pre-add attachment interception:
    • BeforeAttachmentAdd path resolves candidate file metadata early
    • can best-effort cancel host attachment add and launch NC sharing before Outlook post-add handling.
    • hard Outlook/Exchange size blocks can still happen before add-in callbacks and are not interceptable via official Outlook OOM events.
  • Runtime host guard checks (live large-attachment setting) at:
    • pre-evaluation
    • pre-prompt-action handling
    • wizard finalize (enforced in UI/FileLinkWizardForm.cs via Services/OutlookAttachmentAutomationGuardService.cs).
  • Attachment-mode wizard launch:
    • removes selected compose attachments
    • queues files as initial wizard selections
    • opens directly in file-step-equivalent mode.
  • UI/FileLinkWizardForm.cs file-step queue accepts Explorer drag & drop for files/folders across queue and action-area controls.
  • Compose share cleanup lifecycle:
    • arm immediately after share creation
    • clear only after successful send
    • delete server folder artifacts on unsent close (with send/close grace timer).
  • Separate password-mail dispatch:
    • queue password-only HTML after share creation
    • capture recipients on send
    • dispatch only after successful primary send
    • auto-send first, then manual fallback draft on failure.

IFB flow

  1. User enables IFB in Settings.
  2. Services/FreeBusyServer.cs starts a local HTTP listener on the configured IFB port (Settings -> IFB -> Local IFB port, default: 7777).
  3. Services/FreeBusyManager.cs updates Outlook registry values so Outlook requests free/busy data via the local endpoint.

Network endpoints

The add-in uses Nextcloud OCS and WebDAV endpoints.

Talk (OCS, selection):

  • Capabilities/version hint: GET /ocs/v2.php/cloud/capabilities
  • Create room: POST /ocs/v2.php/apps/spreed/api/v4/room
  • Delete room: DELETE /ocs/v2.php/apps/spreed/api/v4/room/<token>
  • Lobby timer: PUT /ocs/v2.php/apps/spreed/api/v4/room/<token>/webinar/lobby
  • Listable scope: PUT /ocs/v2.php/apps/spreed/api/v4/room/<token>/listable
  • Description: PUT /ocs/v2.php/apps/spreed/api/v4/room/<token>/description
  • Add participants: POST /ocs/v2.php/apps/spreed/api/v4/room/<token>/participants
  • Get participants: GET /ocs/v2.php/apps/spreed/api/v4/room/<token>/participants?includeStatus=true
  • Promote moderator: POST /ocs/v2.php/apps/spreed/api/v4/room/<token>/moderators
  • Self leave: DELETE /ocs/v2.php/apps/spreed/api/v4/room/<token>/participants/self

Sharing:

  • Create public share: POST /ocs/v2.php/apps/files_sharing/api/v1/shares
  • Upload/folder creation: remote.php/dav/... (WebDAV)
  • Large file upload: MKCOL /remote.php/dav/uploads/<user>/<upload-id>, chunk PUTs, then MOVE /remote.php/dav/uploads/<user>/<upload-id>/.file to the final file path

IFB (DAV via proxy):

  • Local listener: http://127.0.0.1:<ifb-port>/nc-ifb/... (default <ifb-port>=7777)
  • The proxy talks to CalDAV and Addressbook endpoints under remote.php/dav/...

Localization (i18n)

  • Locale files:
    • src/NcTalkOutlookAddIn/Resources/_locales/<lang>/messages.json
  • Runtime loader:
    • src/NcTalkOutlookAddIn/Utilities/Strings.cs

Notes:

  • The default language is German (de).
  • The UI language is derived from Windows UI culture. Some generated text blocks can be overridden via Settings (see “Language overrides”).
  • Placeholders in messages.json use $1, $2, ... and are converted to .NET string.Format placeholders.

See Translations.md for the full language list and maintenance workflow.

Logging

Debug logging is optional and is intended to make support cases reproducible.

  • Enable: Settings → Debug → “Write debug log file”
  • Optional safety control (default on): “Anonymize logs”
  • Daily log file format: %LOCALAPPDATA%\\NC4OL\\addin-runtime.log_YYYYMMDD
  • Runtime exceptions are always written via DiagnosticsLogger.LogException(...), even when debug logging is disabled.
  • Retention: keep latest 7 daily log files and delete files older than 30 days (best effort cleanup).
  • Anonymization redacts configured NC URL/base host, token/password-like values, authorization credentials, user identifiers, email addresses, and local user path fragments before log write.

Format:

  • [YYYY-MM-DD HH:mm:ss.fff] [CATEGORY] Message

Example:

[2026-02-13 03:57:12.345] [TALK] BEGIN CreateRoom
[2026-02-13 03:57:12.910] [TALK] END CreateRoom (565 ms)

Implementation:

  • src/NcTalkOutlookAddIn/Utilities/DiagnosticsLogger.cs
  • src/NcTalkOutlookAddIn/Utilities/LogCategories.cs

Guidelines for new code:

  • Log start/end of network operations (use DiagnosticsLogger.BeginOperation(...)).
  • Log decisions (feature detection, version checks, fallbacks).
  • Log exceptions with context (use DiagnosticsLogger.LogException(...)). LogException(...) bypasses the optional debug switch and must remain the always-on error path.
  • Never swallow exceptions silently.

Compatibility & version checks

Outlook bitness (x86 on x64 Windows)

Outlook can be installed as a 32-bit application on 64-bit Windows. In that case it reads COM add-in registration from the 32-bit registry view (Wow6432Node).

The MSI registers add-in keys for both registry views:

  • 64-bit: HKLM\\Software\\Microsoft\\Office\\Outlook\\Addins\\NcTalkOutlook.AddIn
  • 32-bit: HKLM\\Software\\Wow6432Node\\Microsoft\\Office\\Outlook\\Addins\\NcTalkOutlook.AddIn

Installer definition:

  • installer/Product.wxs

Nextcloud feature detection

Some features depend on server capabilities.

  • Event conversations require Nextcloud >= 31.
  • Version checks and cached “server version hint” live in:
    • src/NcTalkOutlookAddIn/Utilities/NextcloudVersionHelper.cs

UI theming (WinForms)

The add-in uses a dark theme where appropriate so dialogs match dark Outlook setups.

Implementation:

  • src/NcTalkOutlookAddIn/Utilities/UiThemeManager.cs

Detection logic (best-effort):

  1. Try Office/Outlook theme registry values (when available).
  2. Fallback to Windows “app theme” (AppsUseLightTheme).
  3. High contrast mode disables custom theming (system colors win).

Build & release

What build.ps1 does

  1. Builds the COM add-in (NcTalkOutlookAddIn.sln) via MSBuild
  2. Reads the assembly version from NcTalkOutlookAddIn.dll
  3. Builds the WiX v4 installer (installer/NcConnectorOutlookInstaller.wixproj)
  4. Copies the MSI into dist/

Versioning

  • src/NcTalkOutlookAddIn/Properties/AssemblyInfo.cs
    • AssemblyVersion
    • AssemblyFileVersion

build.ps1 derives the MSI ProductVersion from that (format Major.Minor.Build).

Release checklist

  1. Bump version in AssemblyInfo.cs
  2. If vendored dependencies changed: update VENDOR.md
  3. .\build.ps1 -Configuration Release
  4. Install/upgrade MSI test (old version → new version)
  5. Smoke test (Talk + sharing + IFB)
  6. Optional: sign the MSI (if required in your environment)

Local testing

Suggested smoke test sequence:

Note: there is currently no automated test suite in this repository. Use the smoke tests below to validate changes.

  1. Enable debug logging in Settings.
  2. Calendar: create a new appointment, insert a Talk link, save the appointment, then change start time and save again (lobby update).
  3. Calendar: restart Outlook, open the same appointment, change start time and save again (persistent metadata + lobby update).
  4. Calendar: add attendees, save again (participant sync).
  5. Mail: run the sharing wizard, upload 1–2 small files, insert the HTML block, and send to yourself.
  6. IFB: enable IFB, then verify the local endpoint responds:
    • Invoke-WebRequest http://127.0.0.1:<ifb-port>/nc-ifb/ -UseBasicParsing

X-NCTALK-* property reference

The add-in persists Talk appointment metadata as Outlook UserProperties using X-NCTALK-* names only. The old NC Connector-specific Outlook property names are no longer written or read.

Unless stated otherwise:

  • Properties are stored as text values in Outlook (OlUserPropertyType.olText).
  • Boolean values are stored as TRUE / FALSE (uppercase).
  • Timestamps are stored as Unix epoch seconds (UTC) in invariant culture.

Primary write location:

  • src/NcTalkOutlookAddIn/Controllers/TalkAppointmentController.cs -> ApplyRoomToAppointment(...)
  • local Outlook metadata refresh: src/NcTalkOutlookAddIn/Controllers/TalkAppointmentController.cs -> PersistCoreIcalProperties(...)

Properties

Property Purpose Type / format Example Written Read / used Notes
X-NCTALK-TOKEN Talk room token string a1b2c3d4 ApplyRoomToAppointment(...) EnsureSubscriptionForAppointment(...) Required for saved-event room deletion and runtime subscription; generic Talk URLs in Location/URL fields are ignored.
X-NCTALK-URL Talk room URL string https://cloud.example.com/call/a1b2c3d4 ApplyRoomToAppointment(...) RegisterSubscription(...) Stored as local Outlook metadata; not used as a deletion source.
X-NCTALK-LOBBY Lobby enabled flag TRUE / FALSE TRUE ApplyRoomToAppointment(...) EnsureSubscriptionForAppointment(...) Used to decide whether lobby updates run on save.
X-NCTALK-START Appointment start time (epoch seconds) int64 as string 1739750400 ApplyRoomToAppointment(...), AppointmentSubscription.OnWrite(...) GetIcalStartEpochOrNull(...), TryReadAppointmentStartEpoch(...) Local metadata for subscription state; lobby updates use the current save/deferred start epoch directly.
X-NCTALK-EVENT Room creation mode marker event | standard event ApplyRoomToAppointment(...) GetRoomType(...) No legacy Outlook property fallback.
X-NCTALK-OBJECTID Time-window identifier "<start>#<end>" 1739750400#1739754000 ApplyRoomToAppointment(...) (not read by add-in) Stored as local Outlook metadata.
X-NCTALK-ADD-USERS Participant sync: internal users TRUE / FALSE TRUE ApplyRoomToAppointment(...) TrySyncRoomParticipants(...) Split participant sync flag for Nextcloud users.
X-NCTALK-ADD-GUESTS Participant sync: external emails TRUE / FALSE FALSE ApplyRoomToAppointment(...) TrySyncRoomParticipants(...) Split participant sync flag for guests.
X-NCTALK-DELEGATE Delegation target user ID string alice ApplyRoomToAppointment(...) IsDelegatedToOtherUser(...), IsDelegationPending(...), TryApplyDelegation(...) No legacy Outlook property fallback.
X-NCTALK-DELEGATE-NAME Delegation target display name string Alice Example ApplyRoomToAppointment(...) (not read by add-in) Stored as local Outlook metadata.
X-NCTALK-DELEGATED Delegation state marker TRUE / FALSE FALSE ApplyRoomToAppointment(...), TryApplyDelegation(...) IsDelegatedToOtherUser(...), IsDelegationPending(...) Controls whether delegation is still pending.
X-NCTALK-DELEGATE-READY Delegation “ready” marker TRUE TRUE ApplyRoomToAppointment(...) (not read by add-in) Local marker retained for the Outlook delegation contract; the add-in currently uses X-NCTALK-DELEGATED + delegate ID to detect pending delegation.

Extension points

Add a new setting

  1. Add property to src/NcTalkOutlookAddIn/Settings/AddinSettings.cs.
  2. Persist it in src/NcTalkOutlookAddIn/Settings/SettingsStorage.cs.
  3. Add UI in src/NcTalkOutlookAddIn/UI/SettingsForm.cs.
  4. Add translations (see Translations.md).

Add a new Nextcloud API call

  1. Add to the appropriate service:
    • Talk: src/NcTalkOutlookAddIn/Services/TalkService.cs
    • Sharing: src/NcTalkOutlookAddIn/Services/FileLinkService.cs
    • Use Services/NcHttpClient.cs + Utilities/NcJson.cs for new OCS/JSON calls instead of introducing service-local request/parsing helpers.
  2. Add request/response model in src/NcTalkOutlookAddIn/Models/ (if needed).
  3. Add logging scopes and error handling.
  4. Integrate in the UI/wizard and wire it up via NextcloudTalkAddIn.cs.
  5. For ribbon-triggered flows, prefer adding orchestration in the matching controller (SettingsWorkflowController, FileLinkLaunchController, TalkRibbonController) and keep NextcloudTalkAddIn.cs as a thin delegate layer.

Add a new localized string

  1. Add a property to src/NcTalkOutlookAddIn/Utilities/Strings.cs.
  2. Add the key to all locale files under src/NcTalkOutlookAddIn/Resources/_locales/.
  3. Rebuild and verify the UI.