hifengzy45 downloadsImport Tencent IMA knowledge base and notes, automatically convert to Markdown.
One-way sync your Tencent IMA knowledge base and notes into Obsidian: web clippings auto-converted to Markdown, images downloaded locally, file attachments (PDF/Word/PPT) saved as-is, all with frontmatter metadata for offline search.
Notes/ subfolder, toggleable on/off..md stub for searchability.per-kb or Obsidian global setting), links rewritten to ![[local-file]] wikilinks.doc_id as primary key. Standalone notes compared by modify_time; wiki items use "skip if exists" strategy (API limitation). Clear cache to trigger full re-sync.title / created / source / tags to each document. User-added properties preserved on update.ima.qq.com exclusively.main.js, manifest.json, styles.css from the latest Release..obsidian/plugins/ima-sync/ in your vault.git clone https://github.com/hifengzy/ima-sync.git
cd ima-sync
npm install
npm run build # produces main.js
Copy main.js, manifest.json, styles.css into .obsidian/plugins/ima-sync/ and enable.
ima or A/B).per-kb (inside each KB folder) or obsidian-global (inherit Obsidian's global setting).<vault>/
└── ima/ # sync root (user-configured)
├── KB-A/ # each knowledge base as a folder
│ ├── article-1.md
│ ├── subfolder/ # mirrors IMA folder hierarchy
│ │ └── article-2.md
│ ├── report.pdf
│ ├── report.md # stub for file attachments
│ └── attachments/ # per-kb attachment mode
│ └── doc123-1.png
├── KB-B/
│ └── ...
└── Notes/ # when notes sync is enabled
├── note-1.md
└── ...
| Content Type | Handling |
|---|---|
| KB Notes | Fetch body → Markdown conversion → image localization |
| Web Articles / Links | Download HTML → extract body → Markdown conversion → image localization; graceful degradation on failure |
| Files (PDF/Word/PPT/Excel/images) | Download original + generate .md stub with metadata and file link |
| Standalone Notes | list_note_by_folder_id → get_doc_content → Markdown conversion |
| Folders | Recursively traverse sub-levels, mirror locally |
Incremental sync: standalone notes compared by modify_time; wiki items use "skip if exists" due to API not returning update_time. Deletion is conservative — files removed on IMA are kept locally. To rebuild from scratch, clear the cache and sync again.
RateLimiter).REQUEST_TIMEOUT_MS).npm run dev # watch mode with sourcemaps
npm run build # type-check + production build
npm run typecheck # type-check only
# verification tests
npm run verify:frontmatter
npm run verify:quota
npm run verify:naming
npm run verify:unit
npm run verify:constants
npm run verify:normalize
npm run verify:images
npm run verify:clear
# E2E smoke test (requires real API credentials)
npm run test:build
IMA_CLIENT_ID=xxx IMA_API_KEY=xxx npm test
src/
├── api/ # IMA OpenAPI client
│ ├── imaClient.ts # auth, throttling, retry, fetchUrl
│ ├── endpoints.ts # pagination and recursive traversal
│ ├── errors.ts # tiered errors (fatal / retryable / quota)
│ └── types.ts # API data types
├── sync/ # sync engine
│ ├── SyncManager.ts # core orchestration
│ ├── SyncIndex.ts # local sync index (doc_id → metadata)
│ └── SyncState.ts # mutex lock
├── transform/ # content conversion
│ ├── htmlToMarkdown.ts
│ ├── frontmatter.ts # properties construction and writing
│ ├── imageDownloader.ts
│ ├── fileDownloader.ts
│ ├── webArticle.ts # web page body extraction
│ └── imageNaming.ts
├── ui/ # UI components
│ ├── KbPickerModal.ts # knowledge base picker (fuzzy search)
│ ├── ConfirmModal.ts # confirmation dialog
│ └── ProgressNotice.ts # progress and summary notices
├── settings/ # settings
│ ├── types.ts # config types and defaults
│ └── SettingTab.ts # settings UI
├── utils/ # utilities
│ ├── path.ts # path, filename sanitization, attachment dir
│ ├── rateLimiter.ts # 2 QPS throttling
│ └── logger.ts # console wrapper with [imasync] prefix
├── main.ts # plugin entry: lifecycle, commands, ribbon, scheduler
└── constants.ts # URLs, enums, defaults
data.json (excluded from git).https://ima.qq.com.MIT © hifengzy