Skip to content

Repository files navigation

Sub-Tracker icon

📱 Sub-Tracker

eSIM 保号 & 订阅费用管理看板

基于 Cloudflare Workers + KV 构建,零成本、高颜值、极度安全的个人资产管理面板。

告别忘记充值、眼睁睁看着靓号被回收的惨痛经历!前端展示、后端 API、定时提醒逻辑,全部浓缩在一个 Worker 内。

✨ 核心功能

  • 🔐 动态密码登录:不在代码中写死密码,6位动态验证码,可通过 Telegram / Bark / 企业微信 / Webhook 接收
  • 📱 eSIM 保号管理:号码到期监控、一键续期、智能区域识别
  • 💳 订阅费用管理:分类管理各类订阅服务,费用统计
  • 💰 话费余额管理:余额追踪、月租/扣费日管理、预计停机日计算、充值/校正
  • 智能到期提醒:支持自定义提前提醒天数(30/15/7/3/1/当天),话费停机提醒
  • 📣 多渠道推送:Telegram、Bark、企业微信机器人、通用 Webhook
  • 🔄 一键续期:发完保号短信后,一键续期,自动顺延到期日
  • 🧾 操作历史:记录最近 100 条新增、更新、删除、续期、充值和导入操作
  • 📊 增强统计:按货币、分类统计月度/年度支出
  • 📦 PWA 支持:Manifest + Service Worker,可添加到主屏幕并缓存应用壳
  • 🌍 智能区域识别:输入带区号的号码,自动匹配 ISO 国家/地区代码
  • 🎨 毛玻璃 UI:深色渐变背景 + Glassmorphism 设计,手机/PC 自适应

🚀 部署

方式一:Deploy 按钮(推荐新用户)

适合想直接使用、不关心代码的用户。点击后会自动 Fork 到你的账号并部署。

Deploy to Cloudflare

⚠️ 如果提示"已存在同名仓库",换个名字即可(如 my-sub-tracker)。

方式二:Connect to Git(推荐仓库 Owner)

适合 Fork 过仓库或自己维护仓库的用户。

  1. 登录 Cloudflare Dashboard
  2. 左侧 → Workers & PagesCreate Application
  3. 选择 Connect to Git → 授权 GitHub → 选择仓库
  4. Build 配置:
    • Root directory: 留空
    • Build command: 留空npm run build
    • Entry point: src/index.js
  5. 点击 Save and Deploy
  6. 部署后进入 SettingsVariables and Secrets,至少添加一种通知渠道:
    • TG_BOT_TOKEN — Telegram Bot Token
    • TG_CHAT_ID — Telegram Chat ID
    • 或配置 Bark / 企业微信 / Webhook,见下方「推送配置指南」

此后 push 到 main 分支会自动重新部署。

方式三:Wrangler CLI(本地开发)

需要 Node.js 22 或更高版本。

git clone https://github.com/imwarn/sub-tracker.git && cd sub-tracker
npm install
npx wrangler login
npx wrangler dev          # 本地开发
npx wrangler deploy       # 部署

🔑 环境变量

变量名 说明 配置方式
TG_BOT_TOKEN Telegram Bot Token Deploy 时填写 / CF Dashboard / KV
TG_CHAT_ID Telegram Chat ID 同上
DEFAULT_NOTIFY_CHANNEL 普通提醒默认推送通道:all / telegram / bark / wecom / webhook,默认 all 可选
AUTH_NOTIFY_CHANNEL 登录验证码推送通道:telegram / bark / wecom / webhook 可选
BARK_KEY / BARK_URL Bark 推送 Key 或完整推送 URL 可选
BARK_SERVER Bark 自建服务地址,默认 https://api.day.app 可选
WECOM_WEBHOOK_URL 企业微信机器人 Webhook,兼容 WECHAT_WORK_WEBHOOK_URL 可选
WEBHOOK_URL 通用 Webhook URL
ALLOWED_ORIGIN CORS 允许的跨域来源(逗号分隔多域名),不填则仅允许同源请求

代码优先读取 Worker 环境变量,其次读 KV 数据库。通知渠道至少配置一种即可。

