跳到正文

自动化与投递 ​

没有守护进程。调度交给主机调度器;工具提供生成器和 --print 模式,未经确认不会写入任何内容。同一条报告流水线可从 cron、systemd、Task Scheduler 或 CI 任务运行。

相关页面:报告与差异、数据源与配额、抓取与审计、MCP 与智能体技能。

安装或预览计划任务 ​

bash
lv24-seo schedule install --kind weekly --cron "0 6 * * 1" --config ./seo.toml --print
lv24-seo schedule install --kind daily --cron "0 6 * * *" --config ./seo.toml
lv24-seo schedule print --cron "0 6 * * 1" --target systemd --json

默认 weekly 为 0 6 * * 1,daily 为 0 6 * * *。生成的命令是 report weekly --send --json;daily 类型会追加 --days 1 --lag-days 0。绝对 --config 路径和配置目录会作为工作目录写入,因此自定义文件名、带空格的路径或同一目录中的多个配置都能继续工作。

schedule install 没有 --target 标志:它会检测主机后端。schedule print 接受 --target cron|systemd|windows,只渲染而不触碰主机。没有 schedule status 命令;请用 crontab -l、systemctl --user list-timers 或任务计划程序检查主机。

产物 ​

目标产物位置时区行为
cron带 CRON_TZ=<zone> 和 cd 前缀的受管 crontab 块当前用户的 crontabCRON_TZ 受 Vixie/ISC cron 支持;其他守护进程使用主机时间
systemd用户单元 lv24-seo-<kind>.service 和 .timer~/.config/systemd/user(感知 XDG)OnCalendar 包含配置的 IANA 时区
windowsUTF-16 Task Scheduler XML%APPDATA%\lv24-seo\scheduleStartBoundary 携带解析后的 UTC 偏移

cron 块由 # >>> lv24-seo:<name> >>> 和 # <<< lv24-seo:<name> <<< 界定。重新安装会替换该任务的所有受管块。缺少结束标记的损坏块会被视为延伸到下一个受管标记或 EOF,因此 schedule install 会修复文件,而不是追加重复任务。

只有简单的 cron 形式(M H * * * 和 M H * * DOW)能转换为 systemd 或 Windows。其他形式会被拒绝,而不是静默改期。未知或不可用的时区会在安装前被拒绝。

安装结果始终带有 warnings 列表说明后端限制:cron 可能忽略 CRON_TZ,Windows XML 编码固定偏移而非 IANA 时区,因此季节性 DST 变化需要复核。Windows 使用 tzdata(Windows 自带)。systemd 通过 systemctl --user daemon-reload 和 systemctl --user enable --now 启用计时器。

建议频率 ​

任务时间原因
report weekly --send周一 06:00GSC 数据有 2–3 天延迟;周一较稳定
crawl --start URL每周,报告之后让抓取证据贴近报告窗口
auth status每周确认每个提供商令牌的存在与来源
CrUX 字段数据每周28 天滚动窗口;每日轮询没有额外价值

每个周期只保留一个计划任务。投递是至少一次,因此两个重叠的计划即使有账本也可能把同一份报告发送两次。

Email 与 Telegram ​

Email 使用 587 端口的 SMTP、STARTTLS 和会验证证书的 TLS 上下文。TLS 失败后绝不会登录。消息为 multipart/alternative:产品 HTML 模板加上相同内容的 78 列纯文本,主题为不超过 78 个字符的本地化单行文本。

模板是 600px 卡片,仅使用内联 CSS,没有外部图片、样式表、脚本、跟踪像素或远程字体。未知 KPI 显示为本地化的“无数据”,而不是 0。Metrika 显示为会话,不是点击。问题部分为空时会说明未提供问题数据,而不是声称站点干净。限制和警告会去重;提供商原文保持原语言,并在报告本地化时标注。页脚包含属性 id、UTC 生成时间和“generated by lv24-seo”。

Telegram 通过 Bot API sendMessage 发送相同的 78 列本地化文本。HTTP 4xx/5xx、超时和格式错误的响应都会标记为 failed,绝不记录为已发送。

