Compare commits

..

2 Commits

Author SHA1 Message Date
Jo Eskil
2ed89fecbc Cleaned project directory and added new development plan for simplified stack 2025-11-13 23:43:42 +01:00
Jo Eskil
384d5364a8 Add new development plan for simplified stack 2025-11-13 23:43:42 +01:00
22 changed files with 32 additions and 576 deletions

1
.gitignore vendored
View File

@@ -1 +0,0 @@
.gemini/

View File

@@ -1,79 +1,48 @@
# Multi-Platform Chat Overlay Development Plan (v3) # Multi-Platform Chat Overlay Development Plan (v4 - Simplified Stack)
This document outlines the development plan for a multi-user, web-based chat overlay service. This document outlines the development plan for a multi-user, web-based chat overlay service using a simplified technology stack.
## 1. Project Overview ## 1. Project Overview
The goal is to create a service where streamers can log in using their platform accounts (Twitch, YouTube), configure a personalized chat overlay, and use it in their streaming software (e.g., OBS). The service will aggregate chat from their connected accounts and provide moderation tools. The goal is to create a service where streamers can log in using their platform accounts (Twitch, YouTube), configure a personalized chat overlay, and use it in their streaming software (e.g., OBS). The service will aggregate chat from their connected accounts and provide moderation tools.
## 2. Architecture ## 2. Technology Stack
The system will be a web application with a Python backend and a web-based frontend. * **Backend (API & Chat Listeners):** Python (for Twitch/YouTube chat listeners), Node.js (for WebSocket server and potentially other APIs), PHP (for user management and web serving).
* **Database:** MySQL
* **Frontend:** HTML, CSS, JavaScript
1. **Python Backend (FastAPI):** ## 3. Implementation Roadmap
* Manages user authentication (OAuth2 for Twitch and YouTube).
* Stores user data, configuration, and encrypted access tokens in a database (SQLite initially).
* Provides a REST API for the frontend to manage user settings.
* Dynamically starts, stops, and manages chat listener processes for active users.
* Runs a WebSocket server to broadcast chat messages to the correct user's overlay.
2. **Frontend (HTML/CSS/JavaScript):** ### Phase 1: Basic Setup & Twitch Chat Listener (Python)
* **Login Page:** Allows users to sign in with their Twitch or YouTube accounts. 1. **Project Structure:** Establish a clear directory structure for PHP, Python, Node.js, and static assets.
* **Dashboard:** A secure area for users to manage their connected accounts, configure their overlay, and get their unique overlay URL. 2. **Python Environment:** Set up a Python virtual environment and install `twitchio`.
* **Web Overlay:** The customizable chat display, loaded as a Browser Source in OBS. 3. **Twitch Chat Listener (Python Script):** Create a standalone Python script that connects to Twitch chat, listens for messages, and prints them to standard output. This script will be run as a background process.
4. **Twitch OAuth2 (Python):** Implement a simple Python script or a PHP endpoint to handle Twitch OAuth2 to obtain user access tokens. Store these securely in MySQL.
## 3. Technology Stack ### Phase 2: MySQL Database & User Management (PHP)
1. **MySQL Setup:** Set up a MySQL database and create a `users` table to store user information (Twitch ID, username, access token, refresh token).
2. **PHP Web Server:** Configure a basic PHP web server.
3. **User Registration/Login (PHP):** Implement PHP scripts for user registration and login, integrating with the MySQL database.
4. **Dashboard (PHP/HTML):** Create a basic dashboard where logged-in users can see their Twitch connection status and their unique overlay URL.
* **Backend:** ### Phase 3: WebSocket Server (Node.js) & Overlay (HTML/CSS/JS)
* **Language:** Python 3.9+ 1. **Node.js Environment:** Set up a Node.js environment and install `ws` (WebSocket library).
* **Web Framework:** FastAPI 2. **WebSocket Server (Node.js):** Create a Node.js WebSocket server that:
* **Database:** SQLite with SQLAlchemy * Accepts connections from overlay clients.
* **Authentication:** OAuth2 (via `httpx` or a similar library) * Receives chat messages from the Python Twitch listener (via a simple inter-process communication mechanism, e.g., writing to a file or a local socket).
* **Chat Listeners:** `pytchat` (YouTube), `TwitchIO` (Twitch) * Broadcasts messages to connected overlay clients.
3. **Overlay Frontend (HTML/CSS/JS):** Create a basic `overlay.html` that:
* Connects to the Node.js WebSocket server.
* Displays incoming chat messages.
4. **Inter-process Communication:** Implement a mechanism for the Python Twitch listener to send messages to the Node.js WebSocket server.
* **Frontend:** ### Phase 4: Integration & Refinement
* **Markup/Styling:** HTML5, CSS3 1. **Dynamic Listener Management:** Develop a system (e.g., a PHP script or a Node.js API) to start and stop Python Twitch listener processes based on user activity.
* **JavaScript:** Vanilla JavaScript 2. **YouTube Integration:** Add YouTube chat listening capabilities (Python `pytchat`) and integrate with the existing system.
* **Communication:** Fetch API, WebSockets 3. **Advanced Overlay Customization:** Implement options for users to customize their overlay.
## 4. Implementation Roadmap ## 4. Requirements for Completion (Initial Version)
### Phase 1: User Authentication & Database
1. **Database Setup:**
* Initialize a SQLite database.
* Define the database schema using SQLAlchemy for a `users` table (storing profile info, channel IDs, and encrypted OAuth tokens).
2. **Install Dependencies:** Add `SQLAlchemy` and an OAuth library to the project.
3. **OAuth2 for Twitch:**
* Implement the FastAPI backend routes for Twitch login (`/login/twitch`) and the callback (`/auth/twitch/callback`).
* Securely store user profile information and tokens in the database.
4. **Login Frontend:** Create a `login.html` page with a "Login with Twitch" button.
5. **Session Management:** Implement basic session management to keep users logged in.
### Phase 2: User Dashboard & Configuration
1. **Dashboard UI:** Create a `dashboard.html` page that is only accessible to logged-in users.
2. **Display User Data:** Show the user's connected Twitch account information.
3. **Configuration API:** Create backend API endpoints for users to submit and update their settings (e.g., which chat platforms to connect, overlay appearance settings).
4. **Configuration Form:** Add a form to the dashboard for users to manage these settings.
5. **Overlay URL:** Generate and display a unique, persistent overlay URL for the user (e.g., `/overlay/{user_id}`).
### Phase 3: Dynamic Chat Listeners & Basic Overlay
1. **Listener Management:**
* Design a system to start and stop chat listener processes based on user activity (e.g., when a user is "live" or has the dashboard open). This may involve a background task manager.
* Refactor the existing `chat_listeners.py` to be controlled by this manager.
2. **User-Specific Broadcasting:**
* Update the WebSocket system to route messages from a specific listener to that user's overlay instance.
3. **Basic User Overlay:**
* When a user accesses their unique overlay URL, the backend serves the `index.html` overlay.
* The overlay connects to the WebSocket and receives only that user's chat messages.
### Phase 4: YouTube Integration & Advanced Features
1. **OAuth2 for YouTube:**
* Implement the backend routes for YouTube login and callback.
* Update the database and dashboard to handle a second connected account.
2. **Moderator & Host Panels:** Re-introduce the concepts of the Host and Moderator panels from v2, but adapted for the multi-user model. This will involve secure access and user-specific controls.
3. **Advanced Overlay Customization:** Add more options for users to customize the look and feel of their overlay via the dashboard.
## 5. Requirements for Completion (Initial Version)
The project will be considered complete for its initial version when Phases 1, 2, and 3 are functional: The project will be considered complete for its initial version when Phases 1, 2, and 3 are functional:
1. Users can log in with their Twitch account. 1. Users can log in with their Twitch account.

