跳到主要内容

飞书机器人热点推送

本文说明 ai-hot-trend 当前已接入的飞书群机器人热点推送:它如何从项目热点源拉取数据、如何完成鉴权和签名、如何由 Vercel 每天定时触发,以及需要怎样配置。

适用范围​

  • 推送目标是飞书群里的自定义机器人(Webhook),不是向个人私聊直接发送消息。
  • 需要在飞书群中添加自定义机器人,并取得 Webhook 地址。
  • 个人飞书账号通常也可在自己创建或有管理权限的群中添加机器人;如果群设置里没有“自定义机器人”,说明当前租户策略可能已限制该能力。

全链路流程​

text
Vercel Cron / 手动 HTTP 请求
|
v
GET or POST /api/notify/feishu/daily
|
+--> 校验 Authorization: Bearer <token>
| 或 x-cron-token
|
v
pushDailyTrendDigestToFeishu()
|
+--> 按配置的热点来源并行调用 queryTrendItems()
+--> 将各来源 Top N 热点拼成文本摘要
+--> 可选:使用机器人密钥生成 timestamp + sign
|
v
飞书自定义机器人 Webhook
|
v
飞书群消息

组件职责与原理​

1. 定时触发​

vercel.json 配置了:

json
{
"crons": [
{
"path": "/api/notify/feishu/daily",
"schedule": "0 1 * * *"
}
]
}

Cron 表达式使用 UTC:0 1 * * * 表示每天 UTC 01:00,即 Asia/Shanghai 的每天 09:00。 Vercel 调用 /api/notify/feishu/daily 后,会进入 Hono 的通知路由。路由同时支持 GET 和 POST,因此既能被 Vercel Cron 调用,也便于本地或 CI 手动验证。

2. 接口鉴权​

推送接口位于:

text
/api/notify/feishu/daily

请求需要以下任意一种请求头:

http
Authorization: Bearer <FEISHU_PUSH_CRON_TOKEN>

或:

http
x-cron-token: <FEISHU_PUSH_CRON_TOKEN>

服务端依次读取:

  1. FEISHU_PUSH_CRON_TOKEN
  2. CRON_SECRET(兼容 Vercel 的常用变量名)

只要配置了 token,缺失或不匹配的请求会返回 401 Unauthorized。生产环境未配置 FEISHU_PUSH_CRON_TOKEN 或 CRON_SECRET 时,服务会拒绝执行推送,避免公开接口被滥用。

3. 热点数据聚合​

推送服务复用现有的 queryTrendItems(),不额外维护第二套爬取或缓存逻辑。 每个来源都会按相同参数拉取热点:

  • source:热点来源,例如 ai、github、npm、weibo、zhihu
  • period:时间范围,支持 today、week、month
  • limit:每个来源最多推送多少条
  • offset:固定为 0,即只推送当前排行榜前 N 条

来源请求会并行执行。某个来源失败时,其他来源仍会正常推送;消息会在该来源位置标记“拉取失败”,接口响应中的 failedSources 也会列出失败来源,方便从 Vercel 日志排查。

4. 消息格式​

当前使用飞书 text 消息,不依赖卡片消息模板。消息内容按来源分组,包含:

  • 推送标题与时间范围
  • 按 FEISHU_DAILY_TIMEZONE 格式化的更新时间
  • 每个来源的名称
  • 热点排名、标题、星标/热度字段与原始链接

标题超过 56 个字符会截断,避免单条消息过长。

5. 飞书 Webhook 与签名​

服务端向 FEISHU_BOT_WEBHOOK_URL 发送 JSON:

json
{
"msg_type": "text",
"content": {
"text": "每日热点推送内容"
}
}

如果配置了 FEISHU_BOT_SECRET,会附加:

json
{
"timestamp": "Unix 秒级时间戳",
"sign": "HMAC-SHA256 Base64 签名"
}

签名的目的,是让飞书确认消息来自持有机器人密钥的服务端。仅在飞书机器人安全设置中开启“签名校验”时填写 FEISHU_BOT_SECRET;未开启时留空即可。

配置步骤​

1. 在飞书创建机器人​

  1. 创建或进入目标群聊。
  2. 在群设置中打开“机器人”或“群机器人”。
  3. 添加“自定义机器人”。
  4. 复制机器人 Webhook 地址。
  5. 建议启用“签名校验”,并保存机器人密钥。

