Files
BYW-VoiceHub/.env.example
T
Henry_Du a2ba15c3ca feat(notify): 微信订阅消息推送(驳回通知已对接)
- 新增 server/services/wechatSubscribeService.ts:access_token 缓存 + 模板配置 + 字段裁剪 + subscribe/send
  · 内置默认模板 SONG_REJECTED(模板 ID erAK**…,审核内容=thing6←歌名,驳回原因=thing4←驳回原因)
  · 环境变量 WECHAT_MINI_SUBSCRIBE_TEMPLATES 可按键覆盖默认模板
  · thing 字段按微信限制裁到 20 字(超长截 19 字 + 省略号),避免 47003
  · 发送永不抛异常;43101(用户没授权/没额度)只记 info
- 新增 server/api/user/wechat-subscribe-templates.get.ts:给小程序返回模板 ID(客户端要拿它去申请授权)
- 新增 server/api/admin/wechat/test-subscribe.post.ts:超管自测接口(token/openid/字段/微信原文一次看清)
- notificationService.ts:歌曲被选中/已播放/被驳回/系统通知 四处顺带发微信订阅消息
- .env.example + 部署流水线:WECHAT_MINI_SUBSCRIBE_TEMPLATES 可用仓库 Secret 下发
2026-09-27 13:55:55 +08:00

