首页
/ 自动化你的知识管理:Trilium Notes脚本编程实用指南

自动化你的知识管理:Trilium Notes脚本编程实用指南

2026-04-07 12:39:42作者:齐冠琰

引言:知识管理的自动化革命

你是否每天花费大量时间在复制粘贴信息、整理笔记标签、手动备份数据?这些重复性工作不仅消耗精力,还容易出错。Trilium Notes(一款强大的个人知识库工具)提供的脚本编程功能,就像给你配备了一位不知疲倦的"智能助手",能自动完成这些机械任务。本文将带你探索如何利用Trilium的脚本功能,构建个性化的知识管理自动化流程。

一、场景分析:知识管理中的效率瓶颈

1.1 日常知识管理的痛点

知识工作者每天面临着各种信息管理挑战:

  • 信息收集碎片化:网页、邮件、文档中的重要信息需要手动整理到知识库
  • 重复操作繁琐:相同格式的笔记需要重复设置标签、分类和属性
  • 定期任务耗时:每周/月度的笔记汇总、备份和清理工作占用宝贵时间
  • 关联发现困难:难以快速找到相关笔记,形成知识网络

1.2 自动化能解决的核心问题

Trilium的脚本功能特别适合解决以下问题:

  • 批量处理笔记(创建、更新、分类)
  • 定时执行重复性任务(备份、清理、汇总)
  • 实现自定义工作流(从信息收集到知识输出)
  • 增强用户界面功能(添加自定义工具和视图)

二、技术解析:Trilium脚本编程基础

2.1 核心概念:脚本与API

脚本是一系列指令的集合,就像给计算机编写的"操作指南",告诉它如何完成特定任务。API(应用程序编程接口) 则是Trilium提供的"操作手册",定义了你可以让Trilium做什么。

Trilium提供两套脚本环境:

  • 后端脚本:运行在服务器/应用程序内部,拥有操作数据库的权限
  • 前端脚本:运行在浏览器中,主要用于增强用户界面和交互

2.2 开发环境搭建

创建你的第一个Trilium脚本只需三步:

  1. 创建新笔记,设置类型为"code"
  2. 设置MIME类型为"application/javascript"
  3. 添加#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:网页内容自动抓取与整理

痛点描述

你是否经常需要将网页文章保存到笔记中,但又讨厌手动复制粘贴格式混乱的内容?这个脚本将帮你一键抓取网页并自动格式化。

实现思路

  1. 创建前端按钮触发网页抓取
  2. 使用浏览器API获取当前页面内容
  3. 提取标题、正文和图片等关键信息
  4. 在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();
}

效果验证

  1. 在浏览器中打开任意网页
  2. 点击Trilium工具栏中的"网页剪藏"按钮
  3. 检查你的笔记文件夹,应该会出现包含网页标题和内容的新笔记
  4. 验证笔记是否包含"source:web"标签和原始URL属性

案例2:笔记元数据自动维护

痛点描述

随着笔记数量增长,手动维护笔记的创建日期、修改记录和关联标签变得越来越困难。这个后端脚本可以自动为笔记添加和更新元数据。

实现思路

  1. 定期扫描指定笔记本中的笔记
  2. 检查并添加缺失的元数据(创建日期、字数统计)
  3. 根据内容自动生成相关标签
  4. 更新修改记录和版本信息

代码解析

// == 笔记元数据自动维护脚本 ==
// 添加#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();

效果验证

  1. 将脚本添加到Trilium并设置#run=backend#trigger=daily属性
  2. 等待一天或手动执行脚本
  3. 检查目标文件夹中的笔记,确认它们已添加:
    • createdDate: YYYY-MM-DD格式的创建日期
    • wordCount: 笔记字数统计
    • autoTags: 自动生成的标签(对长笔记)
    • metadata: processed标签

案例3:智能笔记备份与清理

痛点描述

定期备份重要笔记和清理无用草稿是良好的知识管理习惯,但手动执行既容易忘记,又难以坚持。这个脚本将自动完成备份和清理工作。