View File

@@ -1,17 +0,0 @@
# Use an official Python runtime as a parent image
FROM python:3.9-slim
# Set the working directory in the container
WORKDIR /app
# Copy the requirements file into the container
COPY requirements.txt .
# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code into the container
COPY . .
# Command to run the application
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-w", "4", "-b", "0.0.0.0:8000", "main:app"]

View File

@@ -1,38 +0,0 @@
# Project Progress Report
This document summarizes the key steps and decisions made during the initial setup and planning of the MultiChat Overlay project.
## 1. Initial Setup & Environment Assessment
- **Environment Assessed:** The initial container environment was assessed, and `python3` and `git` were confirmed to be installed.
- **Project Directory:** The project directory was created at `/home/joe/MultiChatOverlay`.
- **Collaboration:** The directory permissions were configured to allow for collaboration by setting the group to `collaborators` and permissions to `775`.
- **Git Repository:** The project was cloned from the Gitea repository at `https://gitea.ramforth.net/ramforth/MultiChatOverlay`.
## 2. Initial Development (Single-User Model)
- **Virtual Environment:** A Python virtual environment was created at `/home/joe/MultiChatOverlay/venv`.
- **Dependencies:** Initial Python dependencies (`fastapi`, `uvicorn`, `websockets`, `pytchat`, `twitchio`) were installed.
- **Basic Framework:** A basic FastAPI application was created with a WebSocket endpoint and a simple HTML overlay.
- **Chat Listeners:** Placeholder chat listener modules were created for YouTube and Twitch.
## 3. Pivot to a Multi-User Service
- **New Requirement:** The project direction was updated to create a multi-user, web-based service where users can log in with their streaming accounts.
- **Revised Development Plan:** A new development plan (`DEVELOPMENT_PLAN.md` v3) was created to reflect this change. The new plan focuses on user authentication, a database, and dynamic management of chat listeners.
- **Plan Synced:** The revised development plan was pushed to the Gitea repository.
## 4. Implementation of the Multi-User Framework
- **Database:** A SQLite database was initialized, and a `users` table schema was defined using SQLAlchemy.
- **Authentication:** A placeholder Twitch OAuth2 implementation was created in `auth.py`.
- **Login Frontend:** A `login.html` page and a corresponding FastAPI endpoint were created.
- **Session Management:** Basic session management using signed cookies was implemented to keep users logged in.
- **Dashboard:** A protected `/dashboard` endpoint and a simple `dashboard.html` page were created.
- **Usage Guide:** A `USAGE.md` file was created to document the login process for end-users.
- **Code Synced:** All changes for the initial multi-user framework were pushed to the Gitea repository.
## 5. Pivot to a Production-Ready Docker-Based Framework
- **New Requirement:** The need for a more robust, scalable, and easily accessible framework was identified.
- **Revised Plan:** A new plan was created to use Docker Compose to manage the application services.
- **Docker Compose Plan:**
- A `web` service for the FastAPI application.
- A `db` service using PostgreSQL.
- The use of `gunicorn` with `uvicorn` workers for the production server.
- The use of Docker volumes to allow for easy collaboration on frontend files.

