Telemovris 2.0 Rewrite

This commit is contained in:
Joan
2026-01-26 15:17:54 +01:00
commit b128c99334
382 changed files with 6510 additions and 0 deletions

238
src/index.php Normal file
View File

@@ -0,0 +1,238 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
use danog\MadelineProto\API;
use Predis\Client;
$redis = new Client(['host' => getenv('REDIS_HOST') ?: 'redis']);
// Router
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];
// API: Queue
if ($method === 'POST' && $uri === '/api/queue') {
$data = json_decode(file_get_contents('php://input'), true);
if (!$data || !isset($data['username'], $data['message'])) {
http_response_code(400);
echo json_encode(['error' => 'Missing username or message']);
exit;
}
$jobId = uniqid('job_');
$data['id'] = $jobId;
$data['status'] = 'queued';
$data['created_at'] = date('Y-m-d H:i:s');
// Store status
$redis->hmset("job:$jobId", $data);
// Push to processing queue
$redis->rpush('call_queue', json_encode($data));
// Push to history list (for display)
$redis->lpush('job_history', $jobId);
echo json_encode(['job_id' => $jobId, 'status' => 'queued']);
exit;
}
// API: Jobs History
if ($method === 'GET' && $uri === '/api/jobs') {
// Get last 50 jobs
$ids = $redis->lrange('job_history', 0, 49);
$jobs = [];
foreach ($ids as $id) {
$job = $redis->hgetall("job:$id");
if ($job) {
$jobs[] = $job;
}
}
echo json_encode($jobs);
exit;
}
// API: Preview Audio
if ($method === 'POST' && $uri === '/api/preview') {
$data = json_decode(file_get_contents('php://input'), true);
if (!$data || !isset($data['message'])) {
http_response_code(400);
echo json_encode(['error' => 'Missing message']);
exit;
}
try {
require_once __DIR__ . '/TTS.php';
$path = TTS::generate($data['message'], 'es');
$filename = basename($path);
echo json_encode(['url' => "/data/$filename"]);
} catch (\Throwable $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
exit;
}
// API: Status
if ($method === 'GET' && $uri === '/api/status') {
$jobId = $_GET['id'] ?? null;
if (!$jobId) {
http_response_code(400);
echo json_encode(['error' => 'Missing id']);
exit;
}
$status = $redis->hgetall("job:$jobId");
echo json_encode($status ?: ['status' => 'not_found']);
exit;
}
// API: Telegram Status
if ($method === 'GET' && $uri === '/api/me') {
$status = $redis->get('telegram:status') ?: 'unknown';
$me = json_decode($redis->get('telegram:me') ?: '{}', true);
echo json_encode(['status' => $status, 'me' => $me]);
exit;
}
// API: Legacy Send Message (Compatibility)
if ($method === 'GET' && $uri === '/sendmessage') {
$user = $_GET['user'] ?? null;
$message = $_GET['message'] ?? null;
$audioParam = $_GET['audio'] ?? null;
if (!$user || !$message) {
echo "Error: Missing user or message";
exit;
}
$audio = 0;
if ($audioParam && strtolower($audioParam) === 'yes') {
$audio = 1;
}
$jobId = uniqid('job_');
$data = [
'id' => $jobId,
'username' => $user, // Map 'user' to 'username' as used internally
'message' => $message,
'audio_enabled' => ($audio === 1),
'status' => 'queued',
'created_at' => date('Y-m-d H:i:s')
];
// Store status
$redis->hmset("job:$jobId", $data);
// Push to processing queue
$redis->rpush('call_queue', json_encode($data));
// Push to history list
$redis->lpush('job_history', $jobId);
// Return legacy format
echo "Inserted {$user} - {$message} - {$audio}";
exit;
}
// API: Logout
if ($method === 'POST' && $uri === '/api/logout') {
touch('/app/data/logout.signal');
echo json_encode(['status' => 'logout_requested']);
exit;
}
// API: Save Config
if ($method === 'POST' && $uri === '/api/config') {
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['api_id'], $data['api_hash'])) {
http_response_code(400);
echo json_encode(['error' => 'Missing api_id or api_hash']);
exit;
}
file_put_contents('/app/data/config.json', json_encode([
'api_id' => trim($data['api_id']),
'api_hash' => trim($data['api_hash'])
]));
// Force worker restart to pick up new config
touch('/app/data/logout.signal');
echo json_encode(['status' => 'config_saved']);
exit;
}
// API: Reset Config
if ($method === 'POST' && $uri === '/api/reset') {
if (file_exists('/app/data/config.json')) {
unlink('/app/data/config.json');
}
// Force worker restart (which will then see missing config)
touch('/app/data/logout.signal');
echo json_encode(['status' => 'reset_complete']);
exit;
}
// Frontend: Dashboard
if ($method === 'GET' && ($uri === '/' || $uri === '/index.php')) {
include 'dashboard_view.php';
exit;
}
// Frontend: Login UI
if ($method === 'GET' && $uri === '/login') {
include 'login_view.php';
exit;
}
// Frontend: Login Logic
if ($method === 'POST' && $uri === '/login') {
// This is complex because MP interactive login is stateful.
// We will use a dedicated session API wrapper or just basic calls if possible.
// For simplicity, we try to Instantiate MP and check state.
$settings = new \danog\MadelineProto\Settings();
$settings->setAppInfo((new \danog\MadelineProto\Settings\AppInfo())
->setApiId((int)getenv('API_ID'))
->setApiHash(getenv('API_HASH'))
);
$MadelineProto = new API('/app/data/session.madeline', $settings);
$phone = $_POST['phone'] ?? null;
$code = $_POST['code'] ?? null;
$password = $_POST['password'] ?? null;
try {
if ($phone) {
// Create lock file to pause worker
touch('/app/data/login.lock');
$MadelineProto->phoneLogin($phone);
echo json_encode(['status' => 'code_requested']);
} elseif ($code) {
$authorization = $MadelineProto->completePhoneLogin($code);
// If we are here, login was successful (otherwise exception)
unlink('/app/data/login.lock');
echo json_encode(['status' => 'success']);
} elseif ($password) {
$authorization = $MadelineProto->complete2faLogin($password);
unlink('/app/data/login.lock');
echo json_encode(['status' => 'success']);
} else {
echo json_encode(['status' => 'error', 'message' => 'Invalid Request']);
}
} catch (\Throwable $e) {
// Don't remove lock on error immediately, user might retry code?
// Actually if phoneLogin failed, we should probably remove it?
// For now, let's keep it simple. If it's a fatal error or user gives up, they might need to restart.
// Or we can provide a 'reset' button.
// Let's just catch and return error.
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
exit;
}