Sign inSign up

zekihan/youaud

By zekihan

•Updated about 3 hours ago

YouAud

Image
0

50K+

zekihan/youaud repository overview

⁠YouAud

YouAud is a small Go-based HTTP service that exposes RSS-style feeds and helpers for several content platforms (YouTube, Reddit, TikTok, Twitter, Instagram) and integrates with Miniflux and notification backends. It provides an API surface for generating feeds, handling YouTube auth, and administrative triggers for reconciliation tasks.

Key features

  • Exposes RSS endpoints for YouTube channels and other platforms.
  • Integrates with Miniflux (reconciliation and import helpers).
  • Supports scheduled reconciliation loops for YouTube and Miniflux.
  • Optional Flaresolverr provider transport for sites that require JavaScript solving.
  • Notification support (Telegram) and pluggable notifier initialization.
  • Persistent storage using GORM with support for SQLite, Postgres (and libSQL).
  • Configuration driven by configs/config.yaml (sample provided) and environment variables.
  • Optional Authentik OIDC dashboard with HTMX feed refresh and per-user Miniflux reconciliation.
  • Graceful shutdown, health/ping/readiness endpoints, and API key-based admin protection.

Quick links

  • Code: module github.com/zekihan/youaud (see go.mod)
  • Entrypoint: main.go
  • Configuration sample: configs/config.sample.yaml (copy to configs/config.yaml and edit)
  • Docker: Dockerfile and docker-compose.yaml
  • Migrations: internal/platform/database/migrations/

Requirements

  • Go, using the version declared in go.mod
  • Optional: Docker & docker-compose for containerized runs

Configuration

  1. Copy the sample config and edit as needed:
cp configs/config.sample.yaml configs/config.yaml
# edit configs/config.yaml
  1. Environment variables: the service will also load an environment file (see project root). You can set values in your shell or use a .env file and the included environment loader.

Web UI and shared Miniflux SSO

The root page (/) is a small authenticated dashboard. It lists the current user's configured feed inventory, refreshes it with HTMX, starts only that user's Miniflux reconciliation, and links to the user's configured Miniflux instance. It never sends YouAud or Miniflux API keys to the browser.

Enable web.sso using the dedicated youaud Authentik OAuth2 client created by the Terraform configuration. Its callback is:

https://youaud.<domain>/auth/callback

For local development, http://localhost:42312/auth/callback is also registered. Set YOUAUD__WEB_SSO_REDIRECT_URL=http://localhost:42312 for a local process while retaining the public web.callbackUrl for feed URLs. Use the provider's per-provider issuer URL and keep sub_mode = "user_username", matching the Miniflux client. Set each allowed user's sso.subject to that Authentik username. Because Authentik already has the Miniflux session, opening either application is a single-login experience.

The Terraform client credentials belong in the existing Doppler-backed authentik_oauth2_client_secrets.youaud input; do not commit them. Generate separate long random cookie keys for web.sso.cookieHashKey and web.sso.cookieBlockKey. The sample config shows all required fields. SSO enablement, issuer/client changes, and cookie-key rotation require a process restart. A rejected reload leaves the active authentication configuration intact.

Running locally (Go)

Build and run the binary with the standard Go tooling:

# build
go build -o youaud ./

# run (reads config.yaml from the configs/ directory)
CONFIG_DIR=./configs ./youaud

Or run without building:

CONFIG_DIR=./configs go run ./

Running with Docker

The Dockerfile packages binaries that have already been built into dist/; it does not compile the application inside the image. Build the Linux binaries before building the image:

make build/docker
docker build -t youaud:local .

# Or build and start the Compose stack
make build/docker
docker compose up --build

API surface

The server exposes several routes. Important ones include:

  • /api/ping — basic ping
  • /api/health — health check
  • /api/ready — readiness probe

Admin (API key protected):

  • /api/admin/trigger/youtube_reconcile — trigger YouTube reconcile
  • /api/admin/trigger/miniflux_reconcile — trigger Miniflux reconcile

YouTube and feed endpoints:

  • /youtube/auth — YouTube OAuth entrypoint
  • /api/youtube/subscriptions — authenticated, cached YouTube subscription metadata
  • /feeds/youtube/channel/{channelID} — feed for a channel (API key protected)

Reddit:

  • /feeds/reddit/subreddit/{subreddit}
  • /feeds/reddit/user/{user}

TikTok:

  • /feeds/tiktok/profile/{handle}?variant=tikvib

Twitter:

  • /feeds/twitter/profile/{handle}?variant=twitter-viewer

Instagram:

  • /feeds/instagram/profile/{handle}?variant=web-api