View File

@@ -1,8 +0,0 @@
There is a need for a chat overlay in live streaming circles that allows streamers to read chat from several of the primary platforms. Twitch and Youtube at the very least.
The idea:
Use self hosted web server to present the user integration with account linking and setup instructions. Let the end user log in with Youtube and Twitch. Have preset templates for html overlay for OBS use.
Must have functions to highlight single messages, preferably from a dockable html browser dock in OBS studio.
This is a specific extension of project: /home/joe/Cloud9/Documents/Obisdian/projects/youtube-chat-webhook-v2

View File

@@ -1,30 +0,0 @@
# Multi-Platform Chat Overlay
A self-hosted tool to aggregate chat from multiple streaming platforms (YouTube, Twitch) and display it in a customizable OBS overlay. This project also provides a suite of tools for both the streamer (host) and their moderators to manage the chat.
## Core Features
* **Combined Chat:** Aggregates chat from YouTube and Twitch into a single feed.
* **OBS Overlay:** A customizable web-based overlay to display the chat in your stream.
* **Host Control Panel:** A dockable OBS panel for the streamer to:
* Highlight important messages to feature them on the overlay.
* View a queue of messages tagged by moderators.
* Dismiss queued messages after they have been addressed.
* **Moderator Panel:** A separate, secure web page for moderators to:
* View the combined chat feed.
* "Tag" or "Queue" important messages for the host's attention.
## Technology Stack
* **Backend:** Python 3.9+ with FastAPI and WebSockets.
* **Frontend:** HTML5, CSS3, and vanilla JavaScript.
* **Chat Libraries:** `pytchat` for YouTube and `TwitchIO` for Twitch.
## Getting Started
_(Instructions will be added here once the initial version is complete)_
1. Clone the repository.
2. Install Python dependencies.
3. Run the backend server.
4. Add the frontend components to OBS as Browser Sources/Docks.

View File