133 lines
5.9 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据库连接地址(必填)
# 格式:postgresql://用户名:密码@主机:端口/数据库名?sslmode=require
# 示例:postgresql://myuser:mypassword@localhost:5432/voicehub?sslmode=require
DATABASE_URL="postgresql://username:password@host:port/database?sslmode=require"
# JWT 认证密钥(必填)
# 请使用强随机字符串,建议至少 32 位
JWT_SECRET="your-very-secure-jwt-secret-key"
# 受信的 CDN/反向代理真实 IP 头(可选)
# 多个头用逗号分隔;未配置时只使用 TCP 连接地址,避免客户端伪造转发头。
# 示例:EdgeOne 使用 eo-connecting-ip,Cloudflare 使用 cf-connecting-ip
# TRUSTED_CLIENT_IP_HEADERS=eo-connecting-ip
# WebAuthn / Passkey 配置(可选)
# 依赖方 ID (RP ID),必须是你域名的一个有效域名
# 规则:必须是请求域名的精确匹配或父域名
#
# 示例:
# - 请求域名为 voicehub.example.com,RP ID 可设为 voicehub.example.com 或 example.com
# - 不配置时,默认使用当前请求的 hostname(适合开发/预览环境)
# - 生产环境建议配置为你的主域名,如:voicehub.example.com
WEBAUTHN_RP_ID=
# 允许的 Origin 列表(可选)
# WebAuthn 要求精确匹配 Origin,此配置用于支持多域名部署
# 多个域名用逗号分隔,必须包含 https:// 前缀
#
# 示例:
# - 单域名:https://voicehub.example.com
# - 多域名(Vercel 预览 + 生产):https://voicehub.example.com,https://voicehub-xxx.vercel.app
# - 二级域名:https://voicehub.example.com,https://sub.voicehub.example.com
#
# 不配置时:默认信任请求的 Origin(适合开发环境)
# 生产环境:强烈建议配置,以防止恶意站点伪造 Origin 攻击
WEBAUTHN_ORIGIN=
# 应用运行环境(可选)
# development: 开发环境
# production: 生产环境
NODE_ENV=development
# Sentry 配置(可选)
# 错误监控与性能追踪,配置后系统将自动上报运行时异常
#
# SENTRY_DSN 客户端(浏览器)使用的 DSN(公开可暴露)
# 示例:https://publicKey@o0.ingest.sentry.io/0
# SENTRY_DSN=
#
# SENTRY_SERVER_DSN 服务端(Node)使用的 DSN(保密,不应暴露给浏览器)
# 如未单独配置,服务端会自动降级使用 SENTRY_DSN
# SENTRY_SERVER_DSN=
#
# 采样率配置(0~1 的小数,默认 1.0 表示 100%)
# 错误采样率
# SENTRY_ERROR_SAMPLE_RATE=1.0
# 性能追踪(Traces)采样率
# SENTRY_TRACES_SAMPLE_RATE=1.0
# 浏览器会话回放(Replay)采样率,需同时设置下面两项才会生效
# 生产环境建议分别设为 0.1 和 1.0,即 10% 正常用户 + 100% 错误用户进行回放
# SENTRY_REPLAY_SESSION_SAMPLE_RATE=
# SENTRY_REPLAY_ON_ERROR_SAMPLE_RATE=
#
# 项目版本号,用于区分不同版本的错误;未填时自动使用 package.json 的 version
# SENTRY_RELEASE=
#
# 环境标签,默认继承 NODE_ENV
# SENTRY_ENVIRONMENT=
# Redis 缓存服务(可选,暂不推荐)
# 如果设置了 REDIS_URL,系统将自动启用 Redis 缓存功能
# 格式:redis://用户名:密码@主机:端口
# REDIS_URL="redis://default:password@host:port"
# Docker Compose 自带的 Redis 容器(compose 自带 redis 服务,仅在启用自带 redis 时用)
# - 留空(或空字符串):不设置 Redis 密码,内网部署常用(默认)
# - 填写强密码:Redis 会启用 requirepass,连接时 REDIS_URL 里也要带上相同密码
REDIS_PASSWORD=
# Redis 键命名空间,多个 VoiceHub 环境共用 Redis 时应分别设置
# REDIS_KEY_PREFIX="voicehub:v2:"
# OAuth 配置(可选)
# 启用相应的 OAuth 提供商需要填写对应的 Client ID 和 Client Secret
#
# 注意:OAuth 运行时配置已经迁移到管理员后台;以下变量仅用于兼容旧部署和后台一键导入。
# 导入完成后,系统以数据库中保存的配置为准。
# OAuth 回调地址(必填,如果启用 OAuth)
# 注意:[provider] 是占位符,实际使用时需要根据具体情况填写
OAUTH_REDIRECT_URI="http://localhost:3000/api/auth/[provider]/callback"
# 用于加密 OAuth state 的密钥(必填,如果启用 OAuth)
OAUTH_STATE_SECRET=your-secure-random-string-for-oauth-state
# GitHub OAuth
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# Casdoor OAuth
CASDOOR_CLIENT_ID=
CASDOOR_CLIENT_SECRET=
CASDOOR_ENDPOINT=
# Google OAuth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# 聚合登陆 OAuth(如 auxx.cn 等聚合登录服务,支持微信/QQ 等通道
AGGREGATE_OAUTH_APP_ID=
AGGREGATE_OAUTH_APP_KEY=
# 支持单值、逗号分隔或 JSON 数组,例如:qq,wx,sina,baidu
# 可用值:qq,wx,alipay,sina,baidu,douyin,huawei,xiaomi,gitee,gitea,bilibili,kuaishou
AGGREGATE_OAUTH_LOGIN_TYPE=wx
# 聚合登录服务基地址(https,不带 /oauth/... 路径),例如:https://www.auxx.cn
AGGREGATE_OAUTH_ENDPOINT=
# 微信小程序登录(可选)
# 用于小程序端 wx.login() 的 code 换取 openid,对应接口 POST /api/auth/wechat/login
# AppID / AppSecret 在微信公众平台「开发管理 → 开发设置 → 开发者ID」中获取
# 注意:这与上方聚合登录的 wx 通道不是一回事——小程序 openid 按 AppID 维度生成,两者不通用
WECHAT_MINI_APPID=
WECHAT_MINI_SECRET=
# 微信「订阅消息」模板(可选,但**想让通知发到微信里就必须配**)
# 公众平台「功能 → 订阅消息 → 选用模板」拿到模板 ID 后,按下面的 JSON 填:
# {"SONG_PLAYED":{"id":"模板ID","fields":{"thing1":"songTitle","time2":"time","thing3":"message"}}}
# 键是通知类型(SONG_SELECTED / SONG_PLAYED / SONG_REJECTED / SYSTEM_NOTICE),
# fields 的键是模板里的字段名(thing1/time2/... 选用模板时能看到),值是变量名
# (内置变量:songTitle / message / time)。不配就等于关闭微信推送,其它渠道照常。
# ⚠️ 平台限制:一次性订阅=一次授权只能发一条;且只有绑定了微信的账号才有 openid。
WECHAT_MINI_SUBSCRIBE_TEMPLATES=