Skip to content

feat: add Notion notes integration#1032

Open
franktronics wants to merge 1 commit into
backnotprop:mainfrom
franktronics:feat/notion-integration
Open

feat: add Notion notes integration#1032
franktronics wants to merge 1 commit into
backnotprop:mainfrom
franktronics:feat/notion-integration

Conversation

@franktronics

Copy link
Copy Markdown

Summary

Closes #434.

Adds Notion as a fourth note destination alongside Obsidian, Bear, and Octarine. A plan can be saved to Notion on approval, on arrival (auto-save), from the Export > Notes modal, from the header menu, and via the Cmd/Ctrl+S default action.

Each export creates a child page under a chosen parent page (POST /v1/pages), using the plan's first H1 as the title and the plan body as Notion-flavored Markdown.

Authentication

Notion differs from the existing integrations: Obsidian writes a local file, Bear/Octarine open a URI scheme, but Notion needs an authenticated HTTPS API.

To keep this a self-hostable, single-PR feature with no new infrastructure, the integration uses a local Notion integration token read only from NOTION_TOKEN in the server process environment:

  • The token is never stored in cookies, sent from the browser, or included in any API response, snapshot, or log.
  • The UI persists only non-secret settings (enable flag, parent page id/URL, auto-save).
  • It works the same across Claude Code, OpenCode, and Pi as long as the process inherits NOTION_TOKEN.

A public OAuth flow would require a hosted callback, encrypted refresh-token storage, and a client secret that can't ship in a local plugin — that's a separate follow-up, not this PR.

Setup

  1. Create an internal integration (or PAT) in the Notion developer portal, with Insert Content capability.
  2. Share the parent page with that integration.
  3. Start Plannotator with NOTION_TOKEN set.
  4. In Settings > Notion, enable it and paste the parent page URL or ID.

Changes

  • shared: NotionConfig type + optional url on IntegrationResult.
  • server (Bun + Pi): saveToNotion, wired into /api/save-notes and the approve path with the same Promise.allSettled isolation (an integration failure never blocks approval). Both runtimes updated per AGENTS.md.
  • ui: notion settings util, Settings tab, ExportModal card, header menu action, and the three App.tsx export triggers. Duplicate-page gating on approve mirrors Bear (Notion creates a new page per call).
  • tests: Notion request shape + token-safety, dispatcher isolation, and page-id/URL parsing.
  • docs: Notion integration guide + README and API-endpoint updates.

Testing

  • bun test packages/server/integrations.test.ts packages/server/shared-handlers.test.ts packages/ui/utils/notion.test.ts (49 pass)
  • bun run typecheck (all packages, incl. Pi vendoring)
  • bun run --cwd apps/review build and bun run build:hook
  • git diff --check

Notes

  • Scope is a child page under an existing page. Creating rows in a Notion database (data source) has its own schema/field-mapping concerns and is intentionally left as a follow-up.
  • Plannotator-specific Markdown extensions may render with reduced fidelity in Notion; documented in the guide.

Adds Notion as a fourth note destination alongside Obsidian, Bear, and
Octarine. Approved plans (and arrival auto-save, manual export, and the
Cmd/Ctrl+S default action) can create a child page under a chosen Notion
page via POST /v1/pages with the plan title and Notion-flavored Markdown.

The Notion API token is read only from NOTION_TOKEN in the server process
environment. It is never stored in cookies, sent from the browser, or
included in any API response, snapshot, or log. The UI only persists the
non-secret parent page id, enable flag, and auto-save preference.

- shared: NotionConfig type + optional url on IntegrationResult
- server (Bun + Pi): saveToNotion, wired into /api/save-notes and the
  approve path with the same Promise.allSettled isolation
- ui: notion settings util, Settings tab, ExportModal card, header menu
  action, and the three App.tsx export triggers
- tests: Notion request/token-safety, dispatcher, and page-id parsing
- docs: Notion integration guide + README/API endpoint updates

Closes backnotprop#434
@franktronics

Copy link
Copy Markdown
Author

Btw. I'm relatively new to this project. So don't hesitate to let me know if there are any adjustments that need to be made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Notion integration

1 participant