Webhook 和密钥都属于敏感信息,不要提交到 Git 仓库,也不要写入前端环境变量(例如 NEXT_PUBLIC_*)。

2. 配置项目环境变量​

在部署平台和本地 .env 中配置:

bash
# 必填:飞书机器人 Webhook
FEISHU_BOT_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxxx

# 可选:仅在飞书机器人开启签名校验后填写
FEISHU_BOT_SECRET=

# 建议必填:保护 /api/notify/feishu/daily 的随机长 token
FEISHU_PUSH_CRON_TOKEN=replace-with-a-long-random-token

# 可选:默认 ai,github,npm,weibo,zhihu
FEISHU_DAILY_SOURCES=ai,github,npm,weibo,zhihu

# 可选:today | week | month,默认 today
FEISHU_DAILY_PERIOD=today

# 可选:每个来源的 Top N,默认 5,代码上限为 10
FEISHU_DAILY_LIMIT=5

# 可选:消息显示时间使用的时区,默认 Asia/Shanghai
FEISHU_DAILY_TIMEZONE=Asia/Shanghai

FEISHU_DAILY_SOURCES 仅接受项目已注册的热点来源:

text
github,npm,vue,react,node,ai,python,component,zhihu,juejin,v2ex,weibo

包含不支持的来源或非法的 period/limit 时,接口会返回结构化错误,不会静默跳过。

3. 配置 Vercel​

在 Vercel 项目的 Production 环境变量中设置:

  • FEISHU_BOT_WEBHOOK_URL
  • FEISHU_PUSH_CRON_TOKEN
  • FEISHU_BOT_SECRET(如果开启签名校验)
  • 其他可选的 FEISHU_DAILY_* 配置

为了让 Vercel Cron 的请求通过鉴权,推荐同时设置:

bash
CRON_SECRET=<与 FEISHU_PUSH_CRON_TOKEN 相同的值>

这样 Vercel Cron 使用 Authorization: Bearer <CRON_SECRET> 调用时,项目可以直接校验通过。也可以只使用 CRON_SECRET,因为服务会将它作为 FEISHU_PUSH_CRON_TOKEN 的回退值。

部署后,Vercel 会读取根目录的 vercel.json 并按计划调用接口。

本地验证​

先启动开发服务:

bash
pnpm dev

再触发一次推送:

bash
curl -X POST "http://localhost:3000/api/notify/feishu/daily" \
-H "Authorization: Bearer replace-with-a-long-random-token"

成功时会返回类似:

json
{
"success": true,
"data": {
"pushedAt": "2026-07-20T01:00:00.000Z",
"period": "today",
"sources": ["ai", "github", "npm", "weibo", "zhihu"],
"failedSources": []
}
}

常见响应:

  • 401:请求未携带 token,或 token 不匹配。
  • 502:Webhook 地址/签名配置错误、飞书返回失败。
  • success: true 且 failedSources 非空:飞书消息已发出,但其中部分热点来源拉取失败。

不同部署平台的定时任务​

Vercel:vercel.json 中的 crons 是什么​

vercel.json 的 crons 允许在 Vercel 项目中以配置方式声明定时任务。它不会在 Vercel 上常驻运行一段后台脚本,而是让 Vercel 的调度器在指定时间向已部署应用的 HTTP 路径发起请求。 本项目的配置是:

json
{
"crons": [
{
"path": "/api/notify/feishu/daily",
"schedule": "0 1 * * *"
}
]
}

它表示每天 UTC 01:00(北京时间 09:00),Vercel 会向生产环境的 /api/notify/feishu/daily 发起一次 GET 请求。随后由 Hono 路由执行热点查询、消息拼装和飞书 Webhook 推送。 换句话说,crons 只负责“何时调用”,业务逻辑仍在项目服务端。修改 vercel.json 后要重新部署,Vercel 才会读取新计划。 为保护接口,请在 Vercel Production 环境变量中同时设置:

bash
FEISHU_PUSH_CRON_TOKEN=<随机长 token>
CRON_SECRET=<与 FEISHU_PUSH_CRON_TOKEN 相同的值>

