Update files

This commit is contained in:
glpshchn 2025-12-15 04:16:04 +03:00
parent 453d2bf6d2
commit 0d6d8e0ff7
4 changed files with 25 additions and 21 deletions

View File

@ -24,5 +24,6 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:3001/health')" CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:3001/health')"
# Run application # Run application
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3001"] # Используем wrapped_app для поддержки Socket.IO
CMD ["python", "-m", "uvicorn", "main:wrapped_app", "--host", "0.0.0.0", "--port", "3001"]

View File

@ -79,25 +79,20 @@ async def root():
app.include_router(mod_app_router, prefix="/api/mod-app", tags=["moderation"]) app.include_router(mod_app_router, prefix="/api/mod-app", tags=["moderation"])
app.include_router(moderation_auth_router, prefix="/api/moderation-auth", tags=["auth"]) app.include_router(moderation_auth_router, prefix="/api/moderation-auth", tags=["auth"])
# Mount Socket.IO app for WebSocket # Socket.IO будет обернут в uvicorn.run() для правильной работы
# Socket.IO ASGI app needs to wrap FastAPI app to handle both HTTP and WebSocket # Здесь просто инициализируем для проверки
try: try:
socketio_app = get_socketio_app() socketio_app = get_socketio_app()
# Socket.IO will handle /socket.io and /mod-chat paths print("✅ WebSocket (Socket.IO) инициализирован")
# We need to mount it so it can intercept WebSocket connections
# But FastAPI routes should still work
# The Socket.IO ASGI app will handle its own paths and pass others to FastAPI
app.mount("/socket.io", socketio_app)
app.mount("/mod-chat", socketio_app) # Also mount at /mod-chat for namespace
print("✅ WebSocket (Socket.IO) настроен")
print(" 📡 Namespace /mod-chat доступен для чата модераторов") print(" 📡 Namespace /mod-chat доступен для чата модераторов")
print(" 🔌 WebSocket endpoint: /socket.io")
print(" 💡 Подключение: wss://your-domain/socket.io с namespace='/mod-chat'")
except Exception as e: except Exception as e:
print(f"⚠️ Ошибка настройки WebSocket: {e}") print(f"⚠️ Ошибка инициализации WebSocket: {e}")
import traceback import traceback
traceback.print_exc() traceback.print_exc()
print(" Чат модераторов будет недоступен") print(" Чат модераторов будет недоступен")
if __name__ == "__main__": if __name__ == "__main__":
print("\n" + "=" * 60) print("\n" + "=" * 60)
print("✅ Сервер модерации запущен (Python)") print("✅ Сервер модерации запущен (Python)")
@ -107,7 +102,7 @@ if __name__ == "__main__":
print("=" * 60 + "\n") print("=" * 60 + "\n")
uvicorn.run( uvicorn.run(
"main:app", wrapped_app, # Используем обернутое приложение
host="0.0.0.0", host="0.0.0.0",
port=settings.MODERATION_PORT, port=settings.MODERATION_PORT,
reload=settings.IS_DEVELOPMENT, reload=settings.IS_DEVELOPMENT,

View File

@ -484,9 +484,9 @@ async def get_config():
"""Get configuration for frontend""" """Get configuration for frontend"""
bot_username = settings.MODERATION_BOT_USERNAME bot_username = settings.MODERATION_BOT_USERNAME
# If not set, try to get from Bot API (simplified - can add full implementation) # If not set, use default
if not bot_username: if not bot_username:
bot_username = "moderation_bot" bot_username = "rbachbot" # Default bot username
return {"botUsername": bot_username} return {"botUsername": bot_username}

View File

@ -128,7 +128,7 @@ export default function App() {
const [commentsLoading, setCommentsLoading] = useState(false); const [commentsLoading, setCommentsLoading] = useState(false);
// Конфигурация (bot username) // Конфигурация (bot username)
const [moderationBotUsername, setModerationBotUsername] = useState('moderation_bot'); const [moderationBotUsername, setModerationBotUsername] = useState('rbachbot');
// Форма авторизации // Форма авторизации
const [authForm, setAuthForm] = useState({ const [authForm, setAuthForm] = useState({
@ -316,9 +316,12 @@ export default function App() {
script.setAttribute('data-onauth', 'onTelegramAuth'); script.setAttribute('data-onauth', 'onTelegramAuth');
script.setAttribute('data-radius', '10'); script.setAttribute('data-radius', '10');
// Добавить auth-url для валидации домена // Добавить auth-url для валидации домена
const API_URL = getApiUrl(); // Telegram требует, чтобы auth-url был на том же домене, где размещен виджет
const fullApiUrl = API_URL.startsWith('http') ? API_URL : `${window.location.origin}${API_URL}`; const authUrl = `${window.location.origin}/api/moderation-auth/telegram-widget`;
script.setAttribute('data-auth-url', `${fullApiUrl}/moderation-auth/telegram-widget`); script.setAttribute('data-auth-url', authUrl);
console.log('[Telegram Widget] Bot username:', moderationBotUsername);
console.log('[Telegram Widget] Auth URL:', authUrl);
console.log('[Telegram Widget] Current origin:', window.location.origin);
script.onload = () => { script.onload = () => {
console.log('[Telegram Widget] Скрипт загружен'); console.log('[Telegram Widget] Скрипт загружен');
@ -515,9 +518,14 @@ export default function App() {
hasUsername: !!user.username, hasUsername: !!user.username,
hasTelegramId: !!user.telegramId hasTelegramId: !!user.telegramId
}); });
console.log('[Chat] Подключение к:', `${socketBase}/mod-chat`); // Socket.IO подключается к /socket.io, но использует namespace /mod-chat
// В production Socket.IO слушает на /socket.io, namespace указывается отдельно
const socketUrl = socketBase.endsWith('/socket.io') ? socketBase : `${socketBase}/socket.io`;
console.log('[Chat] Подключение к Socket.IO:', socketUrl);
console.log('[Chat] Использование namespace: /mod-chat');
const socket = io(`${socketBase}/mod-chat`, { const socket = io(socketUrl, {
namespace: '/mod-chat',
transports: ['websocket', 'polling'], transports: ['websocket', 'polling'],
reconnection: true, reconnection: true,
reconnectionDelay: 1000, reconnectionDelay: 1000,