自定义脚本总览
自定义脚本让你用一段 JavaScript 直接操作 dYm 的数据、下载任务和抖音接口, 做界面上没有做成按钮的批量操作——批量改用户设置、按自己的规则清理文件、 把收藏夹整个拉下来,都属于这一类。
打开入口
「自定义脚本」页默认是隐藏的,需要先开开发者模式:
设置 → 系统 → 开发者模式 打开后,左侧导航会多出「自定义脚本」。
关掉开发者模式时,如果正停在该页面会被送回首页,但已经在跑的脚本不会停。
两类脚本
| 内置脚本 | 我的脚本 | |
|---|---|---|
| 来源 | 随应用发布,编译在包里 | 用户数据目录下的 scripts/*.js |
| 能否编辑 | 只读 | 可以,编辑器里直接改 |
| 升级影响 | 随版本更新 | 不受升级影响 |
两类脚本跑的是同一套运行时——内置脚本也是以 CommonJS 源码的形式存在, 和你自己写的没有区别。所以内置脚本可以当范例读,点「以此为模板新建」 就能得到一份逐字相同、可编辑的副本。
脚本长什么样
一个脚本就是一个 CommonJS 模块,导出 meta 和 run 两样东西:
exports.meta = {
name: '脚本名称', // 必填,列表里显示的名字
description: '一句话说明', // 可选
timeout: 0 // 可选,超时毫秒数;不填或 0 = 不限时长
}
exports.run = async (api) => {
api.log('开始')
// 逻辑写在这里,能做什么见 API 参考
return { done: true } // 返回值会显示在运行结果里(需 JSON 可序列化)
}run 的入参 api 就是脚本的全部能力来源,详见 API 参考。
沙箱限制
脚本在 Node 的 vm 沙箱里求值,有两条必须知道的约束:
没有 require,也没有 import。 不能引第三方库,也不能直接用 fs、path 这些 Node 内置模块。所有能力都从 run(api) 的入参走——文件操作用 api.fs, 网络请求用 api.net.fetch。
沙箱挡的是手滑,不是恶意
这些限制的目的是让写错的脚本不至于毁掉无关文件,不是用来安全地运行别人的代码。 api.db.exec 能跑任意 SQL、api.net.fetch 能连任意地址;开启 api.shell 之后更是能执行任意本地命令。 运行来路不明的脚本前先把代码读一遍。
沙箱里能直接用的全局只有:console、setTimeout、clearTimeout、 URL、URLSearchParams、TextEncoder、TextDecoder,以及 JS 自带的 Math、JSON、Date、Map、Set 等标准对象。
顶层代码会在「列出脚本」时执行。 应用扫描脚本列表时会把每个文件求值一遍, 好读出 meta。所以顶层只放常量和函数声明,别在顶层写有副作用的逻辑—— 写了的话,光是打开「自定义脚本」页就会触发它。
// 顶层:可以
const DELAY_MS = 3000
// 顶层:不要这么写,打开页面就会执行
// deleteEverything()
exports.run = async (api) => {
// 有副作用的事情写在这里
}顶层求值有 5 秒超时,写死循环会让脚本在列表里显示为加载失败。
脚本放在哪
我的脚本存在用户数据目录的 scripts/ 下,一个 .js 文件就是一个脚本。 点页面右上角「打开脚本目录」可以直接跳过去。同一个目录里还有一份 README.md,是随版本更新的 API 速查,内容与本站的 API 参考 对应。
只有 .js 结尾的文件会被当成脚本,所以往里放笔记、数据文件都不影响。