Vercel Cron 会携带 CRON_SECRET 作为 Bearer token;本项目也会把 CRON_SECRET 作为 FEISHU_PUSH_CRON_TOKEN 的回退值进行校验。

官方文档:https://vercel.com/docs/cron-jobs

Vercel 部署配置清单​

在 Vercel 项目中打开 Settings -> Environment Variables,并在 Production 环境配置以下变量:

变量是否必填说明
FEISHU_BOT_WEBHOOK_URL必填飞书群自定义机器人的完整 Webhook 地址
FEISHU_PUSH_CRON_TOKEN必填保护推送接口的随机长 token
CRON_SECRET必填与 FEISHU_PUSH_CRON_TOKEN 保持完全相同,供 Vercel Cron 鉴权
FEISHU_BOT_SECRET可选仅当飞书机器人开启签名校验时填写
FEISHU_DAILY_SOURCES可选逗号分隔的热点来源列表
FEISHU_DAILY_PERIOD可选today、week 或 month;默认 today
FEISHU_DAILY_LIMIT可选每个来源的推送条数;默认 5,上限 10
FEISHU_DAILY_TIMEZONE可选消息中显示时间的时区;建议 Asia/Shanghai

推荐的 Production 配置:

bash
FEISHU_BOT_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxxx
FEISHU_PUSH_CRON_TOKEN=replace-with-a-long-random-token
CRON_SECRET=replace-with-the-same-token
FEISHU_DAILY_SOURCES=ai,github,npm,weibo,zhihu
FEISHU_DAILY_PERIOD=today
FEISHU_DAILY_LIMIT=5
FEISHU_DAILY_TIMEZONE=Asia/Shanghai

不要把 Webhook、机器人密钥或 token 配置为 NEXT_PUBLIC_* 环境变量,否则敏感信息可能暴露给浏览器端。

可推送的热点来源​

FEISHU_DAILY_SOURCES 可从以下来源中任选一个或多个,并使用英文逗号分隔:

text
ai,github,npm,vue,react,node,python,component,zhihu,juejin,v2ex,weibo
值推送内容
aiAI 生态趋势
githubGitHub 热门仓库
npmnpm 包趋势
vue、react、node、python对应技术生态趋势
component组件库趋势
zhihu、juejin、v2ex、weibo社区与内容热点

例如,只推送 AI、GitHub 和 Python 的当日热点,每个来源取前 10 条:

bash
FEISHU_DAILY_SOURCES=ai,github,python
FEISHU_DAILY_PERIOD=today
FEISHU_DAILY_LIMIT=10

未配置 FEISHU_DAILY_SOURCES 时,默认推送 ai,github,npm,weibo,zhihu。

推送时间配置​

时间由根目录 vercel.json 的 schedule 控制,不通过环境变量设置:

json
{
"path": "/api/notify/feishu/daily",
"schedule": "0 1 * * *"
}

Vercel Cron 使用 UTC;当前 0 1 * * * 表示每天 UTC 01:00,即北京时间每天 09:00。常见时间换算如下:

北京时间schedule
每天 08:000 0 * * *
每天 09:000 1 * * *
每天 12:3030 4 * * *
每天 18:000 10 * * *

修改 vercel.json 后需要重新部署,新的 Cron 计划才会生效。FEISHU_DAILY_TIMEZONE 只影响飞书消息内显示的时间,不影响 Vercel 的实际调度时间。

部署后手动验证​

配置保存、重新部署完成后,可用以下命令手动触发一次推送:

bash
curl -X POST "https://your-domain.example.com/api/notify/feishu/daily" \
-H "Authorization: Bearer your-feishu-push-cron-token"

飞书群收到消息且接口返回 success: true,表示 Webhook、热点来源和 Vercel 环境变量均已生效。若返回 401,检查 Authorization 中的 token 是否与 FEISHU_PUSH_CRON_TOKEN 一致;若返回 502,检查飞书 Webhook、飞书签名密钥和 Vercel Functions 日志。

Cloudflare Workers:推荐作为定时触发器​