@@ -1,41 +0,0 @@
# MultiChat Overlay Usage Guide
This guide explains how to log in to the MultiChat Overlay service and connect your streaming accounts to generate a personalized chat overlay.
## 1. Logging In
To use the MultiChat Overlay, you first need to log in with your streaming platform account.
1. **Access the Login Page:** Open your web browser and navigate to the service's login page (e.g., `http://localhost:8000/login`).
2. **Choose Your Platform:** On the login page, you will see options to log in with different streaming platforms.
3. **Authorize MultiChat Overlay:**
* Click on the "Login with Twitch" button.
* You will be redirected to Twitch's authorization page. Review the permissions requested by MultiChat Overlay and click "Authorize" to grant access.
* After successful authorization, you will be redirected back to the MultiChat Overlay dashboard.
## 2. Connecting Services
Currently, only Twitch is supported for connection. YouTube integration will be added in a future update.
### Connecting Twitch
Once you have logged in with your Twitch account, your Twitch channel will automatically be connected. You can verify this on your dashboard.
## 3. Your Personalized Overlay
After logging in and connecting your services, you will find your unique overlay URL on the dashboard.
1. **Copy Overlay URL:** On the dashboard, locate and copy the provided "Overlay URL". This URL is unique to your account.
2. **Add to OBS (or other streaming software):**
* In OBS Studio, add a new "Browser Source".
* Paste your copied Overlay URL into the "URL" field of the Browser Source properties.
* Adjust the width and height of the browser source to match your desired overlay size.
* Click "OK".
Your chat overlay should now appear in your streaming software, displaying messages from your connected Twitch channel.
## 4. Future Integrations (Coming Soon)
* **YouTube Integration:** Connect your YouTube channel to aggregate chat from both platforms.
* **Customization Options:** Personalize the look and feel of your chat overlay directly from the dashboard.
* **Moderator & Host Panels:** Access dedicated panels for advanced moderation and stream management.

Binary file not shown.

Binary file not shown.

Binary file not shown.

87
auth.py
View File

@@ -1,87 +0,0 @@
import os
from fastapi import APIRouter, Depends
from fastapi.responses import RedirectResponse
from sqlalchemy.orm import Session
import httpx
from database import get_db, User
from itsdangerous import URLSafeTimedSerializer
# Get configuration from environment variables
TWITCH_CLIENT_ID = os.environ.get("TWITCH_CLIENT_ID")
TWITCH_CLIENT_SECRET = os.environ.get("TWITCH_CLIENT_SECRET")
SECRET_KEY = os.environ.get("SECRET_KEY")
REDIRECT_URI = "http://localhost:8000/auth/twitch/callback" # This will need to be updated for production
serializer = URLSafeTimedSerializer(SECRET_KEY)
router = APIRouter()
@router.get("/login/twitch")
async def login_with_twitch():
# Scopes required to get user's email and channel info
scopes = "user:read:email"
auth_url = (
f"https://id.twitch.tv/oauth2/authorize"
f"?client_id={TWITCH_CLIENT_ID}"
f"&redirect_uri={REDIRECT_URI}"
f"&response_type=code"
f"&scope={scopes}"
)
return RedirectResponse(url=auth_url)
@router.get("/auth/twitch/callback")
async def auth_twitch_callback(code: str, db: Session = Depends(get_db)):
# Exchange the authorization code for an access token
token_url = "https://id.twitch.tv/oauth2/token"
token_data = {
"client_id": TWITCH_CLIENT_ID,
"client_secret": TWITCH_CLIENT_SECRET,
"code": code,
"grant_type": "authorization_code",
"redirect_uri": REDIRECT_URI,
}
async with httpx.AsyncClient() as client:
token_response = await client.post(token_url, data=token_data)
token_json = token_response.json()
access_token = token_json.get("access_token")
refresh_token = token_json.get("refresh_token")
if not access_token:
return {"error": "Could not fetch access token"}
# Get user info from Twitch API
user_info_url = "https://api.twitch.tv/helix/users"
headers = {
"Authorization": f"Bearer {access_token}",
"Client-Id": TWITCH_CLIENT_ID,
}
user_response = await client.get(user_info_url, headers=headers)
user_data = user_response.json()["data"][0]
twitch_id = user_data["id"]
twitch_username = user_data["login"]
# Check if user exists in the database, otherwise create them
user = db.query(User).filter(User.twitch_id == twitch_id).first()
if not user:
user = User(
twitch_id=twitch_id,
twitch_username=twitch_username,
twitch_access_token=access_token, # TODO: Encrypt this
twitch_refresh_token=refresh_token, # TODO: Encrypt this
)
db.add(user)
db.commit()
db.refresh(user)
else:
# Update tokens for existing user
user.twitch_access_token = access_token # TODO: Encrypt this
user.twitch_refresh_token = refresh_token # TODO: Encrypt this
db.commit()
# Create a session cookie
response = RedirectResponse(url="/dashboard")
session_data = {"user_id": user.id}
session_cookie = serializer.dumps(session_data)
response.set_cookie(key="session", value=session_cookie)
return response