CORS 跨域配置(ALLOWED_ORIGIN)

默认情况下,Sub-Tracker 仅允许同源请求(即前端和 API 在同一域名下),无需额外配置。

如果你的 Worker 绑定了自定义域名,或需要从其他域名访问 API,需设置 ALLOWED_ORIGIN

场景 ALLOWED_ORIGIN 值 说明
单域名 https://sub.example.com 只允许该域名跨域访问
多域名(逗号分隔) https://sub.example.com, https://sub2.example.com 绑定了多个自定义域名
多域名(空格分隔) https://sub.example.com https://sub2.example.com 同上,两种写法均可
不设置 留空 默认行为:仅允许同源请求(推荐)

Cloudflare Workers 绑定多域名:

在 CF Dashboard → Workers → Settings → Domains & Routes 中,一个 Worker 可以绑定多个自定义域名和路由。 例如同时绑定了 sub.example.comtracker.mysite.com,则设置:

ALLOWED_ORIGIN = https://sub.example.com, https://tracker.mysite.com

注意: 没有配置 ALLOWED_ORIGIN 时,CORS 策略默认为同源限制。如果从 a.com 的页面请求 b.com 的 Worker API,会被浏览器拦截。绝大多数场景不需要设置此项(前端和 API 同域部署)。

推送配置指南

🟢 已验证 🟡 未验证

Telegram 🟢

  1. @BotFather 创建 Bot,得到 TG_BOT_TOKEN
  2. 给 Bot 发一条消息,再通过 @userinfobot 或 Bot API 获取 TG_CHAT_ID
  3. 未指定单一默认通道时,登录验证码会优先走 Telegram

Bark 🟢

  1. iOS 安装 Bark,复制设备 Key
  2. 设置 BARK_KEY=<你的 Key>;如果使用自建 Bark 服务,再设置 BARK_SERVER=https://你的服务地址
  3. 也可以直接设置完整推送地址 BARK_URL=https://api.day.app/<key>

三个变量的优先级:BARK_URL > BARK_KEY + BARK_SERVER > 默认服务器

配置方式 变量 说明
最简(官方服务器) BARK_KEY 自动拼接为 https://api.day.app/<key>
自建服务器 BARK_KEY + BARK_SERVER 拼接为 <BARK_SERVER>/<key>
完整地址 BARK_URL 直接使用,忽略 BARK_KEYBARK_SERVER

企业微信机器人 🟡

  1. 在企业微信群中添加「群机器人」
  2. 复制 Webhook 地址到 WECOM_WEBHOOK_URL
  3. 如果群里不只你一个人,不建议用它接收登录验证码

暂无企业微信环境,未实际验证。欢迎反馈测试结果。

通用 Webhook 🟢

设置 WEBHOOK_URL 后,系统会向该地址 POST JSON:

{
  "source": "sub-tracker",
  "title": "Sub-Tracker",
  "text": "去掉 HTML 标签后的纯文本",
  "html": "原始 HTML 消息",
  "timestamp": "2026-06-03T00:00:00.000Z"
}

已验证平台:飞书(Lark)自定义机器人 Webhook

⚠️ 部分 Webhook 平台支持关键词过滤(如飞书、企业微信),会根据消息内容决定是否放行。所有通知标题均包含 Sub-Tracker(如 【Sub-Tracker 到期提醒】),配置关键词白名单时添加 Sub-Tracker 即可保证推送正常接收。

ℹ️ 目前仅测试了部分通道组合,未覆盖所有排列。如遇到问题欢迎反馈。

默认通道与登录验证码

DEFAULT_NOTIFY_CHANNEL 控制普通提醒和测试通知:

  • 不填或设为 all:发送到全部已配置渠道,保持旧版行为
  • 设为 telegram / bark / wecom / webhook:只发送到指定渠道

AUTH_NOTIFY_CHANNEL 控制登录动态验证码:

  • 不填时:如果 DEFAULT_NOTIFY_CHANNEL 是单一通道,就沿用它;否则优先 Telegram,再使用第一个已配置渠道
  • 设置后:验证码只发送到指定渠道