Notes

  • Admin endpoints require an API key defined in the configuration (WebConfig.APIKey).
  • The server redirects unknown paths to /404.
  • Public HTTP feed requests accept only HTTP(S) URLs without embedded credentials. Every request and redirect resolves its destination and rejects private, loopback, link-local, metadata, and other special-use addresses. Connections dial checked numeric addresses to prevent DNS rebinding. Environment forward proxies are disabled for these clients because they bypass local dialing checks. Cross-origin redirects (including scheme or port changes) drop caller headers; credentials remain removed for the rest of that redirect chain. Per-user database header injection is also disabled after any origin change.
  • Explicit source endpoint overrides and the Flaresolverr service URL are trusted operator configuration and may point to self-hosted private services. Their HTTP clients allow only that exact origin, including on redirects. Do not populate these settings from untrusted feed input. Browser and Flaresolverr page navigation occur outside the Go HTTP client's destination policy and need their own network controls. Injected custom HTTP clients/transports must enforce their own dialing policy.
  • Configuration reloads apply API keys, users, notifiers, YouTube OAuth settings, logging, and schedules. Listener, database, Redis, and Flaresolverr endpoint or pool changes, along with OIDC settings, are rejected with a restart-required error so they cannot appear to have taken effect when they have not.

Database & Migrations

The project uses GORM for ORM and includes migration helpers in internal/platform/database/. Migration SQL files are in internal/platform/database/migrations. The project supports SQLite and Postgres (and libSQL) based on configuration.

PostgreSQL connections default to sslmode=require: startup fails if the server refuses TLS. This encrypts traffic but does not authenticate the server certificate or hostname. For authenticated production connections, explicitly use sslmode=verify-full and a trusted CA (sslrootcert in the database URL), with a hostname matching the certificate. Certificate paths and trust configuration must be provisioned by the operator; this default change does not alter them.

database.sslMode (or YOUAUD__DATABASE_SSL_MODE) selects the mode; a nonempty sslmode in database.url takes precedence. Empty modes use require. Existing explicit modes remain supported for compatibility. Only use sslmode=disable for a disposable local development database on loopback, never for remote or production databases. prefer and allow permit plaintext fallback and should not be used in production. Mandatory certificate validation and rejection of explicit insecure modes remain operator policy decisions; they are not enforced by this change. SQLite remains the shipped default.

The service refuses to start when the database schema is newer than the application, preventing an older binary from automatically running destructive down migrations. For an intentional rollback, set YOUAUD__DATABASE_ALLOW_DOWNGRADE=true for that run (or set database.allowDowngrade: true in configuration).

To make local database changes against a production-like snapshot without touching PostgreSQL, run:

./scripts/postgres_to_sqlite.sh
# later refresh the local snapshot explicitly
./scripts/postgres_to_sqlite.sh --replace

The script reads POSTGRES_URL, YOUAUD__DATABASE_URL, or the local .env, and only ever reads from the PostgreSQL source. It builds the destination from this checkout's SQLite migrations, copies matching table data, and validates a temporary SQLite file before replacing tmp/database/postgres-snapshot.sqlite. It then writes a companion .env file containing the SQLite settings to source for a local run. A custom destination may be passed as its final argument.

To copy the live YouAud database into an existing, empty local PostgreSQL database, install the PostgreSQL client tools and run:

createdb youaud_snapshot
LOCAL_POSTGRES_URL=postgresql://localhost:5432/youaud_snapshot make database/cluster-to-postgres

This reads the miniflux-pguser-youaud secret in the miniflux namespace on cluster-1-local, forwards the primary database service temporarily, and restores a consistent pg_dump snapshot into the local database. It refuses a destination with existing tables. Set KUBE_CONTEXT, KUBE_NAMESPACE, SECRET_NAME, PF_SVC, or PF_PORT to override the cluster defaults.

Notifications

Telegram is supported as a notifier — configure chat IDs and enable notifications in configs/config.yaml.

Development & tests

Tests must run through the included script so the configuration loader receives the sample test configuration:

# run all tests
./scripts/go_test.sh -v ./...

# run the race detector too (the same checks run by `make test`)
./scripts/go_test.sh -v -race ./...

Contributing

Contributions are welcome. If you plan to make changes, please:

  1. Open an issue or discussion for larger changes.
  2. Add tests for new functionality.
  3. Keep changes focused and well-documented.

License

This repository includes a LICENSE file — please refer to it for licensing details.

Support / Contact

If you have questions or find issues, please open an issue on the repository.

Publishing and manual recovery: Publishing⁠.

Tag summary

Content type

Image

Digest

sha256:211ef76e1…

Size

15.3 MB

Last updated

2 days ago

docker pull zekihan/youaud