View File

@@ -1,65 +0,0 @@
# chat_listeners.py
import asyncio
from pytchat import LiveChat
from twitchio.ext import commands
# YouTube Chat Listener (Placeholder)
async def listen_youtube_chat(video_id: str, callback):
livechat = LiveChat(video_id=video_id)
while True:
try:
chatdata = await livechat.get().as_dict()
for c in chatdata['items']:
message = {
"platform": "youtube",
"author": c['author']['name'],
"message": c['message'],
"is_moderator": False # Placeholder
}
await callback(message)
except Exception as e:
print(f"YouTube chat error: {e}")
await asyncio.sleep(1) # Don't hammer the API
# Twitch Chat Listener (Placeholder)
class TwitchBot(commands.Bot):
def __init__(self, token: str, channel: str, callback):
super().__init__(token=token, prefix='!', initial_channels=[channel])
self.callback = callback
async def event_ready(self):
print(f'Logged in as | {self.nick}')
print(f'User ID is | {self.user_id}')
async def event_message(self, message):
if message.echo:
return
is_moderator = 'moderator' in message.tags and message.tags['moderator'] == '1'
chat_message = {
"platform": "twitch",
"author": message.author.name,
"message": message.content,
"is_moderator": is_moderator
}
await self.callback(chat_message)
async def listen_twitch_chat(token: str, channel: str, callback):
bot = TwitchBot(token, channel, callback)
await bot.start()
# Example usage (for testing purposes, not part of the main application flow)
async def main():
async def print_message(message):
print(f"[{message['platform']}] {message['author']}: {message['message']} (Mod: {message['is_moderator']})")
# Replace with actual YouTube video ID and Twitch token/channel
# asyncio.create_task(listen_youtube_chat("YOUR_YOUTUBE_VIDEO_ID", print_message))
# asyncio.create_task(listen_twitch_chat("YOUR_TWITCH_OAUTH_TOKEN", "YOUR_TWITCH_CHANNEL", print_message))
while True:
await asyncio.sleep(3600) # Keep main running
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -1,22 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>MultiChat Overlay Dashboard</title>
</head>
<body>
<h1>Welcome to your Dashboard</h1>
<p>This is your personalized dashboard. You can manage your connected accounts and configure your overlay here.</p>
<h2>Your Overlay URL</h2>
<p>Use this URL as a browser source in your streaming software:</p>
<pre id="overlay-url"></pre>
<script>
// In a real application, we would fetch the user's unique overlay URL
// from an API and display it here. For now, we'll just show a placeholder.
const overlayUrlElement = document.getElementById('overlay-url');
// This would be something like `http://localhost:8000/overlay/USER_ID`
overlayUrlElement.textContent = `http://localhost:8000/overlay/YOUR_USER_ID`;
</script>
</body>
</html>

View File

@@ -1,35 +0,0 @@
import os
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
DATABASE_URL = os.environ.get("DATABASE_URL")
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
twitch_id = Column(String, unique=True, index=True)
twitch_username = Column(String)
# We will store encrypted tokens
twitch_access_token = Column(String)
twitch_refresh_token = Column(String)
youtube_id = Column(String, unique=True, index=True, nullable=True)
youtube_username = Column(String, nullable=True)
youtube_access_token = Column(String, nullable=True)
youtube_refresh_token = Column(String, nullable=True)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def create_tables():
Base.metadata.create_all(bind=engine)

View File

