Subscription aggregation service for multi-device use, based on subconverter-rs.
apps/control-plane: Next.js control plane (OpenNext on Cloudflare Workers)workers/converter: Rust converter Worker (stateless, no KV binding)- Dynamic data: Cloudflare KV (
SUB_KV, control-plane only) - Internal call:
control-plane->convertervia Service Binding (CONVERTER_SERVICE)
- Public subscription entry:
GET /{alias} - Admin API:
/api/admin/* - Admin UI:
/admin/*
Workflow file:
.github/workflows/deploy-cloudflare.yml
Deploy behavior:
- Trigger on push to
main(converter/control-plane/core files changed), or manualworkflow_dispatch. - Deploy sequence is fixed:
converter->control-plane. - Before deploying
control-plane, workflow syncs runtime secrets viawrangler secret put.
Required GitHub Actions Secrets:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_IDSUB_KV_NAMESPACE_IDSUB_KV_PREVIEW_NAMESPACE_IDCONFIG_ASSET_BASE_URLSUBCONVERTER_TIMEOUT_MSPULL_LOG_RETENTION_DAYSCF_ACCESS_TEAM_DOMAINCF_ACCESS_AUDCF_ACCESS_ISSUER(optional)
Notes:
CLOUDFLARE_API_TOKENshould include Worker/KV/R2 edit permissions for this account.SUB_KV_NAMESPACE_ID/SUB_KV_PREVIEW_NAMESPACE_IDare injected intoapps/control-plane/wrangler.jsoncduring CI.services.CONVERTER_SERVICEinwrangler.jsoncshould point tomy-sub-converter.
Converter:
cd workers/converter
npm install
npx wrangler deployControl plane:
cd apps/control-plane
npm install
npm run build:cf
npm run deploy:cfIn apps/control-plane/wrangler.jsonc:
services.CONVERTER_SERVICE->my-sub-converterkv_namespaces.SUB_KV-> your KV namespace IDs
CONFIG_ASSET_BASE_URL=
SUBCONVERTER_TIMEOUT_MS=15000
PULL_LOG_RETENTION_DAYS=30
CF_ACCESS_TEAM_DOMAIN=
CF_ACCESS_AUD=
CF_ACCESS_ISSUER=GPL-3.0+ (same as upstream project license in this repository).