当前项目是 Next.js + Node.js + Prisma + MySQL。最稳妥的 Cloudflare 方案是部署一个小型 Worker,使用 Cloudflare Cron Trigger 定时调用当前应用的推送接口,而不是立刻把整套应用迁移到 Worker。 这样热点查询、缓存、MySQL 与飞书推送逻辑仍只维护一份;Cloudflare 只负责调度和鉴权转发。主应用可以继续部署在 Vercel、其他云平台或自建服务器。 新建独立 Worker 项目,创建 wrangler.toml:

toml
name = "ai-hot-trend-scheduler"
main = "src/index.ts"
compatibility_date = "2026-07-20"

[triggers]
crons = [ "0 1 * * *" ]

[vars]
APP_URL = "https://your-app.example.com"

Cloudflare Cron Trigger 使用 UTC,因此 0 1 * * * 同样对应北京时间每天 09:00。 创建 src/index.ts:

ts
interface Env {
APP_URL: string
FEISHU_PUSH_CRON_TOKEN: string
}

export default {
async scheduled(_controller: ScheduledController, env: Env, ctx: ExecutionContext) {
ctx.waitUntil((async () => {
const response = await fetch(`${env.APP_URL}/api/notify/feishu/daily`, {
method: 'POST',
headers: {
Authorization: `Bearer ${env.FEISHU_PUSH_CRON_TOKEN}`,
},
})

if (!response.ok) {
throw new Error(`Daily Feishu push failed: ${response.status}`)
}
})())
},
} satisfies ExportedHandler<Env>

设置 Worker 密钥并部署:

bash
npx wrangler secret put FEISHU_PUSH_CRON_TOKEN
npx wrangler deploy

输入的 token 必须与主应用的 FEISHU_PUSH_CRON_TOKEN 相同。APP_URL 可放在 [vars];如果不希望公开域名,也可通过 npx wrangler secret put APP_URL 设置。 本地测试 scheduled handler:

bash
npx wrangler dev --test-scheduled
curl "http://localhost:8787/__scheduled"

如果要把整个 Next.js 应用直接部署到 Cloudflare Workers,需要额外接入 Next.js 的 Cloudflare 运行时适配,并重新评估 Prisma/MySQL 的兼容性、数据库连接池和网络访问。这是部署架构迁移,不是增加 Cron Trigger 就能完成的改动。

官方文档:https://developers.cloudflare.com/workers/configuration/cron-triggers/

自建服务器:使用 systemd timer​

自建 Linux 服务器时,推荐让 Next.js 应用继续作为常驻服务运行,再用 systemd timer 每天调用本机 API。不要把定时器嵌入 Node 进程,这样应用重启、部署和服务器恢复时更容易管理。

企业自建部署的完整链路​

企业自建场景中,建议把“Web 应用运行”和“每天触发任务”拆成两个由 systemd 管理的单元:

text
浏览器 / API 调用
|
v
Nginx(TLS、域名、反向代理)
|
v
Next.js 常驻服务(systemd service,监听 127.0.0.1:3000)
|
v
Hono: /api/notify/feishu/daily
|
+--> queryTrendItems() --> 外部热点来源
|
+--> 飞书机器人 Webhook

每天 09:00 Asia/Shanghai
|
v
systemd timer
|
v
ai-hot-trend-feishu-push.service(一次性 curl)
|
v
http://127.0.0.1:3000/api/notify/feishu/daily

这里有两个不同的 systemd 单元:

  • ai-hot-trend.service:长期运行的 Next.js 应用进程。
  • ai-hot-trend-feishu-push.timer:保存“每天何时执行”的计划,并在时间到达时启动一次性的 ai-hot-trend-feishu-push.service。

业务代码只在 Next.js 服务中执行一次;timer 不直接访问热点源或飞书,它只通过本机 HTTP 调用现有 API。这使手动触发、Vercel Cron、Cloudflare Worker Cron 和自建服务器的行为保持一致。

1. systemd timer 是什么,如何理解​

systemd 是大多数现代 Linux 发行版的服务管理器。它不仅可以拉起常驻进程,也可以管理“在指定时间启动某个服务”的任务。 可以把它理解为:

  • .service 文件定义“要做什么工作”。对于本项目,工作是调用一次推送 API。
  • .timer 文件定义“何时执行这个工作”。对于本项目,工作日或每天的 09:00 触发一次。
  • systemctl enable 让该计划在服务器重启后仍然生效。
  • journalctl 记录每次执行的标准输出、错误和退出状态。