实现思路

  1. 每周日自动备份标记为"重要"的笔记
  2. 自动清理超过30天未修改的草稿笔记
  3. 生成备份报告并发送通知
  4. 保留最近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();

效果验证

  1. 设置脚本属性#run=backend#trigger=weekly
  2. 等待脚本自动执行或手动触发
  3. 检查备份文件夹,应包含最新日期的备份笔记
  4. 查看"已删除草稿"文件夹,确认旧草稿已被移动
  5. 检查"备份报告"文件夹,应生成包含备份和清理统计的报告

四、常见问题解决

Q1: 脚本执行失败,如何调试?

A: Trilium提供了日志功能帮助调试:

  1. 使用api.log("调试信息")在脚本中添加日志
  2. 在后端脚本中,可以通过api.getBackendLog()查看系统日志
  3. 前端脚本错误可以通过浏览器开发者工具的控制台查看
  4. 检查脚本是否设置了正确的#run=backend#run=frontend属性

Q2: 脚本执行权限不足怎么办?

A: ⚠️ 确保了解脚本的安全影响:

  1. 后端脚本默认拥有较高权限,可操作所有笔记
  2. 前端脚本只能访问当前用户有权限的笔记
  3. 敏感操作(如删除笔记)建议先在测试环境验证
  4. 考虑使用api.transactional()包装关键操作,以便出错时回滚

Q3: 如何让脚本定时运行?

A: 使用Trilium的触发器属性:

  1. #trigger=daily - 每天执行一次
  2. #trigger=weekly - 每周执行一次
  3. #trigger=monthly - 每月执行一次
  4. #trigger=hourly - 每小时执行一次
  5. 时间触发脚本必须是后端脚本(#run=backend

Q4: 脚本执行超时怎么办?

A: 优化脚本性能:

  1. 避免一次性处理过多笔记,分批次处理
  2. 使用api.transactional()减少数据库提交次数
  3. 将大型任务拆分为多个小脚本
  4. 对于特别耗时的操作,添加状态跟踪以便断点续传

Q5: 如何分享和重用脚本?

A: 脚本共享最佳实践:

  1. 将通用脚本标记为#module=脚本名称
  2. 在其他脚本中使用const module = require("脚本名称")导入
  3. 重要脚本添加详细注释和使用说明
  4. 考虑创建"脚本库"笔记本统一管理

五、扩展思考:自动化知识管理的未来

Trilium脚本功能不仅仅是简单的任务自动化工具,更是构建个人知识管理系统的强大框架。通过脚本,你可以:

  1. 构建个性化工作流:从信息收集、处理到输出的全流程自动化
  2. 创建智能助手:基于笔记内容提供建议和提醒
  3. 实现知识挖掘:发现笔记间隐藏的关联和模式
  4. 扩展Trilium功能:添加官方未提供的定制化功能

随着AI技术的发展,未来你还可以将Trilium脚本与AI服务集成,实现更高级的自动化,如:

  • 使用自然语言处理自动提取笔记要点
  • 通过机器学习识别笔记中的重要概念和关系
  • 创建智能问答系统,从你的知识库中寻找答案

六、进阶学习路径图

初级:脚本基础

中级:功能扩展

高级:系统集成

七、相关工具与资源

  1. Trilium官方文档:项目中的docs/目录包含完整的API文档和使用指南
  2. 脚本示例src/tools/generate_document.js提供了批量创建笔记的示例
  3. 社区脚本库:Trilium社区中有许多用户共享的实用脚本,可以通过搜索"Trilium script"找到

通过本文介绍的技术和案例,你已经具备了使用Trilium脚本功能自动化知识管理的基础。记住,最好的自动化方案是那些为你个人工作流程量身定制的方案。现在就开始尝试创建第一个脚本,让Trilium成为你真正的知识管理助手!

登录后查看全文
热门项目推荐
相关项目推荐