Third-party integrations primer

  • primer
  • integrations
  • sessionize
  • third-party
  • http-client

The external dependencies this site talks to are, almost entirely, a handful of server-side data feeds that pull content from someone else's API — and the good news is they're all the same shape, so learn one and you can read or add any of them. (There are also a couple of avatar / build-time odds and ends, covered at the end.)

Just want the inventory? Skip to the map.

The server-side feed pattern

Every server-side integration is a Features/<Name>/ module (see the backend primer for why features get their own folder) built from the same four parts:

  1. An options class bound to an appsettings.json section — base URL, cache duration, any keys.
  2. A named HttpClient with a sane timeout and a User-Agent, registered in the feature's composer.
  3. A service that fetches, deserialises, and caches with a stale fallback — so a slow or down upstream degrades to slightly-old data instead of a 500. (That caching shape is question 4 in the caching primer.)
  4. A composer — an Umbraco IComposer, the startup hook where a feature registers its own services (RegisterSessionize, RegisterFeeds) — that wires the three together. AddComposers() discovers it; nothing else has to know the feature exists.

The three feeds:

  • Sessionize (Features/Sessionize/) — conference programme, speakers, and schedule from the Sessionize platform. Config section Sessionize (EventId, BaseUrl, CacheDurationInMinutes); EventId is the one bit you must supply per environment. Unlike the other two, it's surfaced to the browser through /api/sessionize/* endpoints (output-cached with the ExternalApi policy) and rendered by Lit components — so it has a frontend half too. SessionizeApiClient keeps an in-memory cache and an on-disk fallback for when the API is unreachable. This is the most-documented integration: see the Sessionize section of CLAUDE.md for the endpoint and component map.
  • Calendar Feed (Features/Feeds/Calendar/) — community events from umbracalendar.com. Config section CalendarFeed (Url, CacheDurationInMinutes). A public endpoint, no key; CalendarFeedService keeps a 7-day stale copy. Rendered server-side, not exposed as an API.
  • Community Blogs (Features/Feeds/CommunityBlogs/) — aggregated community blog posts from an external community-content aggregation API. The richest of the three: a CommunityBlogsBackgroundService refreshes on an interval (RefreshIntervalInHours), CommunityBlogsApiClient pages through results, and CommunityBlogsImageDownloader pulls featured images on its own HttpClient. Config section CommunityBlogs — note ApiBaseUrl and ApiKey, both secrets with no committed default: set them in appsettings.Local.json (or the Cloud portal). Rendered server-side; caches in memory with a disk copy and a 30-day stale fallback.

Both Calendar and Community Blogs register through one composer, Features/Feeds/Configuration/RegisterFeeds.cs.

Avatars and build-time

Worth knowing they exist, though they're hot-linked CDN/build-time bits rather than configured services:

  • Member/MVP avatars (Features/Mvp/Infrastructure/MvpDataService.cs) — avatars hot-link to GitHub (github.com/{handle}.png) when an MVP has a GitHub handle, falling back to a deterministic DiceBear avatar (api.dicebear.com/.../{seed}) when they don't. No config, no auth — public image URLs.
  • Doc contributors (StaticAssets/devops/generate-doc-contributors.js) — a build-time script that reads git history for the docs and, if a GITHUB_TOKEN is present in CI, resolves commit emails to GitHub accounts for the avatar chips on each rendered doc. Runs in CI, not at request time.

The map

Integration Where Type Config Key/secret?
Sessionize Features/Sessionize/ backend feed + /api/sessionize + Lit Sessionize section EventId per env
Calendar Feed Features/Feeds/Calendar/ backend feed (server-rendered) CalendarFeed section none (public)
Community Blogs Features/Feeds/CommunityBlogs/ backend feed + background service CommunityBlogs section ApiKey (Local/portal)
MVP / contributor avatars Features/Mvp/, devops/ CDN hot-link / build-time none / GITHUB_TOKEN (CI)

What isn't here (so you don't go looking)

The project's top-level description and some older docs mention integrations that aren't in this repo: Matomo, Intercom, and a Google Maps community map were never wired up or have been removed (the @googlemaps/* npm packages linger in package.json but no code uses them), and the GitHub release-tracking feature was extracted into a separate releases site. If you're hunting for any of those here, stop — they live elsewhere or not at all.

Adding a new integration

For anything server-side that calls an external API, follow the feed pattern above rather than inventing a new one: an options class bound to an appsettings section, a named HttpClient with a timeout, a service that caches with a stale fallback, and a composer to wire it up — all under Features/<Name>/. Put secrets in appsettings.Local.json (gitignored), never in the committed config. Promote to a Features/ folder once there's a client + options + service + DTOs that belong together; see the backend primer for the threshold.

Learn the feed shape once and the rest of the server-side integrations read the same. Adding one is mostly a matter of not being clever — copy the pattern, keep the secret out of git, cache with a fallback.