## 背景 GitHub Actions 工作流 [Sync Strava Activities](https://github.com/yuler/yuler.dev/actions/workflows/sync-strava.yml)(每小时 :55 cron)自 **2026-06-30 22:19 UTC** 起持续失败。最后一次成功同步约为 **2026-06-30 21:23 UTC**。 示例失败 run:[actions/runs/28581001311](https://github.com/yuler/yuler.dev/actions/runs/28581001311) 本地执行 `pnpm sync:strava:activities` 复现相同错误。 ## 错误信息 ```text Strava API /athlete/activities failed (403): {"message":"Forbidden","errors":[{"resource":"Application","field":"Status","code":"Inactive"}]} ``` - `Inactive` **不是**仓库里的配置,而是 Strava API 返回的错误体(`errors[].code`) - 错误在 `src/utils/strava.ts` 的 `stravaFetch()` 中抛出,经 `scripts/sync-strava-activities.mjs` 打印 - Token refresh 通常能成功;失败发生在拉取 `/athlete/activities` 时,说明是 **OAuth 应用状态** 被 Strava 标记为不可用 ## 根因(Strava 政策变更) Strava Developer Program 更新(**2026-06-30 生效**): - **Standard Tier** 开发者必须有 **活跃的 Strava 订阅** 才能继续使用 API - 未满足条件时,应用状态变为 `Inactive`,API 返回 403 - 当前应用信息:Standard Tier,Client ID `212904`,Category Training,1/1 athletes ### 官方参考 - [An Update To Our Developer Program](https://communityhub.strava.com/insider-journal-9/an-update-to-our-developer-program-13428) - [Strava API FAQ(订阅与 Tier 说明)](https://communityhub.strava.com/developers-knowledge-base-14/strava-api-faq-12906) - [Strava API Policy](https://cdn-1.strava.com/legal/api_policy) - [API 设置页](https://www.strava.com/settings/api) - [订阅设置页](https://www.strava.com/settings/subscription) ## 当前站点影响 - 站点构建时只读本地 `data/strava/activities/*.json`,**展示不受影响** - 已有约 **68 条**活动缓存;**2026-06-30 之后的新运动不会自动同步** - 断的是自动同步管道,不是前端展示逻辑 相关实现: - Workflow: `.github/workflows/sync-strava.yml` - 同步脚本: `scripts/sync-strava-activities.mjs` - API 封装: `src/utils/strava.ts` - 博文记录: `src/content/posts/2026/app-strava.mdx` ## 已尝试 / 进展 - [x] 确认 GitHub Actions 与本地脚本逻辑正常 - [x] 重新 OAuth 授权(scope: `read,activity:read_all`)— 授权流程 OK,但应用仍为 Inactive(需先解决订阅) - [ ] 查找 **3 个月免费过渡码** 邮件 — **未找到**(见下文) ### 3 个月免费码说明 - **资格**:*Active developer* = 2026 年内至少发过 1 次 API 请求(我们符合,6/30 前同步成功) - **发放方式**:仅通过邮件,**后台无兑换入口** - **搜索建议**:邮箱关键词 `Strava API Update`、`3-month`、`developer`;时间约 2026 年 5 月底~6 月初;检查垃圾邮件 / 其他关联邮箱 若仍未收到,可向 Strava 补要: - 社区发帖参考:[3-months free code](https://communityhub.strava.com/developers-api-7/3-months-free-code-13532) - 发帖区:[Strava Developers API](https://communityhub.strava.com/developers-api-7) - 可附 Client ID `212904`、Inactive 错误、最后成功同步时间 --- ## ⚠️ 重要提醒:3 个月免费码到期后必须处理 如果拿到并兑换 **3 个月免费订阅码**: 1. **记录兑换日期**,到期前约 2 周设置提醒 2. 到期前必须二选一(否则应用会再次变为 `Inactive`,定时同步再次失败): - **续费 Strava 订阅**(Standard Tier 无额外 API 费用,订阅即含 API 访问) - **停用 API 自动同步**,改用下方替代方案 3. 兑换后还需: - 重新 OAuth 拿新 `refresh_token`(scope: `read,activity:read_all`) - 更新 GitHub Secrets:`STRAVA_CLIENT_ID`、`STRAVA_CLIENT_SECRET`、`STRAVA_REFRESH_TOKEN` - 手动触发 [Sync Strava Activities](https://github.com/yuler/yuler.dev/actions/workflows/sync-strava.yml) 验证 > 若本身已是 Strava 订阅用户,无需免费码,直接确保订阅活跃 + 更新 token 即可恢复 API。 --- ## 后续可探索方案(按优先级) ### A. 恢复 API 自动同步(推荐,若愿意付费或拿到免费码) 1. 订阅 / 兑换 3 个月免费码 2. 重新 OAuth → 更新 Secrets → 验证 workflow 3. **到期前决定**是否续订 ### B. 向 Strava 补要免费码(零成本,需等待) 见上文社区发帖 / 邮件支持 ### C. 冻结定时任务(零成本,维持现状) - Disable workflow 或改为仅 `workflow_dispatch`,避免每小时失败通知 - 站点继续展示已有 JSON 数据 ### D. Strava Bulk Export 导入(零成本,半自动) - [Exporting your Data and Bulk Export](https://support.strava.com/en-us/articles/15401919-exporting-your-data-and-bulk-export) - Settings → My Account → Request Your Archive(**不是删号**) - ZIP 含 `activities/`(GPX/FIT)+ `activities.csv` - 需编写导入脚本:GPX → 现有 JSON 格式(含 polyline 编码) - 适合「不定期手动同步」,非实时 ### E. 不推荐 - 订阅 1 个月再取消 → 到期后再次 Inactive - 爬取 Strava 网页 → 违反 ToS - 第三方中转平台 → 2026 政策已限制 intermediary - 申请 Extended Access → 个人站场景不现实 --- ## 待办 checklist - [ ] 再搜一遍邮箱(含垃圾邮件)找 3 个月免费码 - [ ] 若无码:Strava 社区 / 支持补要 - [ ] 若拿到码:**记录兑换日 + 设置 3 个月到期提醒** - [ ] 恢复 API 后:OAuth → 更新 Secrets → 手动跑 workflow 验证 - [ ] 到期前决定:续订 vs 改 Bulk Export / 冻结同步 - [ ] (可选)Disable 当前失败的 cron,减少噪音 --- ## 相关链接速查 | 用途 | 链接 | |------|------| | 失败 Actions | https://github.com/yuler/yuler.dev/actions/workflows/sync-strava.yml | | Strava API 设置 | https://www.strava.com/settings/api | | Strava 订阅 | https://www.strava.com/settings/subscription | | 政策更新公告 | https://communityhub.strava.com/insider-journal-9/an-update-to-our-developer-program-13428 | | API FAQ | https://communityhub.strava.com/developers-knowledge-base-14/strava-api-faq-12906 | | 补要免费码参考帖 | https://communityhub.strava.com/developers-api-7/3-months-free-code-13532 | | 数据 Bulk Export | https://support.strava.com/en-us/articles/15401919-exporting-your-data-and-bulk-export | | 本站实现博文 | https://yuler.dev/posts/2026/app-strava/(源码 `src/content/posts/2026/app-strava.mdx`) |
背景
GitHub Actions 工作流 Sync Strava Activities(每小时 :55 cron)自 2026-06-30 22:19 UTC 起持续失败。最后一次成功同步约为 2026-06-30 21:23 UTC。
示例失败 run:actions/runs/28581001311
本地执行
pnpm sync:strava:activities复现相同错误。错误信息
Inactive不是仓库里的配置,而是 Strava API 返回的错误体(errors[].code)src/utils/strava.ts的stravaFetch()中抛出,经scripts/sync-strava-activities.mjs打印/athlete/activities时,说明是 OAuth 应用状态 被 Strava 标记为不可用根因(Strava 政策变更)
Strava Developer Program 更新(2026-06-30 生效):
Inactive,API 返回 403212904,Category Training,1/1 athletes官方参考
当前站点影响
data/strava/activities/*.json,展示不受影响相关实现:
.github/workflows/sync-strava.ymlscripts/sync-strava-activities.mjssrc/utils/strava.tssrc/content/posts/2026/app-strava.mdx已尝试 / 进展
read,activity:read_all)— 授权流程 OK,但应用仍为 Inactive(需先解决订阅)3 个月免费码说明
Strava API Update、3-month、developer;时间约 2026 年 5 月底~6 月初;检查垃圾邮件 / 其他关联邮箱若仍未收到,可向 Strava 补要:
212904、Inactive 错误、最后成功同步时间如果拿到并兑换 3 个月免费订阅码:
Inactive,定时同步再次失败):refresh_token(scope:read,activity:read_all)STRAVA_CLIENT_ID、STRAVA_CLIENT_SECRET、STRAVA_REFRESH_TOKEN后续可探索方案(按优先级)
A. 恢复 API 自动同步(推荐,若愿意付费或拿到免费码)
B. 向 Strava 补要免费码(零成本,需等待)
见上文社区发帖 / 邮件支持
C. 冻结定时任务(零成本,维持现状)
workflow_dispatch,避免每小时失败通知D. Strava Bulk Export 导入(零成本,半自动)
activities/(GPX/FIT)+activities.csvE. 不推荐
待办 checklist
相关链接速查
src/content/posts/2026/app-strava.mdx)