From 9a018c4494ff6efceb987194ab5545b8384fa17f Mon Sep 17 00:00:00 2001 From: huojl Date: Wed, 6 May 2026 14:27:15 +0800 Subject: [PATCH] first commit --- manifest.json | 8 +- package.json | 6 +- release/obsidian-plugin.html | 252 +++++++++++++++++++++++++++++++++++ release/sonicnote-sync.zip | Bin 0 -> 4936 bytes src/api.ts | 39 ++++-- src/formatter.ts | 2 +- src/main.ts | 42 +++--- src/settings.ts | 47 +++---- src/sync.ts | 16 +-- src/types.ts | 8 +- styles.css | 6 +- 11 files changed, 339 insertions(+), 87 deletions(-) create mode 100644 release/obsidian-plugin.html create mode 100644 release/sonicnote-sync.zip diff --git a/manifest.json b/manifest.json index 86df8e0..645157d 100644 --- a/manifest.json +++ b/manifest.json @@ -1,9 +1,9 @@ { - "id": "znote-sync", - "name": "Znote Sync", + "id": "sonicnote-sync", + "name": "SonicNote Sync", "version": "1.0.0", "minAppVersion": "0.15.0", - "description": "Sync recordings from Znote (SonicNote) to Obsidian as Markdown files", - "author": "EasyLink", + "description": "Sync recordings from SonicNote to Obsidian as Markdown files", + "author": "EasyLinkIn", "isDesktopOnly": false } diff --git a/package.json b/package.json index d1346ca..e33087a 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { - "name": "znote-sync", + "name": "sonicnote-sync", "version": "1.0.0", - "description": "Sync recordings from Znote (SonicNote) to Obsidian as Markdown files", + "description": "Sync recordings from SonicNote to Obsidian as Markdown files", "main": "main.js", "scripts": { "dev": "node esbuild.config.mjs", "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production" }, - "keywords": ["obsidian", "znote", "recording", "sync"], + "keywords": ["obsidian", "sonicnote", "recording", "sync"], "author": "EasyLink", "license": "MIT", "devDependencies": { diff --git a/release/obsidian-plugin.html b/release/obsidian-plugin.html new file mode 100644 index 0000000..86db441 --- /dev/null +++ b/release/obsidian-plugin.html @@ -0,0 +1,252 @@ + + + + + +SonicNote Sync — Obsidian 插件 + + + + +
+
v1.0.0
+

SonicNote Sync

+

将 SonicNote 妙记的录音、转录、总结同步到 Obsidian,以 Markdown 文件管理。

+ + + 下载插件 + +
+ +
+ +
+

前置要求

+
    +
  • Obsidian 桌面版 v0.15.0 及以上(下载地址
  • +
  • SonicNote 妙记账号
  • +
+
+ +
+

安装

+
    +
  1. 点击上方按钮下载 sonicnote-sync.zip
  2. +
  3. 解压 zip 文件,得到以下文件: +
      +
    • main.js
    • +
    • manifest.json
    • +
    • styles.css
    • +
    +
  4. +
  5. 打开 Obsidian Vault 所在文件夹,进入插件目录:
  6. +
+
.obsidian/plugins/
+
    +
  1. plugins 目录下新建文件夹 sonicnote-sync,将解压的 3 个文件放进去:
  2. +
+
.obsidian/plugins/sonicnote-sync/
+├── main.js
+├── manifest.json
+└── styles.css
+
    +
  1. 重启 Obsidian,进入 设置 → 第三方/社区插件,在列表中找到 SonicNote Sync 并启用
  2. +
+
+ +
+

使用方法

+

登录

+
    +
  1. 进入 设置 → SonicNote Sync
  2. +
  3. 点击"登录"按钮
  4. +
  5. 输入 SonicNote 妙记的手机号和密码(使用 APP 验证码或者申领长期密码)
  6. +
+ +

同步录音

+

登录成功后,通过以下任一方式触发同步:

+
    +
  • 点击左侧功能区的 耳机图标
  • +
  • 命令面板(Ctrl/Cmd + P)输入 "SonicNote: 同步录音"
  • +
+

同步完成后,Vault 中会生成 SonicNoteSync/ 文件夹,每条录音对应一个 Markdown 文件。

+
+ +
+

同步内容

+

每个录音文件包含:

+ + + + + + + + +
内容说明
Frontmatter录音元数据(ID、时间、时长、设备名、标签等)
笔记你在 App 中手写的笔记内容
转录内容AI 转写文本(含说话人、时间戳)
AI 总结智能总结内容(要点、行动项等)
+
+ +
+

设置项

+ + + + + +
设置默认值说明
同步文件夹SonicNoteSyncMarkdown 文件存放目录
+
+ +
+

卸载

+
    +
  1. 进入 设置 → 社区插件,找到 SonicNote Sync,点击禁用并卸载
  2. +
  3. 手动删除 .obsidian/plugins/sonicnote-sync/ 文件夹
  4. +
+
+ +
+ + + + + + + diff --git a/release/sonicnote-sync.zip b/release/sonicnote-sync.zip new file mode 100644 index 0000000000000000000000000000000000000000..903b12b5cec64739b6213dcb6e93e5a1f5ccd118 GIT binary patch literal 4936 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 XKRwdb#Krs18_wUT_?zP?{&V^-W@sj5 literal 0 HcmV?d00001 diff --git a/src/api.ts b/src/api.ts index 8fad6f5..d346902 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,8 +1,8 @@ import { requestUrl, RequestUrlParam } from 'obsidian'; -import { BackendResponse, Recording, TranscriptSegment, SummaryData, ZnotePluginSettings } from './types'; +import { BackendResponse, Recording, TranscriptSegment, SummaryData, SonicNotePluginSettings } from './types'; -export class ZnoteApiClient { - constructor(private getSettings: () => ZnotePluginSettings) {} +export class SonicNoteApiClient { + constructor(private getSettings: () => SonicNotePluginSettings) {} isAuthenticated(): boolean { return this.getSettings().token !== ''; @@ -31,19 +31,25 @@ export class ZnoteApiClient { headers['Authorization'] = `Bearer ${this.token}`; } - const params: RequestUrlParam = { - url, - method, - headers, - }; - if (method === 'POST' && options?.body) { headers['Content-Type'] = 'application/json'; - params.body = JSON.stringify(options.body); } - const response = await requestUrl(params); - return response.json as BackendResponse; + try { + const response = await requestUrl({ + url, + method, + headers, + body: method === 'POST' && options?.body ? JSON.stringify(options.body) : undefined, + }); + return response.json as BackendResponse; + } catch (e: any) { + // requestUrl throws on non-2xx status codes; try to extract the body + if (e?.json) { + return e.json as BackendResponse; + } + throw new Error(e?.message || `请求失败: ${method} ${path}`); + } } async login(phone: string, code: string): Promise<{ token: string; userId: string }> { @@ -53,9 +59,14 @@ export class ZnoteApiClient { if (res.code !== 200) { throw new Error(res.msg || '登录失败'); } + const data = res.data; + const token = typeof data === 'string' ? data : data?.token; + if (!token) { + throw new Error('登录响应中缺少 token'); + } return { - token: res.data.token || res.data, - userId: res.data.userId || '', + token, + userId: data?.user?.userId || data?.userId || '', }; } diff --git a/src/formatter.ts b/src/formatter.ts index d07dab4..8101b8a 100644 --- a/src/formatter.ts +++ b/src/formatter.ts @@ -50,7 +50,7 @@ export function generateFrontmatter(recording: Recording, syncTime: string): str } lines.push('tags:'); - lines.push(' - znote'); + lines.push(' - sonicnote'); const recordTypeLabel = recording.recordType === '00' ? '通话' : '录音'; lines.push(` - ${recordTypeLabel}`); diff --git a/src/main.ts b/src/main.ts index 39b58e8..58af37a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,12 @@ import { Notice, Plugin } from 'obsidian'; -import { ZnoteApiClient } from './api'; +import { SonicNoteApiClient } from './api'; import { SyncService } from './sync'; -import { ZnoteSettingTab } from './settings'; -import { DEFAULT_SETTINGS, ZnotePluginSettings } from './types'; +import { SonicNoteSettingTab } from './settings'; +import { DEFAULT_SETTINGS, SonicNotePluginSettings } from './types'; -export default class ZnoteSyncPlugin extends Plugin { - settings: ZnotePluginSettings = DEFAULT_SETTINGS; - private api!: ZnoteApiClient; +export default class SonicNoteSyncPlugin extends Plugin { + settings: SonicNotePluginSettings = DEFAULT_SETTINGS; + private api!: SonicNoteApiClient; private syncService!: SyncService; private statusBarEl!: HTMLElement; @@ -14,7 +14,7 @@ export default class ZnoteSyncPlugin extends Plugin { await this.loadSettings(); // Initialize API client and sync service - this.api = new ZnoteApiClient(() => this.settings); + this.api = new SonicNoteApiClient(() => this.settings); this.syncService = new SyncService( this.app, this.api, @@ -27,42 +27,42 @@ export default class ZnoteSyncPlugin extends Plugin { this.updateStatusBar(); // Ribbon icon - this.addRibbonIcon('headphones', 'Znote Sync: 同步录音', () => { + this.addRibbonIcon('headphones', 'SonicNote Sync: 同步录音', () => { this.triggerSync(); }); // Commands this.addCommand({ - id: 'znote-sync:sync', + id: 'sonicnote-sync:sync', name: '同步录音', callback: () => this.triggerSync(), }); this.addCommand({ - id: 'znote-sync:login', + id: 'sonicnote-sync:login', name: '登录', callback: () => { // @ts-ignore - internal API to open settings this.app.setting.open(); // @ts-ignore - this.app.setting.openTabById('znote-sync'); + this.app.setting.openTabById('sonicnote-sync'); }, }); this.addCommand({ - id: 'znote-sync:logout', + id: 'sonicnote-sync:logout', name: '登出', callback: async () => { this.settings.token = ''; this.settings.phoneNumber = ''; await this.saveSettings(); - new Notice('已登出 Znote'); + new Notice('已登出 SonicNote'); this.updateStatusBar(); }, }); // Settings tab - this.addSettingTab(new ZnoteSettingTab( + this.addSettingTab(new SonicNoteSettingTab( this.app, this, this.api, @@ -70,11 +70,11 @@ export default class ZnoteSyncPlugin extends Plugin { () => this.saveSettings() )); - console.log('Znote Sync plugin loaded'); + console.log('SonicNote Sync plugin loaded'); } onunload() { - console.log('Znote Sync plugin unloaded'); + console.log('SonicNote Sync plugin unloaded'); } async loadSettings() { @@ -87,15 +87,15 @@ export default class ZnoteSyncPlugin extends Plugin { private async triggerSync() { if (!this.api.isAuthenticated()) { - new Notice('请先登录 Znote(设置 → Znote Sync)'); + new Notice('请先登录 SonicNote(设置 → SonicNote Sync)'); return; } - this.statusBarEl.setText('Znote: 同步中...'); + this.statusBarEl.setText('SonicNote: 同步中...'); try { const result = await this.syncService.syncAll((msg) => { - this.statusBarEl.setText(`Znote: ${msg}`); + this.statusBarEl.setText(`SonicNote: ${msg}`); }); let message = `同步完成: ${result.synced} 条新/更新`; @@ -115,9 +115,9 @@ export default class ZnoteSyncPlugin extends Plugin { const lastSync = this.settings.lastSyncTime ? `上次同步: ${this.settings.lastSyncTime.substring(0, 16).replace('T', ' ')}` : '未同步'; - this.statusBarEl.setText(`Znote: ${lastSync}`); + this.statusBarEl.setText(`SonicNote: ${lastSync}`); } else { - this.statusBarEl.setText('Znote: 未登录'); + this.statusBarEl.setText('SonicNote: 未登录'); } } } diff --git a/src/settings.ts b/src/settings.ts index ceac65f..d625f74 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,17 +1,17 @@ import { App, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian'; -import { ZnoteApiClient } from './api'; -import { ZnotePluginSettings, DEFAULT_SETTINGS } from './types'; +import { SonicNoteApiClient } from './api'; +import { SonicNotePluginSettings, DEFAULT_SETTINGS } from './types'; -export class ZnoteSettingTab extends PluginSettingTab { - private api: ZnoteApiClient; - private getSettings: () => ZnotePluginSettings; +export class SonicNoteSettingTab extends PluginSettingTab { + private api: SonicNoteApiClient; + private getSettings: () => SonicNotePluginSettings; private saveSettings: () => Promise; constructor( app: App, plugin: Plugin, - api: ZnoteApiClient, - getSettings: () => ZnotePluginSettings, + api: SonicNoteApiClient, + getSettings: () => SonicNotePluginSettings, saveSettings: () => Promise ) { super(app, plugin); @@ -25,26 +25,14 @@ export class ZnoteSettingTab extends PluginSettingTab { const settings = this.getSettings(); containerEl.empty(); - containerEl.createEl('h2', { text: 'Znote Sync 设置' }); - - // Server URL - new Setting(containerEl) - .setName('服务器地址') - .setDesc('智音笔记后端服务地址') - .addText(text => text - .setPlaceholder('http://localhost:8048') - .setValue(settings.serverUrl) - .onChange(async (value) => { - settings.serverUrl = value; - await this.saveSettings(); - })); + containerEl.createEl('h2', { text: 'SonicNote Sync 设置' }); // Sync folder new Setting(containerEl) .setName('同步文件夹') .setDesc('录音 Markdown 文件存放的文件夹(相对于 Vault 根目录)') .addText(text => text - .setPlaceholder('ZnoteSync') + .setPlaceholder('SonicNoteSync') .setValue(settings.syncFolder) .onChange(async (value) => { settings.syncFolder = value; @@ -83,15 +71,15 @@ export class ZnoteSettingTab extends PluginSettingTab { } class LoginModal extends Modal { - private api: ZnoteApiClient; - private getSettings: () => ZnotePluginSettings; + private api: SonicNoteApiClient; + private getSettings: () => SonicNotePluginSettings; private saveSettings: () => Promise; private onCloseCallback: () => void; constructor( app: App, - api: ZnoteApiClient, - getSettings: () => ZnotePluginSettings, + api: SonicNoteApiClient, + getSettings: () => SonicNotePluginSettings, saveSettings: () => Promise, onCloseCallback: () => void ) { @@ -106,7 +94,7 @@ class LoginModal extends Modal { const { contentEl } = this; contentEl.empty(); - contentEl.createEl('h2', { text: '登录智音笔记' }); + contentEl.createEl('h2', { text: '登录 SonicNote' }); let phone = ''; let code = ''; @@ -118,9 +106,10 @@ class LoginModal extends Modal { .onChange((value) => { phone = value; })); new Setting(contentEl) - .setName('验证码') + .setName('密码') + .setDesc('使用 APP 验证码或者申领长期密码') .addText(text => text - .setPlaceholder('请输入验证码') + .setPlaceholder('请输入密码') .onChange((value) => { code = value; })); new Setting(contentEl) @@ -129,7 +118,7 @@ class LoginModal extends Modal { .setCta() .onClick(async () => { if (!phone || !code) { - new Notice('请输入手机号和验证码'); + new Notice('请输入手机号和密码'); return; } try { diff --git a/src/sync.ts b/src/sync.ts index b568a7a..5c9356b 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -1,18 +1,18 @@ import { App, Notice, TFile, TFolder } from 'obsidian'; -import { ZnoteApiClient } from './api'; -import { ZnotePluginSettings, LocalFileInfo, Recording, SyncResult, TranscriptSegment, SummaryData } from './types'; +import { SonicNoteApiClient } from './api'; +import { SonicNotePluginSettings, LocalFileInfo, Recording, SyncResult, TranscriptSegment, SummaryData } from './types'; import { formatFileName, toMarkdown } from './formatter'; export class SyncService { - private api: ZnoteApiClient; + private api: SonicNoteApiClient; private app: App; - private getSettings: () => ZnotePluginSettings; + private getSettings: () => SonicNotePluginSettings; private saveSettings: () => Promise; constructor( app: App, - api: ZnoteApiClient, - getSettings: () => ZnotePluginSettings, + api: SonicNoteApiClient, + getSettings: () => SonicNotePluginSettings, saveSettings: () => Promise ) { this.app = app; @@ -113,7 +113,7 @@ export class SyncService { return match ? match[1] : null; } - private async processRecording(recording: Recording, localIndex: Map, settings: ZnotePluginSettings): Promise { + private async processRecording(recording: Recording, localIndex: Map, settings: SonicNotePluginSettings): Promise { const syncTime = new Date().toISOString(); // Check if we need to update @@ -150,7 +150,7 @@ export class SyncService { }); } - private async writeRecordingToNewFile(recording: Recording, syncTime: string, settings: ZnotePluginSettings, conflictWithPath?: string): Promise { + private async writeRecordingToNewFile(recording: Recording, syncTime: string, settings: SonicNotePluginSettings, conflictWithPath?: string): Promise { const content = await this.buildRecordingContent(recording, syncTime); let fileName = formatFileName(recording); diff --git a/src/types.ts b/src/types.ts index 485d5fc..bd4e727 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,6 @@ // ===== 插件设置 ===== -export interface ZnotePluginSettings { +export interface SonicNotePluginSettings { serverUrl: string; syncFolder: string; pageSize: number; @@ -9,9 +9,9 @@ export interface ZnotePluginSettings { lastSyncTime: string; } -export const DEFAULT_SETTINGS: ZnotePluginSettings = { - serverUrl: 'http://ainote.easylinkin.com:8048', - syncFolder: 'ZnoteSync', +export const DEFAULT_SETTINGS: SonicNotePluginSettings = { + serverUrl: 'https://ainote.easylinkin.com:18048/prod-api', + syncFolder: 'SonicNoteSync', pageSize: 50, token: '', phoneNumber: '', diff --git a/styles.css b/styles.css index 457130d..37c422d 100644 --- a/styles.css +++ b/styles.css @@ -1,10 +1,10 @@ -/* Znote Sync Plugin Styles */ +/* SonicNote Sync Plugin Styles */ /* Login modal */ -.znote-login-modal .setting-item { +.sonicnote-login-modal .setting-item { padding: 8px 0; } -.znote-login-modal .setting-item-control input { +.sonicnote-login-modal .setting-item-control input { width: 200px; }