chore: auto-commit from dashboard

This commit is contained in:
2026-05-27 05:40:22 +00:00
parent 2a05f7cf49
commit 3dd2ddbd6a
11 changed files with 430 additions and 19 deletions

View File

@@ -3,6 +3,8 @@
import asyncio
import json
import logging
import os
import subprocess
from pathlib import Path
from telegram import (
@@ -10,6 +12,7 @@ from telegram import (
ForceReply,
InlineKeyboardButton,
InlineKeyboardMarkup,
ReactionTypeEmoji,
Update,
)
from telegram.constants import ChatAction, ChatType
@@ -742,6 +745,40 @@ async def callback_ralph(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
return
# --- Audio helpers ---
_AUDIO_PREFIX = "__AUDIO__:"
async def _send_voice_telegram(update: Update, wav_path: str) -> None:
"""Convertește WAV→OGG (ffmpeg) și trimite ca voice note Telegram."""
ogg_path = wav_path.replace(".wav", ".ogg")
try:
ffmpeg = "/home/moltbot/bin/ffmpeg"
subprocess.run(
[
ffmpeg, "-i", wav_path,
"-c:a", "libopus", "-b:a", "64k",
ogg_path, "-y",
],
check=True, capture_output=True, timeout=30,
)
with open(ogg_path, "rb") as f:
await update.message.reply_voice(voice=f)
except subprocess.CalledProcessError as e:
err = e.stderr.decode(errors="replace")[:200]
await update.message.reply_text(f"Conversie audio eșuată: {err}")
except Exception as e:
await update.message.reply_text(f"Eroare trimitere audio: {e}")
finally:
for p in [wav_path, ogg_path]:
try:
if os.path.exists(p):
os.unlink(p)
except OSError:
pass
# --- Fast command handlers ---
@@ -750,8 +787,12 @@ async def _fast_cmd(update: Update, name: str, args: list[str]) -> None:
await update.message.chat.send_action(ChatAction.TYPING)
result = await asyncio.to_thread(fast_dispatch, name, args)
if result:
for chunk in split_message(result):
await update.message.reply_text(chunk)
if result.startswith(_AUDIO_PREFIX):
wav_path = result[len(_AUDIO_PREFIX):]
await _send_voice_telegram(update, wav_path)
else:
for chunk in split_message(result):
await update.message.reply_text(chunk)
else:
await update.message.reply_text(f"Unknown command: /{name}")
@@ -862,6 +903,11 @@ async def cmd_heartbeat_tg(update: Update, context: ContextTypes.DEFAULT_TYPE) -
await _fast_cmd(update, "heartbeat", [])
async def cmd_audio(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/audio [voce] [text|url] — TTS via Supertonic."""
await _fast_cmd(update, "audio", list(context.args or []))
# --- Message handler ---
@@ -954,6 +1000,16 @@ async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
)
return
# Emoji reaction: 👀 = am văzut, procesez
try:
await context.bot.set_message_reaction(
chat_id=chat_id,
message_id=message.message_id,
reaction=[ReactionTypeEmoji(emoji="👀")],
)
except Exception:
pass # Reactions not supported in this chat type — ignore silently
# Show typing indicator
await context.bot.send_chat_action(chat_id=chat_id, action=ChatAction.TYPING)
@@ -983,6 +1039,16 @@ async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) ->
chunks = split_message(response)
for chunk in chunks:
await message.reply_text(chunk)
# Emoji reaction: ✅ = răspuns trimis
try:
await context.bot.set_message_reaction(
chat_id=chat_id,
message_id=message.message_id,
reaction=[ReactionTypeEmoji(emoji="")],
)
except Exception:
pass
except Exception:
logger.exception("Error processing Telegram message from %s", user_id)
await message.reply_text("Sorry, something went wrong processing your message.")
@@ -1037,6 +1103,7 @@ def create_telegram_bot(config: Config, token: str) -> Application:
app.add_handler(CommandHandler("logs", cmd_logs))
app.add_handler(CommandHandler("doctor", cmd_doctor))
app.add_handler(CommandHandler("heartbeat", cmd_heartbeat_tg))
app.add_handler(CommandHandler("audio", cmd_audio))
# Text message handler (must be last)
app.add_handler(
@@ -1068,6 +1135,7 @@ def create_telegram_bot(config: Config, token: str) -> Application:
BotCommand("logs", "Show log lines"),
BotCommand("doctor", "Diagnostics"),
BotCommand("heartbeat", "Health checks"),
BotCommand("audio", "TTS: text → voice note"),
BotCommand("p", "Ralph: propose new project"),
BotCommand("a", "Ralph: approve project for tonight"),
BotCommand("l", "Ralph: list projects status"),