与传统 crontab 相比,systemd timer 更容易查看下次执行时间、追踪失败日志、依赖网络就绪,并可通过 Persistent=true 补跑服务器停机期间错过的一次任务。 需要特别区分:这里推荐使用的是“操作系统级 systemd timer”;不推荐的是“嵌在 Next.js/Node 进程里的应用内定时器”。两者不是同一种方案。

2. 如何让 Next.js 常驻运行​

生产环境中,先在部署目录构建项目,然后由 systemd 负责启动和重启 pnpm start。示例假定应用位于 /srv/ai-hot-trend,运行用户为 ai-hot-trend,并由 Nginx 反向代理。 创建运行用户和部署目录后,创建 /etc/systemd/system/ai-hot-trend.service:

ini
[Unit]
Description=AI Hot Trend Next.js application
After=network.target

[Service]
Type=simple
User=ai-hot-trend
Group=ai-hot-trend
WorkingDirectory=/srv/ai-hot-trend
Environment=NODE_ENV=production
EnvironmentFile=/etc/ai-hot-trend.env
Environment=PATH=/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/bin/env pnpm start
Restart=always
RestartSec=5
TimeoutStopSec=30
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target

pnpm start 会运行项目的 next start,Next.js 进程因此持续监听服务端口。若服务器上的 pnpm 不在 /usr/local/bin 或 /usr/bin,请先执行 command -v pnpm,再按实际路径调整 PATH 或 ExecStart。 启用应用服务:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now ai-hot-trend.service
sudo systemctl status ai-hot-trend.service
sudo journalctl -u ai-hot-trend.service -f

部署更新的推荐顺序是:拉取新代码、安装依赖、执行 pnpm build、确认迁移成功、然后执行 sudo systemctl restart ai-hot-trend.service。不要在运行中的进程目录里直接覆盖文件,也不要依赖手工在 SSH 会话里启动 pnpm start。 如果使用 Nginx,只将 Next.js 监听到回环地址,再由 Nginx 对外提供 HTTPS。例如反向代理的上游使用:

nginx
proxy_pass http://127.0.0.1:3000;

推送接口由 timer 直接访问 127.0.0.1:3000,不需要经过公网域名或 Nginx。可以在 Nginx 中额外拒绝外部访问 /api/notify/feishu/daily,保留 timer 的本机访问路径,进一步缩小暴露面。

3. 如何每天调用 API​

timer 不会自己执行 HTTP;它负责按时间启动一个 one-shot service。该 service 使用 curl 向本机接口发送带 Bearer token 的 POST 请求:

text
09:00 到达
-> systemd 启动 ai-hot-trend-feishu-push.service
-> service 从 /etc/ai-hot-trend.env 读取 token
-> curl POST 127.0.0.1:3000/api/notify/feishu/daily
-> Hono 校验 token,查询热点并推送飞书
-> systemd 将成功或失败写入 journal

下面的 .service 与 .timer 配置就是这一流程的实现。建议先执行一次 service 验证接口、token 和飞书 Webhook 都正确,再启用 timer:

bash
sudo systemctl start ai-hot-trend-feishu-push.service
sudo journalctl -u ai-hot-trend-feishu-push.service -n 100 --no-pager

确认无误后再执行:

bash
sudo systemctl enable --now ai-hot-trend-feishu-push.timer
systemctl list-timers ai-hot-trend-feishu-push.timer

--retry 2 只处理短暂网络故障;如果 Next.js 服务在执行时间不可用,任务会以失败状态结束并留下日志。因此生产环境仍应对该 unit 的失败日志进行监控和告警。

4. 为什么不建议使用应用内定时器​