只有 email 和 Telegram 两个渠道。没有 Resend 或 Brevo 适配器,也没有 --channel github。

在 seo.toml 的 [report.email] 和 [report.telegram] 中配置投递。SMTP 密码和 Telegram 机器人令牌来自 auth set --provider smtp|telegram,绝不来自配置文件。--send 是必需的;生成的计划任务已经包含它。

幂等性 ​

报告投递通过 sends 账本实现幂等,账本在 (kind, property, period, channel, content_hash) 上唯一。哈希覆盖标题和各个部分以及规范化后的渲染语言;generated_at 和诊断信息不参与。英语不在哈希中包含语言,因此升级不会重发已经投递的英语周期。

only_on_change 在内容哈希已投递时跳过发送(already_sent)。当没有任何变化达到 report.thresholds 时,实质性门槛会跳过发送(no_material_change)。门槛先于语言哈希运行,因此当周期没有实质性变化时,单纯切换语言仍可能被抑制。

投递是每渠道至少一次。传输结果不明确时会标记 failed 且不记录,因此下一次运行可能重复投递。进程崩溃后 SMTP 和 Bot API 都不提供恰好一次。数据库会串行化投递尝试,并可能阻塞其他写入者直到传输超时。

写入闸门 ​

提供商写入与报告投递分离。CLI 使用试运行加显式应用:

  1. 设置 LV24_SEO_WRITE_SECRET 并用 --allow-write 运行写入命令。没有密钥时闸门以 WRITE_DISABLED 拒绝。
  2. 检查计划、plan_hash 和 confirm_token。令牌是对动作、目标、计划哈希和过期时间的 HMAC,有效期为 300 秒。
  3. 使用相同标志加 --confirm <token> 应用。计划变化、密钥错误、令牌格式错误或过期都会以 CONFIRM_REQUIRED 失败。

工作区初始化后,闸门支持 pending-to-sent 幂等声明:CLI 附加 SQLite 账本,提供商调用失败会释放声明并允许重试;已完成或仍在进行中的声明视为重复并返回 skipped。没有数据目录时仍会应用,但信封会警告:在令牌五分钟有效期内没有重放保护。试运行不打开账本,也不创建数据库。崩溃可能留下没有 TTL 的 pending 声明(0.5.2),在操作员释放前会被视为进行中。

0.5.2 中只有 IndexNow 真正提交。GSC 站点地图提交和 Yandex 重新抓取会以 WRITE_DISABLED 拒绝,而不是假装成功。MCP 写入工具要求 allow_write=true;它们在本构建中的处理器也未接通,因此返回 WRITE_DISABLED。

GitHub Actions ​

产品仓库提供每周 workflow 配方:examples/github-actions/seo-weekly.yml。把它复制到你的站点仓库,而不是工具仓库。

yaml
on:
  schedule:
    - cron: "0 6 * * 1"
  workflow_dispatch:
permissions:
  contents: read

该配方使用标准 ubuntu-latest 运行器、单个任务、15 分钟超时、concurrency 组和较短的产物保留期。在公开仓库加标准运行器时成本为 $0。私有仓库会消耗包含或计费的 Actions 分钟和存储;更大运行器、矩阵和付费附加项不属于零支出路径。

任务通过 actions/cache 恢复 data/seo.sqlite3(以及 -wal 和 -shm),创建数据目录,然后运行:

bash
uvx --from lv24-seo lv24-seo report weekly --send --json

提供商和投递凭据来自仓库 secret。非秘密标识符保留在已提交的 seo.toml 中。GitHub cron 始终是 UTC,因此要显式换算目标本地时间。

时区 ​

report.timezone 是 IANA 时区(默认 Europe/Minsk)。它驱动报告和 stats 窗口、MCP 默认窗口以及本地日期边界。提供商数据仍按日期存储,不做转换。

调度后端在支持时应用该时区,不支持时给出警告。无效时区会在配置校验时以 CONFIG_INVALID 失败,绝不会被静默替换。DST 转换后要复核 Windows 任务,并在依赖 CRON_TZ 前确认已安装的 cron 守护进程支持它。

Source: _source/engine-scheduling.md, _source/engine-cli.md, _source/engine-config.md.