自动化你的知识管理:Trilium Notes脚本编程实用指南
引言:知识管理的自动化革命
你是否每天花费大量时间在复制粘贴信息、整理笔记标签、手动备份数据?这些重复性工作不仅消耗精力,还容易出错。Trilium Notes(一款强大的个人知识库工具)提供的脚本编程功能,就像给你配备了一位不知疲倦的"智能助手",能自动完成这些机械任务。本文将带你探索如何利用Trilium的脚本功能,构建个性化的知识管理自动化流程。
一、场景分析:知识管理中的效率瓶颈
1.1 日常知识管理的痛点
知识工作者每天面临着各种信息管理挑战:
- 信息收集碎片化:网页、邮件、文档中的重要信息需要手动整理到知识库
- 重复操作繁琐:相同格式的笔记需要重复设置标签、分类和属性
- 定期任务耗时:每周/月度的笔记汇总、备份和清理工作占用宝贵时间
- 关联发现困难:难以快速找到相关笔记,形成知识网络
1.2 自动化能解决的核心问题
Trilium的脚本功能特别适合解决以下问题:
- 批量处理笔记(创建、更新、分类)
- 定时执行重复性任务(备份、清理、汇总)
- 实现自定义工作流(从信息收集到知识输出)
- 增强用户界面功能(添加自定义工具和视图)
二、技术解析:Trilium脚本编程基础
2.1 核心概念:脚本与API
脚本是一系列指令的集合,就像给计算机编写的"操作指南",告诉它如何完成特定任务。API(应用程序编程接口) 则是Trilium提供的"操作手册",定义了你可以让Trilium做什么。
Trilium提供两套脚本环境:
- 后端脚本:运行在服务器/应用程序内部,拥有操作数据库的权限
- 前端脚本:运行在浏览器中,主要用于增强用户界面和交互
2.2 开发环境搭建
创建你的第一个Trilium脚本只需三步:
- 创建新笔记,设置类型为"code"
- 设置MIME类型为"application/javascript"
- 添加
#run=backend或#run=frontend属性指定运行环境
完成后,你会在笔记工具栏看到▶️按钮,点击即可执行脚本。
2.3 核心API快速入门
后端API基础(完整文档:src/services/backend_script_api.js):
// 创建新笔记
const {note} = api.createTextNote(
"parent-note-id", // 父笔记ID
"新笔记标题", // 笔记标题
"笔记内容" // 笔记内容
);
// 搜索笔记
const notes = api.searchForNotes("#tag:important");
// 更新笔记属性
note.setLabel("status", "completed");
note.save();
前端API基础(完整文档:docs/frontend_api/FrontendScriptApi.html):
// 显示消息提示
api.showMessage("操作成功完成!");
// 添加工具栏按钮
api.addButtonToToolbar({
id: "my-tool",
title: "我的工具",
action: () => { /* 按钮点击事件处理 */ }
});
三、实战应用:三个实用自动化案例
案例1:网页内容自动抓取与整理
痛点描述
你是否经常需要将网页文章保存到笔记中,但又讨厌手动复制粘贴格式混乱的内容?这个脚本将帮你一键抓取网页并自动格式化。
实现思路
- 创建前端按钮触发网页抓取
- 使用浏览器API获取当前页面内容
- 提取标题、正文和图片等关键信息
- 在Trilium中创建格式化笔记
代码解析
// == 网页内容抓取工具 ==
// 1. 添加工具栏按钮
api.addButtonToToolbar({
id: "web-clipper",
title: "网页剪藏",
icon: "📌",
action: clipCurrentPage // 点击时执行的函数
});
// 2. 核心抓取函数
async function clipCurrentPage() {
try {
// 获取当前浏览器标签页信息
const tabInfo = await browser.tabs.query({active: true, currentWindow: true});
const tab = tabInfo[0];
// 3. 注入内容提取脚本到当前页面
const result = await browser.scripting.executeScript({
target: {tabId: tab.id},
function: extractPageContent // 在页面中执行的提取函数
});
const pageData = result[0].result;
// 4. 在Trilium中创建新笔记
const parentNoteId = "your-notes-folder-id"; // 替换为你的笔记文件夹ID
const {note} = api.createTextNote(
parentNoteId,
pageData.title,
generateNoteContent(pageData)
);
// 添加标签和属性
note.setLabel("source", "web");
note.setLabel("url", pageData.url);
note.save();
api.showMessage(`已保存: ${pageData.title}`);
} catch (e) {
api.showMessage(`抓取失败: ${e.message}`, "error");
}
}
// 5. 页面内容提取函数
function extractPageContent() {
// 简化的内容提取逻辑
return {
title: document.title,
url: window.location.href,
content: document.querySelector("article")?.innerText ||
document.body.innerText.substring(0, 2000)
};
}
// 6. 生成格式化笔记内容
function generateNoteContent(data) {
return `
# ${data.title}
原文链接
## 内容摘要
${data.content}
---
*自动抓取于: ${new Date().toLocaleString()}*
`.trim();
}
效果验证
- 在浏览器中打开任意网页
- 点击Trilium工具栏中的"网页剪藏"按钮
- 检查你的笔记文件夹,应该会出现包含网页标题和内容的新笔记
- 验证笔记是否包含"source:web"标签和原始URL属性
案例2:笔记元数据自动维护
痛点描述
随着笔记数量增长,手动维护笔记的创建日期、修改记录和关联标签变得越来越困难。这个后端脚本可以自动为笔记添加和更新元数据。
实现思路
- 定期扫描指定笔记本中的笔记
- 检查并添加缺失的元数据(创建日期、字数统计)
- 根据内容自动生成相关标签
- 更新修改记录和版本信息
代码解析
// == 笔记元数据自动维护脚本 ==
// 添加#run=backend和#trigger=daily属性让脚本每天自动运行
// 1. 配置参数
const TARGET_FOLDER_ID = "your-folder-id"; // 替换为目标文件夹ID
const MIN_WORD_COUNT = 100; // 自动标签的最低字数要求
// 2. 主函数
async function processNotesMetadata() {
// 使用事务确保操作的原子性
await api.transactional(async () => {
// 3. 搜索需要处理的笔记
const notes = await api.searchForNotes(`parent:${TARGET_FOLDER_ID} -#metadata:processed`);
api.log(`找到 ${notes.length} 个需要处理的笔记`);
for (const note of notes) {
try {
// 4. 添加创建日期属性(如果缺失)
if (!note.hasLabel("createdDate")) {
const createdDate = note.createdAt.toISOString().split('T')[0];
note.setLabel("createdDate", createdDate);
}
// 5. 更新字数统计
const content = note.getContent();
const wordCount = content ? content.split(/\s+/).filter(word => word.length > 0).length : 0;
note.setLabel("wordCount", wordCount.toString());
// 6. 自动生成标签(仅对长笔记)
if (wordCount >= MIN_WORD_COUNT && !note.hasLabel("autoTags")) {
const tags = await generateAutoTags(note);
if (tags.length > 0) {
note.setLabel("autoTags", tags.join(","));
tags.forEach(tag => note.addLabel("tag", tag));
}
}
// 7. 标记为已处理
note.setLabel("metadata", "processed");
note.save();
} catch (e) {
api.log(`处理笔记 ${note.noteId} 时出错: ${e.message}`);
}
}
});
api.log("元数据处理完成");
}
// 8. 简单的标签生成函数
async function generateAutoTags(note) {
const content = note.getContent().toLowerCase();
const tags = [];
// 关键词映射(实际应用中可使用更复杂的NLP方法)
const keywordMap = {
"javascript": ["js", "javascript", "前端", "代码"],
"productivity": ["效率", " productivity", "工作流", "自动化"],
"reading": ["阅读", "书籍", "笔记", "摘要"]
};
// 检查内容中的关键词
for (const [tag, keywords] of Object.entries(keywordMap)) {
if (keywords.some(keyword => content.includes(keyword))) {
tags.push(tag);
}
}
return tags.slice(0, 3); // 最多返回3个标签
}
// 执行主函数
processNotesMetadata();
效果验证
- 将脚本添加到Trilium并设置
#run=backend和#trigger=daily属性 - 等待一天或手动执行脚本
- 检查目标文件夹中的笔记,确认它们已添加:
- createdDate: YYYY-MM-DD格式的创建日期
- wordCount: 笔记字数统计
- autoTags: 自动生成的标签(对长笔记)
- metadata: processed标签
案例3:智能笔记备份与清理
痛点描述
定期备份重要笔记和清理无用草稿是良好的知识管理习惯,但手动执行既容易忘记,又难以坚持。这个脚本将自动完成备份和清理工作。
实现思路
- 每周日自动备份标记为"重要"的笔记
- 自动清理超过30天未修改的草稿笔记
- 生成备份报告并发送通知
- 保留最近5次备份,自动删除旧备份
代码解析
// == 智能备份与清理脚本 ==
// 添加#run=backend和#trigger=weekly属性让脚本每周运行
// 1. 配置参数
const IMPORTANT_NOTES_QUERY = "#tag:important";
const DRAFTS_QUERY = "#type:draft AND #dateModified:<30days";
const BACKUP_FOLDER = "backups";
const MAX_BACKUPS = 5;
// 2. 主函数
async function backupAndCleanup() {
try {
api.log("开始备份与清理任务");
// 3. 创建备份
const backupResult = await createImportantNotesBackup();
// 4. 清理旧草稿
const cleanupResult = await cleanupOldDrafts();
// 5. 生成报告
const report = generateReport(backupResult, cleanupResult);
await createReportNote(report);
api.log("备份与清理任务完成");
} catch (e) {
api.log(`备份与清理任务失败: ${e.message}`);
}
}
// 6. 创建重要笔记备份
async function createImportantNotesBackup() {
const importantNotes = await api.searchForNotes(IMPORTANT_NOTES_QUERY);
if (importantNotes.length === 0) {
return { success: true, count: 0, message: "没有找到重要笔记" };
}
// 创建备份文件夹(如果不存在)
let backupFolder = await api.getNoteByTitle(BACKUP_FOLDER);
if (!backupFolder) {
const rootNote = await api.getRootNote();
({note: backupFolder} = await api.createNote(rootNote.noteId, BACKUP_FOLDER, "笔记备份文件夹"));
}
// 创建带日期的备份笔记
const backupDate = new Date().toISOString().split('T')[0];
const backupNoteTitle = `备份_${backupDate}`;
// 检查备份是否已存在
let backupNote = await api.getNoteByTitle(backupNoteTitle, backupFolder.noteId);
if (backupNote) {
return { success: false, message: "今日备份已存在" };
}
// 创建备份笔记
({note: backupNote} = await api.createNote(
backupFolder.noteId,
backupNoteTitle,
`# 重要笔记备份 ${backupDate}\n\n包含 ${importantNotes.length} 个笔记`
));
// 复制重要笔记到备份笔记下
for (const note of importantNotes) {
await api.cloneNoteToParent(note.noteId, backupNote.noteId);
}
// 清理旧备份
await cleanupOldBackups(backupFolder.noteId);
return {
success: true,
count: importantNotes.length,
backupNoteId: backupNote.noteId
};
}
// 7. 清理旧草稿
async function cleanupOldDrafts() {
const oldDrafts = await api.searchForNotes(DRAFTS_QUERY);
if (oldDrafts.length === 0) {
return { success: true, deleted: 0 };
}
// 创建"已删除草稿"文件夹(如果不存在)
let deletedDraftsFolder = await api.getNoteByTitle("已删除草稿");
if (!deletedDraftsFolder) {
const rootNote = await api.getRootNote();
({note: deletedDraftsFolder} = await api.createNote(
rootNote.noteId,
"已删除草稿",
"自动清理的草稿笔记"
));
deletedDraftsFolder.setLabel("hidden", "true");
deletedDraftsFolder.save();
}
// 移动旧草稿到删除文件夹(而不是直接删除)
for (const draft of oldDrafts) {
await api.moveNoteToParent(draft.noteId, deletedDraftsFolder.noteId);
}
return { success: true, deleted: oldDrafts.length };
}
// 8. 辅助函数:清理旧备份
async function cleanupOldBackups(backupFolderId) {
const backupNotes = await api.getChildNotes(backupFolderId);
// 按创建日期排序(最新的在前)
backupNotes.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
// 如果备份数量超过MAX_BACKUPS,删除最旧的
if (backupNotes.length > MAX_BACKUPS) {
const toDelete = backupNotes.slice(MAX_BACKUPS);
for (const note of toDelete) {
await api.deleteNote(note.noteId);
}
api.log(`已删除 ${toDelete.length} 个旧备份`);
}
}
// 9. 生成报告
function generateReport(backupResult, cleanupResult) {
return `# 自动备份与清理报告\n\n## 备份状态\n${
backupResult.success
? `✅ 成功备份 ${backupResult.count} 个重要笔记`
: `⚠️ 备份失败: ${backupResult.message}`
}\n\n## 清理状态\n${
cleanupResult.success
? `✅ 已清理 ${cleanupResult.deleted} 个旧草稿`
: `⚠️ 清理失败: ${cleanupResult.message}`
}\n\n报告生成时间: ${new Date().toLocaleString()}`;
}
// 10. 创建报告笔记
async function createReportNote(content) {
let reportFolder = await api.getNoteByTitle("备份报告");
if (!reportFolder) {
const rootNote = await api.getRootNote();
({note: reportFolder} = await api.createNote(rootNote.noteId, "备份报告", "自动备份与清理报告"));
}
const reportTitle = `报告_${new Date().toISOString().split('T')[0]}`;
await api.createTextNote(reportFolder.noteId, reportTitle, content);
}
// 执行主函数
backupAndCleanup();
效果验证
- 设置脚本属性
#run=backend和#trigger=weekly - 等待脚本自动执行或手动触发
- 检查备份文件夹,应包含最新日期的备份笔记
- 查看"已删除草稿"文件夹,确认旧草稿已被移动
- 检查"备份报告"文件夹,应生成包含备份和清理统计的报告
四、常见问题解决
Q1: 脚本执行失败,如何调试?
A: Trilium提供了日志功能帮助调试:
- 使用
api.log("调试信息")在脚本中添加日志 - 在后端脚本中,可以通过
api.getBackendLog()查看系统日志 - 前端脚本错误可以通过浏览器开发者工具的控制台查看
- 检查脚本是否设置了正确的
#run=backend或#run=frontend属性
Q2: 脚本执行权限不足怎么办?
A: ⚠️ 确保了解脚本的安全影响:
- 后端脚本默认拥有较高权限,可操作所有笔记
- 前端脚本只能访问当前用户有权限的笔记
- 敏感操作(如删除笔记)建议先在测试环境验证
- 考虑使用
api.transactional()包装关键操作,以便出错时回滚
Q3: 如何让脚本定时运行?
A: 使用Trilium的触发器属性:
#trigger=daily- 每天执行一次#trigger=weekly- 每周执行一次#trigger=monthly- 每月执行一次#trigger=hourly- 每小时执行一次- 时间触发脚本必须是后端脚本(
#run=backend)
Q4: 脚本执行超时怎么办?
A: 优化脚本性能:
- 避免一次性处理过多笔记,分批次处理
- 使用
api.transactional()减少数据库提交次数 - 将大型任务拆分为多个小脚本
- 对于特别耗时的操作,添加状态跟踪以便断点续传
Q5: 如何分享和重用脚本?
A: 脚本共享最佳实践:
- 将通用脚本标记为
#module=脚本名称 - 在其他脚本中使用
const module = require("脚本名称")导入 - 重要脚本添加详细注释和使用说明
- 考虑创建"脚本库"笔记本统一管理
五、扩展思考:自动化知识管理的未来
Trilium脚本功能不仅仅是简单的任务自动化工具,更是构建个人知识管理系统的强大框架。通过脚本,你可以:
- 构建个性化工作流:从信息收集、处理到输出的全流程自动化
- 创建智能助手:基于笔记内容提供建议和提醒
- 实现知识挖掘:发现笔记间隐藏的关联和模式
- 扩展Trilium功能:添加官方未提供的定制化功能
随着AI技术的发展,未来你还可以将Trilium脚本与AI服务集成,实现更高级的自动化,如:
- 使用自然语言处理自动提取笔记要点
- 通过机器学习识别笔记中的重要概念和关系
- 创建智能问答系统,从你的知识库中寻找答案
六、进阶学习路径图
初级:脚本基础
- 掌握核心API文档:src/services/backend_script_api.js
- 学习使用
searchForNotes()和createTextNote()等基础操作 - 实现简单的批量处理脚本
中级:功能扩展
- 研究调度系统实现:src/services/scheduler.js
- 学习前端组件开发:src/public/app/widgets/
- 掌握事务和错误处理最佳实践
高级:系统集成
- 探索ETAPI接口开发:src/etapi/
- 研究数据导入导出功能:src/services/import/和src/services/export/
- 实现与外部系统的集成(如同步到云端存储)
七、相关工具与资源
- Trilium官方文档:项目中的docs/目录包含完整的API文档和使用指南
- 脚本示例:src/tools/generate_document.js提供了批量创建笔记的示例
- 社区脚本库:Trilium社区中有许多用户共享的实用脚本,可以通过搜索"Trilium script"找到
通过本文介绍的技术和案例,你已经具备了使用Trilium脚本功能自动化知识管理的基础。记住,最好的自动化方案是那些为你个人工作流程量身定制的方案。现在就开始尝试创建第一个脚本,让Trilium成为你真正的知识管理助手!
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
LongCat-AudioDiT-1BLongCat-AudioDiT 是一款基于扩散模型的文本转语音(TTS)模型,代表了当前该领域的最高水平(SOTA),它直接在波形潜空间中进行操作。00- QQwen3.5-397B-A17BQwen3.5 实现了重大飞跃,整合了多模态学习、架构效率、强化学习规模以及全球可访问性等方面的突破性进展,旨在为开发者和企业赋予前所未有的能力与效率。Jinja00
HY-Embodied-0.5这是一套专为现实世界具身智能打造的基础模型。该系列模型采用创新的混合Transformer(Mixture-of-Transformers, MoT) 架构,通过潜在令牌实现模态特异性计算,显著提升了细粒度感知能力。Jinja00
FreeSql功能强大的对象关系映射(O/RM)组件,支持 .NET Core 2.1+、.NET Framework 4.0+、Xamarin 以及 AOT。C#00