@@ -1,30 +0,0 @@
version: '3.8'
services:
web:
build: .
command: gunicorn -k uvicorn.workers.UvicornWorker -w 4 -b 0.0.0.0:8000 main:app
volumes:
- .:/app
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:password@db/mydatabase
- SECRET_KEY=YOUR_SECRET_KEY # This should be a long, random string
- TWITCH_CLIENT_ID=ogxx1fhpxbg8g89rov6oswuxeup2pb
- TWITCH_CLIENT_SECRET=2660uqpk2e1leayhpwcu35a27zidmh
- REDIRECT_URI=https://multichat.ramforth.net/auth/twitch/callback
depends_on:
- db
db:
image: postgres:13
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydatabase
volumes:
postgres_data:

View File

@@ -1,21 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>MultiChat Overlay</title>
</head>
<body>
<h1>Chat Messages</h1>
<ul id="messages"></ul>
<script>
const messages = document.getElementById('messages');
const ws = new WebSocket("ws://localhost:8000/ws");
ws.onmessage = function(event) {
const chatMessage = JSON.parse(event.data);
const messageElement = document.createElement('li');
messageElement.textContent = `[${chatMessage.platform}] ${chatMessage.author}: ${chatMessage.message}`;
messages.appendChild(messageElement);
};
</script>
</body>
</html>

View File

@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Login to MultiChat Overlay</title>
</head>
<body>
<h1>Login to MultiChat Overlay</h1>
<p>Connect your streaming accounts to get started.</p>
<a href="/auth/login/twitch">
<button>Login with Twitch</button>
</a>
<!-- YouTube login will be added in a later phase -->
</body>
</html>

67
main.py
View File

@@ -1,67 +0,0 @@
import asyncio
import json
from fastapi import FastAPI, WebSocket, Request, Depends
from fastapi.responses import HTMLResponse, RedirectResponse
from starlette.websockets import WebSocketDisconnect
from starlette.middleware.base import BaseHTTPMiddleware
from sqlalchemy.orm import Session
from chat_listeners import listen_youtube_chat, listen_twitch_chat
from auth import router as auth_router, serializer
from database import get_db, User, create_tables
app = FastAPI()
@app.on_event("startup")
async def startup_event():
create_tables()
# The chat listeners will be started dynamically based on user activity
# and not on application startup.
class SessionMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
response = await call_next(request)
session_cookie = request.cookies.get("session")
if session_cookie:
try:
data = serializer.loads(session_cookie, max_age=3600 * 24 * 7) # 1 week
db = next(get_db())
user = db.query(User).filter(User.id == data["user_id"]).first()
request.state.user = user
except Exception:
request.state.user = None
else:
request.state.user = None
return response
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/login", response_class=HTMLResponse)
async def get_login_page():
with open("login.html", "r") as f:
return f.read()
@app.get("/dashboard", response_class=HTMLResponse)
async def get_dashboard(user: User = Depends(get_current_user)):
if not user:
return RedirectResponse(url="/login")
with open("dashboard.html", "r") as f:
return f.read()
@app.get("/overlay", response_class=HTMLResponse)
async def get_overlay():
with open("index.html", "r") as f:
return f.read()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
connected_clients.append(websocket)
try:
while True:
# Keep the connection alive, or handle incoming messages if needed
await websocket.receive_text()
except WebSocketDisconnect:
connected_clients.remove(websocket)

Binary file not shown.

View File

@@ -1,37 +0,0 @@
aiohappyeyeballs==2.6.1
aiohttp==3.13.2
aiosignal==1.4.0
annotated-doc==0.0.4
annotated-types==0.7.0
anyio==4.11.0
attrs==25.4.0
certifi==2025.11.12
click==8.3.0
fastapi==0.121.1
frozenlist==1.8.0
greenlet==3.2.4
gunicorn==23.0.0
h11==0.16.0
h2==4.3.0
hpack==4.1.0
httpcore==1.0.9
httpx==0.28.1
hyperframe==6.1.0
idna==3.11
itsdangerous==2.2.0
multidict==6.7.0
packaging==25.0
propcache==0.4.1
psycopg2-binary==2.9.11
pydantic==2.12.4
pydantic_core==2.41.5
pytchat==0.5.5
sniffio==1.3.1
SQLAlchemy==2.0.44
starlette==0.49.3
twitchio==3.1.0
typing-inspection==0.4.2
typing_extensions==4.15.0
uvicorn==0.38.0
websockets==15.0.1
yarl==1.22.0

View File