64 lines
1.7 KiB
Python
64 lines
1.7 KiB
Python
"""
|
|
WebSocket events via Flask-SocketIO: real-time message delivery.
|
|
"""
|
|
from flask_socketio import emit, join_room, leave_room
|
|
from flask import request
|
|
from app import socketio
|
|
from app.services.chat_engine import ChatEngineService
|
|
from app.models.chat import Message
|
|
import jwt
|
|
from app.config import config_by_name
|
|
import os
|
|
|
|
|
|
def get_user_id_from_token():
|
|
token = request.args.get("token") or request.headers.get("Authorization")
|
|
if token and token.startswith("Bearer "):
|
|
token = token[7:]
|
|
if not token:
|
|
return None
|
|
try:
|
|
cfg = config_by_name.get(os.getenv("FLASK_ENV", "development"))
|
|
payload = jwt.decode(token, cfg.SECRET_KEY, algorithms=["HS256"])
|
|
return payload.get("sub")
|
|
except Exception:
|
|
return None
|
|
|
|
|
|
@socketio.on("connect")
|
|
def on_connect():
|
|
user_id = get_user_id_from_token()
|
|
if user_id:
|
|
join_room("user:{}".format(user_id))
|
|
emit("connected", {"user_id": user_id})
|
|
else:
|
|
emit("error", {"message": "Authentication required"}, room=request.sid)
|
|
|
|
|
|
@socketio.on("disconnect")
|
|
def on_disconnect():
|
|
pass
|
|
|
|
|
|
@socketio.on("join_conversation")
|
|
def on_join_conversation(data):
|
|
cid = (data or {}).get("conversation_id")
|
|
user_id = get_user_id_from_token()
|
|
if not user_id or not cid:
|
|
return
|
|
join_room("conv:{}".format(cid))
|
|
|
|
|
|
@socketio.on("leave_conversation")
|
|
def on_leave_conversation(data):
|
|
cid = (data or {}).get("conversation_id")
|
|
if cid:
|
|
leave_room("conv:{}".format(cid))
|
|
|
|
|
|
def broadcast_new_message(msg):
|
|
if not isinstance(msg, Message):
|
|
return
|
|
room = "conv:{}".format(msg.conversation_id)
|
|
socketio.emit("new_message", msg.to_dict(), room=room)
|