{"id":47883194,"url":"https://github.com/hellfirehd/dkw-onenote-exporter","last_synced_at":"2026-05-07T06:07:19.908Z","repository":{"id":349043108,"uuid":"1200834980","full_name":"hellfirehd/dkw-onenote-exporter","owner":"hellfirehd","description":"Export your Microsoft 365 OneNote notebooks into clean, GitHub‑Flavored Markdown","archived":false,"fork":false,"pushed_at":"2026-04-04T00:05:13.000Z","size":2786,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-04T00:26:15.307Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hellfirehd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-03T22:07:10.000Z","updated_at":"2026-04-04T00:04:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hellfirehd/dkw-onenote-exporter","commit_stats":null,"previous_names":["hellfirehd/dkw-onenote-exporter"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/hellfirehd/dkw-onenote-exporter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellfirehd%2Fdkw-onenote-exporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellfirehd%2Fdkw-onenote-exporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellfirehd%2Fdkw-onenote-exporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellfirehd%2Fdkw-onenote-exporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hellfirehd","download_url":"https://codeload.github.com/hellfirehd/dkw-onenote-exporter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hellfirehd%2Fdkw-onenote-exporter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31384847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T01:22:39.193Z","status":"online","status_checked_at":"2026-04-04T02:00:07.569Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-04T02:01:33.167Z","updated_at":"2026-05-07T06:07:19.902Z","avatar_url":"https://github.com/hellfirehd.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OneNote Markdown Exporter  \n\n\u003c!-- markdownlint-disable MD033 --\u003e\n\u003cp align=\"center\"\u003e\u003cimg src=\"DiggingOut.png\" alt=\"Digging Out\"\u003e\u003c/p\u003e\n\u003c!-- markdownlint-enable MD033 --\u003e\n\nExport your Microsoft 365 OneNote notebooks into clean, GitHub‑Flavored Markdown — with hierarchy, metadata, images, and attachments preserved — using the Microsoft Graph API.\n\nBecause your notes deserve better than being trapped in a proprietary format forever.\n\n---\n\n## 🚀 What This Tool Does\n\n- Authenticates via Microsoft Graph (delegated user auth)  \n- Walks your entire OneNote hierarchy (notebooks → sections → pages)  \n- Downloads page content as HTML  \n- Converts it to GitHub‑Flavored Markdown  \n- Saves images and attachments  \n- Writes YAML front matter for easy static‑site or GitHub‑wiki use  \n- Supports incremental exports so you can run it again without reprocessing everything  \n\nIf you have ever thought, “Why is there no official OneNote export tool?” — this is that tool.\n\n---\n\n## 📦 Prerequisites\n\n- [.NET 8 SDK](https://dotnet.microsoft.com/download)  \n- A Microsoft 365 account with OneNote content  \n- Your OneNote notebooks are synchronized to OneDrive\n- An Azure AD app registration (instructions below)  \n- _(Optional)_ Pandoc [(pandoc.org in Bing)](https://www.bing.com/search?q=\"https%3A%2F%2Fpandoc.org%2Finstalling.html\") if you want the heavyweight HTML→Markdown conversion engine  \n\n---\n\n## 🔐 Azure App Registration\n\n\u003e **Important:** Microsoft removed app‑only authentication for OneNote on **March 31, 2025**.  \n\u003e This tool now uses **delegated** (user) authentication only.\n\nIf that sentence made your eyes glaze over, do not worry — it just means you will be signing in as yourself rather than letting this app impersonate you. Because I do not have a Microsoft Partner Network ID (the thing that makes an app a “Trusted Publisher”), this exporter cannot access anyone’s account except the one you personally authorize.\n\nBy following the steps below, you will create your own Azure app registration and configure it to grant this tool **read‑only access** to your Microsoft account profile — including your OneNote notebooks. In plain English: you stay in control, and the exporter only reads your notes so it can convert them to Markdown. Nothing spooky, nothing shared, nothing written back.\n\n1. Go to  \n   **Azure Portal → App registrations → New registration**\n\n   - **Name:** anything you like (e.g., `OneNote Exporter`)  \n   - **Supported account types:**  \n     _Accounts in any organizational directory and personal Microsoft accounts_  \n   - **Redirect URI:**  \n     - Platform: **Public client / native**  \n     - URI: `http://localhost`\n   - Authentication (Preview) \u003e Settings (Tab)\n       - Enable: Allow public client flows.\n\n2. Copy your:\n \n   - **Application (client) ID**  \n\n3. Add delegated Microsoft Graph permissions:\n\n  | Permission   | Purpose                                               |\n  | ------------ | ----------------------------------------------------- |\n  | `Notes.Read` | Read the signed-in user's OneNote notebooks and pages |\n  | `User.Read`  | Required for delegated sign-in                        |\n\n  - Personal Microsoft accounts: no admin consent needed  \u003c!-- markdownlint-disable-line MD007 --\u003e\n  - Work/school tenants: click **Grant admin consent** if required \u003c!-- markdownlint-disable-line MD007 --\u003e\n\n4. If you are using a personal Microsoft account only, set: \u003c!-- markdownlint-disable-line MD029 --\u003e\n\n   - `TenantId = \"consumers\"`\n\n   Use `\"common\"` only if you intentionally want to support both personal and work accounts.\n\n---\n\n## ⚙️ Configuration\n\n```bash\ncp src/OneNoteMdExport/appsettings.example.json src/OneNoteMdExport/appsettings.json\n```\n\nEdit `appsettings.json`:\n\n```json\n{\n  \"AzureAd\": {\n    \"TenantId\": \"consumers\",\n    \"ClientId\": \"\u003cyour-application-client-id\u003e\",\n    \"RedirectUri\": \"http://localhost\",\n    \"UsePersistentTokenCache\": false\n  },\n  \"Export\": {\n    \"OutputDir\": \"export\",\n    \"UsePandoc\": false,\n    \"PandocPath\": \"pandoc\",\n    \"IncludeImages\": true,\n    \"IncludeAttachments\": true,\n    \"EmitFrontMatter\": true,\n    \"ThrottleRequestsPerMinute\": 100,\n    \"ThrottleRequestsPerHour\": 350,\n    \"ThrottleConcurrentRequests\": 5\n  }\n}\n```\n\n### Notes\n\n- `\"consumers\"` is safest for personal Microsoft accounts  \n- `\"common\"` works for mixed environments\n- `UsePersistentTokenCache = true` lets you reuse tokens across runs (recommended once everything works)\n- The throttle settings default to conservative delegated-auth values with headroom below Microsoft's published OneNote limits\n\n---\n\n## ▶️ Running the Export\n\n```bash\ncd src/OneNoteMdExport\ndotnet run -- --out export\n```\n\nOn first run, a browser window opens for sign‑in.  \nSubsequent requests reuse the in‑memory token cache (or persistent cache if enabled).\n\nA full run log is also written to `\u003coutput-dir\u003e/export.log`. The console shows the message text only, while the log file includes full exception details.\n\n### Throttling\n\nMicrosoft Graph applies general throttling, and OneNote also has service-specific limits. For this exporter's delegated auth flow, Microsoft's published OneNote limits are:\n\n- 120 requests per minute\n- 400 requests per hour\n- 5 concurrent requests\n\nMicrosoft also publishes higher app-only limits for OneNote (240 requests per minute, 800 per hour, and 20 concurrent requests), but this project uses delegated auth only.\n\nThe exporter already retries and paces requests, but large exports can still hit these limits. OneNote resources also do not reliably return a `Retry-After` header on `429 Too Many Requests`, so recovery may require exponential backoff and, in some cases, simply rerunning the export later.\n\n### CLI Options\n\n| Flag                   | Description                                |\n| ---------------------- | ------------------------------------------ |\n| `--out \u003cdir\u003e`          | Output directory (default: `export`)       |\n| `--pandoc`             | Use Pandoc instead of ReverseMarkdown      |\n| `--pandoc-path \u003cpath\u003e` | Path to Pandoc binary                      |\n| `--no-images`          | Skip image download                        |\n| `--no-attachments`     | Skip attachment download                   |\n| `--no-front-matter`    | Omit YAML front matter                     |\n| `--device-code`        | Use device code flow instead of browser    |\n| `--notebook \u003cname\u003e`    | Export only a specific notebook            |\n| `--verbose` / `-v`     | Debug logging                              |\n| `--help` / `-h`        | Show help                                  |\n\n---\n\n## 📁 Output Structure\n\n```text\nexport/\n  Personal Notebook/\n    Quick Notes/\n      Shopping list.md\n      assets/\n        a1b2c3d4.png\n    Work/\n      Meeting notes.md\n  Work Notebook/\n    ...\n  .manifest.json   ← tracks incremental export state\n```\n\nEach Markdown file includes YAML front matter:\n\n```yaml\n---\nonenote_id: \"1-abc123...\"\ntitle: \"Meeting notes\"\ncreated: \"2023-06-01T09:00:00+00:00\"\nmodified: \"2023-06-15T14:30:00+00:00\"\nnotebook: \"Work Notebook\"\nsection: \"Work\"\n---\n```\n\n---\n\n## 🔄 Incremental Exports\n\nRe-running the tool processes only pages whose `lastModifiedDateTime` has changed since the previous run.\n\nState is stored in:\n\n```text\n\u003coutput-dir\u003e/.manifest.json\n```\n\nThis makes the exporter safe to run repeatedly — ideal for large notebooks or slow networks.\n\n---\n\n## 🛠️ Planned Features\n\nThese options are on the roadmap:\n\n- `--list-notebooks` — list notebooks without exporting content\n- `--section \u003cname\u003e` — export only a specific section  \n- `--max-pages \u003cn\u003e` — limit processing for testing or throttling  \n- `--continue-on-error` — keep going even if a page fails  \n- `--skip-missing-pages` — ignore pages that enumerate but return `404`  \n\nIf you want to contribute, PRs are welcome.\n\n---\n\n## 📝 Markdown Conversion Modes\n\n| Mode                          | How                    | When to Use                              |\n| ----------------------------- | ---------------------- | ---------------------------------------- |\n| **ReverseMarkdown** (default) | Built-in NuGet package | Simple, fast, no external dependencies   |\n| **Pandoc**                    | External binary        | Best fidelity; handles tricky HTML cases |\n\nBoth produce GitHub‑Flavored Markdown with tables, fenced code blocks, and task lists. Pandoc is largely untested.\n\n---\n\n## License\n\nMIT - see [LICENSE.md](LICENSE.md)\n\n---\n\n## 🎉 Final Notes\n\nThis project exists because exporting OneNote should not require ritual sacrifice, manual copy‑paste, or a PhD in patience. If this tool saves you even one hour of your life, consider starring the repo — or telling someone else who is trapped in OneNote purgatory.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellfirehd%2Fdkw-onenote-exporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhellfirehd%2Fdkw-onenote-exporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhellfirehd%2Fdkw-onenote-exporter/lists"}