这里不推荐的是在 Next.js 代码里使用 setInterval、node-cron 或类似方案直接执行每日推送。它在单实例的临时工具中可以工作,但不适合通常的企业生产部署,主要原因如下:

  • 多实例会重复推送:扩容为两个或多个 Next.js 实例后,每个实例都会注册自己的定时器,除非再实现数据库锁或分布式选主。
  • 重启会错过任务:发布、崩溃、机器重启或进程滚动重启时,内存中的 timer 会消失;恢复后通常不会知道是否错过了当天任务。
  • 调度与应用生命周期耦合:应用是否成功启动、热更新、进程管理器重拉、数据库暂时不可用,都可能改变 timer 的注册和执行时机。
  • 缺少系统级可观测性:应用日志通常只能说明代码执行过,难以像 systemd 那样直接查看任务状态、下次执行时间、退出码和独立日志。
  • 需要自行补齐可靠性能力:幂等、分布式锁、失败重试、错过任务补跑、超时控制和告警都要在应用代码中重新实现。

systemd timer 将调度可靠性交给操作系统,而 Next.js 只专注提供一次可鉴权、可重复调用的推送 API。这种分层更符合企业的部署和运维方式。 应用内定时器并非绝对不能用:若系统始终单实例、允许偶发漏推,且已经实现数据库锁、任务记录和监控,它可以作为简化方案。但对每日热点推送这类需要可追踪、可恢复的任务,推荐优先使用 systemd timer、云平台 Cron 或独立任务调度系统。 先准备生产环境变量文件,例如 /etc/ai-hot-trend.env:

bash
FEISHU_BOT_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxxx
FEISHU_BOT_SECRET=
FEISHU_PUSH_CRON_TOKEN=replace-with-a-long-random-token
FEISHU_DAILY_SOURCES=ai,github,npm,weibo,zhihu
FEISHU_DAILY_PERIOD=today
FEISHU_DAILY_LIMIT=5
FEISHU_DAILY_TIMEZONE=Asia/Shanghai

限制文件权限:

bash
sudo chown root:root /etc/ai-hot-trend.env
sudo chmod 600 /etc/ai-hot-trend.env

创建 /etc/systemd/system/ai-hot-trend-feishu-push.service:

ini
[Unit]
Description=Push daily AI hot trends to Feishu
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/ai-hot-trend.env
ExecStart=/usr/bin/curl --fail --silent --show-error --max-time 120 --retry 2 --retry-delay 10 -X POST http://127.0.0.1:3000/api/notify/feishu/daily -H "Authorization: Bearer \${FEISHU_PUSH_CRON_TOKEN}"

该任务调用 127.0.0.1:3000,不会经过公网反向代理。若应用端口不同,请同步修改 URL。 创建 /etc/systemd/system/ai-hot-trend-feishu-push.timer:

ini
[Unit]
Description=Run the daily Feishu trend push at 09:00 Asia/Shanghai

[Timer]
OnCalendar=*-*-* 09:00:00 Asia/Shanghai
Persistent=true
RandomizedDelaySec=5m
Unit=ai-hot-trend-feishu-push.service

[Install]
WantedBy=timers.target

启用并验证:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now ai-hot-trend-feishu-push.timer
systemctl list-timers ai-hot-trend-feishu-push.timer
sudo systemctl start ai-hot-trend-feishu-push.service
sudo journalctl -u ai-hot-trend-feishu-push.service -n 100 --no-pager

Persistent=true 会在服务器错过执行时间后、恢复运行时补跑一次。RandomizedDelaySec=5m 用于避开整点并发;如必须精确在 09:00 执行,可以删除这一行。 传统 crontab 也能实现定时调用,但需要自行处理环境变量、日志和错过任务后的补跑。对生产环境而言,systemd timer 更适合这个每日任务。

常见问题​

推送接口能访问但飞书没有消息​

依次检查:

  1. FEISHU_BOT_WEBHOOK_URL 是否为当前群机器人的完整地址。
  2. 飞书机器人是否启用了签名校验;若启用,FEISHU_BOT_SECRET 是否一致。
  3. Vercel 的环境变量是否配置在 Production 环境,并在重新部署后生效。
  4. Vercel Functions 日志中的飞书返回错误码和 message。

Vercel Cron 返回 401​

将 Vercel 的 CRON_SECRET 与项目的 FEISHU_PUSH_CRON_TOKEN 设为相同的随机值,然后重新部署。不要用 URL 参数传 token,因为 URL 可能被日志记录。

想调整推送时间​

修改根目录 vercel.json 的 cron 表达式并重新部署。Vercel 的 cron 表达式使用 UTC;例如北京时间每天 08:30 对应 UTC 30 0 * * *。