Nojoin Calendar Guide
Nojoin supports Google Calendar and Microsoft Outlook calendar integration for dashboard month and agenda views.
This guide covers both sides of the feature:
- Admin and owner setup of the installation OAuth credentials.
- End-user connection of their own calendar accounts.
- Dashboard behaviour, colours, links, and troubleshooting.
Overview
Calendar integration has two distinct layers:
- The installation must be configured with Google and/or Microsoft OAuth credentials.
- Individual users then connect their own accounts and choose which calendars to sync.
Users do not enter OAuth client IDs, client secrets, or tenant IDs themselves.
Before You Begin
- Use a stable HTTPS browser origin whenever possible.
- Set
WEB_APP_URLto the exact public browser origin used to access Nojoin. - Set a stable
DATA_ENCRYPTION_KEYbefore storing provider secrets or connecting user calendars. - If you deploy behind a reverse proxy, make sure the browser origin and provider callback origin are identical.
For the full hosting context, see DEPLOYMENT.md.
Admin Configuration Options
You can provide the installation OAuth credentials in either of these ways:
- Preferred: sign in as an Owner or Admin and save them in Settings > Administration > Calendar providers.
- Alternative: set the matching environment variables and restart the stack.
Supported environment variables:
WEB_APP_URLDATA_ENCRYPTION_KEYGOOGLE_OAUTH_CLIENT_IDGOOGLE_OAUTH_CLIENT_SECRETMICROSOFT_OAUTH_CLIENT_IDMICROSOFT_OAUTH_CLIENT_SECRETMICROSOFT_OAUTH_TENANT_ID
DATA_ENCRYPTION_KEY is not an OAuth credential, but it is what keeps stored calendar provider secrets and user calendar tokens readable across upgrades and infrastructure changes. Earlier v0.8.1 deployments could rely only on the generated key file, which was an operational oversight for installations where the app data directory and database might be managed separately.
End-User Connection Flow
Once the installation credentials exist:
- Open Settings > Personal and go to Calendar Connections.
- Choose Connect Gmail Calendar or Connect Outlook Calendar.
- Complete the provider sign-in and consent flow.
- Return to Nojoin and choose which calendars to sync.
- Optionally apply per-calendar colour overrides.
Connected calendars then feed the dashboard month view, agenda view, and next-event surface. Unlinked Nojoin recordings also appear on the dashboard calendar as first-class historical items.
Dashboard Behaviour
When calendar sync is configured:
- The dashboard month view shows dots on days with synced events and on days that contain unlinked Nojoin recordings.
- Unlinked Nojoin recordings use the Nojoin orange accent so they remain visually distinct from Google or Microsoft calendar sources.
- The agenda view is month-scoped and shows both calendar events and unlinked historical recordings for the viewed month.
- In the current month, the agenda lists upcoming items first and collapses past items behind a
Show past eventscontrol; past months render fully expanded. - Selecting a day in month view opens a day agenda, and selecting today shows a live now marker against timed events.
- Clicking a timed event on the day timeline opens a details popover with the full event metadata, join link, and linked recordings; live events additionally show a
Joinbutton on the bubble. - Timeline bubbles size their metadata to the event duration: shorter events show fewer detail rows, and events spanning midnight are marked with dashed edges and chevrons.
- The
Todayaction jumps back to the current month and date context. - Per-calendar colours can be used so different sources remain visually distinct.
- Event times render in the user’s configured Nojoin timezone.
- Meeting links and supported online meeting URLs surface from agenda items as compact
Join meetinglabels showing the provider host instead of the raw URL.
When no calendar is connected and there are no unlinked recordings in view, the dashboard deliberately shows an honest empty state rather than mock data.
Synced calendar events also store their description and attendee list, and recordings carry a nullable calendar_event_id so a recording can be linked to the calendar event it belongs to (see Meeting Intelligence in USAGE.md). When a recording is linked, the dashboard suppresses the standalone Nojoin meeting item and shows only the calendar event.
Sync Frequency and Live Sync
Nojoin keeps connected calendars up to date in two complementary ways.
- Scheduled sync (always on): A background scheduler refreshes every connected account that has at least one selected calendar every 15 minutes. Sync is incremental, using each provider’s change cursor (Google
syncToken, Microsoft Graphdelta), so only changes since the last run are fetched. This runs entirely on the worker and needs no inbound network access. - Live sync (optional push notifications): When enabled and supported, Nojoin registers a per-calendar push subscription with the provider so changes arrive by webhook within seconds instead of waiting for the next 15-minute cycle. Scheduled sync keeps running as a safety net, so calendars stay correct even if a push subscription lapses.
You can also trigger an immediate refresh at any time with the Sync now action on a connected account.
Enabling Live Sync
Live sync is off by default and is enabled per provider by an Owner or Admin in Settings > Administration > Calendar providers.
Requirements:
- The installation must be reachable from the public internet over HTTPS at the exact
WEB_APP_URLorigin. Localhost or LAN-only deployments cannot receive provider webhooks and should rely on scheduled sync. - For Google, the webhook domain must be verified in the Google Cloud project, because Google only delivers push notifications to verified domains.
- For Microsoft, no extra verification is needed; Microsoft validates the webhook automatically when the subscription is created.
When live sync is active for a connected account, that account shows a Live indicator in Settings > Personal > Calendar Connections. If a subscription cannot be created (for example, the instance is not publicly reachable, or the Google domain is unverified), Nojoin records the failure and continues with scheduled sync; no data is lost.
Nojoin exposes these webhook endpoints for the providers to call:
- Google:
<public-origin>/api/v1/calendar/webhooks/google - Microsoft:
<public-origin>/api/v1/calendar/webhooks/microsoft
Google OAuth Setup
- Open Google Cloud Console and create or select the project you want to use.
- Enable the Google Calendar API.
- Configure the OAuth consent screen.
- Add the scopes used by Nojoin:
openidemailprofilehttps://www.googleapis.com/auth/calendar.readonly
- If the app remains in testing mode, add every Google account that needs access as a test user.
- Create an OAuth client ID of type Web application.
-
Add this redirect URI exactly:
<public-origin>/api/v1/calendar/oauth/google/callback - Save the client.
- Enter the generated client ID and client secret into Nojoin Admin Calendar settings or the matching environment variables.
- Optional, for Live Sync only: verify the Nojoin public domain under the project’s Domain verification settings so Google will deliver calendar push notifications to
<public-origin>/api/v1/calendar/webhooks/google. Scheduled 15-minute sync works without this step.
Microsoft OAuth Setup
Microsoft setup is slightly more sensitive because tenant choice affects which accounts can sign in.
Supported Account Type
- In the current Entra registration UI, use Any Entra ID Tenant + Personal Microsoft Accounts if you want both Microsoft 365 work or school accounts and personal Outlook.com or Hotmail accounts.
- Older Microsoft documentation may describe this same choice using different wording, but in the current interface the label to look for is Any Entra ID Tenant + Personal Microsoft Accounts.
- Use Accounts in this organisational directory only only if you deliberately want a single-tenant work or school deployment.
Registration Steps
- Open Microsoft Entra admin centre.
- Go to Identity > Applications > App registrations.
- Create a new registration.
- Choose the supported account type that matches your intended users. For mixed Microsoft 365 and personal Microsoft account support, select Any Entra ID Tenant + Personal Microsoft Accounts.
-
Add this redirect URI as a Web platform redirect:
<public-origin>/api/v1/calendar/oauth/microsoft/callback - Copy the Application (client) ID.
- If the app is single-tenant, also copy the Directory (tenant) ID.
- Open API permissions and add delegated permissions for:
openidprofileemailoffline_accessUser.ReadCalendars.Read
- Do not add application permissions for this user-consent flow.
- Open Certificates & secrets and create a client secret.
- Copy the secret Value immediately. Do not use the Secret ID.
- Save the values into Nojoin Admin Calendar settings or the matching environment variables.
- Live Sync needs no extra Microsoft setup: the existing
Calendars.Readpermission covers change-notification subscriptions, and Microsoft validates the webhook automatically. It still requires Nojoin to be publicly reachable over HTTPS atWEB_APP_URL.
Tenant Selection Rules
- Use
commononly when the app registration supports both organisational directories and personal Microsoft accounts. - If the app is single-tenant, use the explicit tenant ID instead of
common. - If the app is meant to support personal Microsoft accounts but Nojoin is pointed at a specific tenant GUID, sign-in may succeed while the first calendar read still fails. In that case, switch back to
common, save, disconnect the failed connection, and reconnect it.
Verification Checklist
After setup:
- Sign in as a normal user.
- Connect Google or Microsoft from Settings > Personal > Calendar Connections.
- Approve the provider consent flow.
- Select one or more calendars.
- Confirm the dashboard shows calendar markers, agenda items, and next-event data.
Troubleshooting
Redirect Origin Is Wrong
- Confirm
WEB_APP_URLmatches the exact browser origin users open. - Confirm the provider registration uses the same callback origin.
AADSTS50194 with Microsoft
Your Microsoft app is still single-tenant while Nojoin is using common.
Fix one of these:
- Change the app registration to Any Entra ID Tenant + Personal Microsoft Accounts.
- Or set Nojoin to the explicit tenant ID instead of
common.
Microsoft Sign-In Works but Calendar Sync Still Fails
If you intend to support personal Microsoft accounts or mixed account types, confirm Nojoin is using common, then disconnect and reconnect the Outlook calendar connection.
invalid_client During Token Exchange
Make sure Nojoin stores the client secret Value, not the Secret ID.
Admin Approval Message in Microsoft
The delegated permissions exist, but the tenant blocks user consent. A tenant administrator must grant consent.
Google Testing Mode Blocks a User
If the Google app is still in testing mode, that Google account must be listed as a test user until the consent screen is published.
Live Sync Not Activating
If a connected account never shows the Live indicator:
- Confirm the provider’s push toggle is enabled in Settings > Administration > Calendar providers.
- Confirm Nojoin is reachable from the public internet over HTTPS at exactly
WEB_APP_URL. Localhost or LAN-only deployments cannot receive webhooks; scheduled 15-minute sync still works. - For Google, confirm the webhook domain is verified in the Google Cloud project.
- Confirm a reverse proxy or tunnel forwards
POSTrequests to/api/v1/calendar/webhooks/googleand/api/v1/calendar/webhooks/microsoftand preserves theHostheader.
Live sync is an accelerator only. When it cannot be established, calendars still refresh on the 15-minute schedule.