如果不想用 Telegram 接收登录验证码,Bark 是最适合替代 TG 动态密码登录的通道,因为它通常只推到你的个人设备。企业微信和通用 Webhook 也能接验证码,但前者要确保机器人所在群只有可信成员,后者要确保你的 Webhook 端点私密、可靠且能即时提醒。


🔒 安全

  • CORS:动态 origin,不用 *,通过 ALLOWED_ORIGIN 精确控制
  • OTPcrypto.getRandomValues 生成,5 次错误锁定,60s 冷却,5min TTL
  • Session:UUID token,30 天 TTL,支持主动登出
  • URL 安全safeHref() 阻止 javascript: / data: / vbscript: 协议
  • XSS 防护:所有用户输入通过 esc() 做 HTML 转义(含日期、数字等防御性转义)
  • 导入去重:基于 id 的 Set 去重,保留原始 id,单次上限 500 条
  • KV 并发:read-modify-write 无锁,个人单用户场景可接受;多用户并发需迁移到 D1

❓ 常见问题 (FAQ)

Q1: 在「偏好设置」中删除了某个预设分类或区域,已添加的历史订阅数据会丢失或异常吗?

不会。

  • 预设分类与区域仅作为表单录入时的**「下拉建议推荐池」**,与具体订阅数据是完全解耦的。
  • 即使在偏好设置中删除了 域名 / SSL,已有订阅卡片依然正常展示该分类,图表统计依然正常聚合,全局搜索依然能正常搜出。
  • 录入表单下拉框具备智能兜底:会自动将当前所有卡片正在使用的自定义分类加入提示选项。

Q2: 历史数据中存储的旧版英文分类(如 Domain, AI, Streaming)是如何兼容与迁移的?

系统内置了代码级平滑映射引擎(CATEGORY_ALIASES):

  • 加载与展示时,系统会自动将 Domain 映射为 域名 / SSLAI 映射为 AI 服务Streaming 映射为 流媒体 等;
  • 编辑并重新保存该订阅时,数据会自动完成升级为最新的规范中文名;
  • 全局搜索支持中英文双向别名匹配:输入 Domaindomain域名SSL 均可直接检索出对应服务;
  • 无论你在偏好设置中如何增删预设标签,底层静态映射规则始终永久生效。

Q3: 点击偏好设置中的「恢复默认预设分类 / 区域」会发生什么?

  • 偏好设置中的预设标签列表会重置回官方出厂的 11 个分类或 18 个区域;
  • 如果你之前自行添加过额外的个性预设(如 健身 / 运动),它们会从“预设标签列表”中移除;
  • 所有已录入到订阅条目中的数据完全不受影响
  • 只有点击弹窗底部的【保存设置】后重置才会真正生效,误点时直接点击【取消】或按 ESC 即可放弃修改。

Q4: 货币与汇率管理是如何运作的?

  • ISO 4217 标准:所有币种严格按照国际 ISO 4217 3 位大写字母代码管理(涵盖 CNY, USD, EUR, TRY, ARS, NGN, EGP, BRL 等 60+ 种主流及跨区订阅币种);
  • 基准货币(Base Currency):支持在偏好设置中指定主统计货币(如 CNY 或 USD),面板总支出与年度预算均基于此动态折算;
  • 实时汇率同步:支持一键联网同步公网最新汇率中间价,也支持针对信用卡手续费或礼品卡汇率手动微调;
  • 表单智能检索:录入时支持按代码(USD)、中文名(美元土耳其里拉日元)或点选快速匹配带回。

Q5: 移动端体验如何?是否支持 PWA 添加到主屏幕?

  • 原生级体验:添加/编辑表单与偏好设置弹窗采用顶部标题与底部操作栏固定锁定、中间表单独立平滑滚动的三段式视口布局,在移动端呈现贴合底部的 Bottom-Sheet 卡片风格,键盘弹出时不遮挡保存按钮;
  • PWA 原生支持:内置 Manifest 与 Service Worker,使用手机 Safari 或 Chrome 打开时,点击「添加到主屏幕」即可像独立 App 一样沉浸式使用。

📄 许可证

MIT License

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages