feat: connect Twungeon to live Twitch
This commit is contained in:
+40
-9
@@ -10,7 +10,8 @@ provide the variables through your process manager.
|
||||
- A Twitch developer application and a development channel.
|
||||
- A Twitch Extension with identity sharing enabled. Twungeon requires the
|
||||
numeric `user_id`; anonymous or opaque-only viewers fail closed.
|
||||
- A broadcaster user access token that can read chat and check followers.
|
||||
- A confidential Twitch developer application whose OAuth callback is the
|
||||
public Twungeon `/oauth/callback` URL.
|
||||
- The Extension shared secret, copied exactly as the base64 value supplied by
|
||||
the Extension Manager.
|
||||
|
||||
@@ -20,16 +21,19 @@ rotating tokens or upgrading packages.
|
||||
|
||||
## Required environment
|
||||
|
||||
Set `TWITCH_ENABLED=true`, then provide:
|
||||
Provide the following values first. Keep `TWITCH_ENABLED=false` until OAuth,
|
||||
Extension, and Channel Points setup are complete; then switch it to `true` for
|
||||
live operation.
|
||||
|
||||
| Variable | Purpose |
|
||||
| --- | --- |
|
||||
| `TWITCH_CLIENT_ID` | Developer application/Extension client ID |
|
||||
| `TWITCH_CLIENT_ID` | Confidential OAuth application client ID |
|
||||
| `TWITCH_CLIENT_SECRET` | Server-only application secret |
|
||||
| `TWITCH_BROADCASTER_ID` | Numeric channel owner ID |
|
||||
| `TWITCH_CHANNEL_LOGIN` | Channel login joined by Twurple chat |
|
||||
| `TWITCH_BOT_ACCESS_TOKEN` | Broadcaster user access token |
|
||||
| `TWITCH_EXTENSION_SECRET` | Base64 Extension shared secret |
|
||||
| `TWITCH_OAUTH_REDIRECT_URI` | Exact HTTPS OAuth callback registered with Twitch |
|
||||
| `TWITCH_TOKEN_FILE` | Restricted file used for access and refresh tokens |
|
||||
| `CHANNEL_POINTS_RESURRECTION_REWARD_ID` | Stable ID of the resurrection custom reward |
|
||||
| `PUBLIC_BASE_URL` | Public HTTPS backend origin |
|
||||
|
||||
@@ -40,13 +44,40 @@ Twungeon subscribes only to the configured custom reward and uses Twitch's
|
||||
stable redemption ID as the deduplication key. The broadcaster owns the reward
|
||||
cost in Twitch; the backend does not duplicate it.
|
||||
|
||||
## Broadcaster OAuth authorization
|
||||
|
||||
1. Register a **Confidential** Twitch application with an exact HTTPS redirect
|
||||
such as `https://twungeon.example/oauth/callback`.
|
||||
2. Configure `TWITCH_CLIENT_ID`, `TWITCH_CLIENT_SECRET`,
|
||||
`TWITCH_CHANNEL_LOGIN`, `TWITCH_OAUTH_REDIRECT_URI`, and
|
||||
`TWITCH_TOKEN_FILE` while leaving `TWITCH_ENABLED=false`.
|
||||
3. Restart Twungeon and confirm `/oauth/status` reports `configured: true` and
|
||||
`authorized: false`.
|
||||
4. Open `/oauth/login` in a browser and authorize using the configured
|
||||
broadcaster account. Twungeon requests only `chat:read`,
|
||||
`moderator:read:followers`, and `channel:read:redemptions`.
|
||||
5. Confirm the callback reports success and `/oauth/status` reports
|
||||
`authorized: true`. The callback validates the client ID, broadcaster login,
|
||||
and required scopes before storing the token.
|
||||
6. Record the numeric broadcaster ID shown by the callback as
|
||||
`TWITCH_BROADCASTER_ID`.
|
||||
|
||||
The access and refresh tokens are stored atomically at `TWITCH_TOKEN_FILE` with
|
||||
owner-only permissions. Twurple refreshes the access token when necessary and
|
||||
Twungeon replaces the stored token without printing either token. The token
|
||||
directory must be writable only by the Twungeon service account. Never place the
|
||||
token file inside the repository or a web-served directory.
|
||||
|
||||
## Extension configuration
|
||||
|
||||
1. Host the built static files and backend at an HTTPS origin allowed by the
|
||||
Extension configuration. Twitch embeds the UI in an iframe and supplies the
|
||||
Extension Helper JWT through `onAuthorized`.
|
||||
2. Point the viewer/mobile video component to the application root.
|
||||
3. Enable identity sharing. A JWT without `user_id`, with the wrong
|
||||
1. Create a Twitch Extension separately from the confidential OAuth
|
||||
application. In the Extension Manager, use a testing base URI ending in
|
||||
`/`, select a video component, and set its viewer path to `extension`.
|
||||
2. Enable **Request Identity Link**. The viewer must click **Share Twitch
|
||||
identity** in the component; the Extension Helper then invokes
|
||||
`requestIdShare()` from that user gesture and supplies a new JWT through
|
||||
`onAuthorized`.
|
||||
3. A JWT without `user_id`, with the wrong
|
||||
`channel_id`, an expired signature, or an `external` role is rejected.
|
||||
4. Keep the Extension secret only in the backend environment. It must never be
|
||||
included in the UI bundle or URL.
|
||||
|
||||
Reference in New Issue
Block a user