diff --git a/db.php b/db.php index 8930318..fa069f6 100644 --- a/db.php +++ b/db.php @@ -52,3 +52,45 @@ function notify_group($group_id, $message) { notify_user($u['user_id'], $message); } } + +function notify_waha($action, $module, $item_name) { + global $pdo; + try { + $u_id = $_SESSION['user_id'] ?? 0; + $current_user_name = "System"; + if($u_id) { + $u = get_user($u_id); + if($u) $current_user_name = $u['username']; + } + + $stmt = $pdo->query("SELECT waha_endpoint, waha_chat_id, waha_template FROM users WHERE notify_channels LIKE '%whatsapp%' AND waha_endpoint IS NOT NULL AND waha_endpoint != ''"); + while ($user = $stmt->fetch()) { + $endpoint = $user['waha_endpoint']; + $chat_id = $user['waha_chat_id']; + $template = $user['waha_template'] ?: "*Update:* {action} on {module} '{item}' by {user}"; + + if(!$endpoint || !$chat_id) continue; + + $text = str_replace( + ['{action}', '{module}', '{item}', '{user}'], + [$action, $module, $item_name, $current_user_name], + $template + ); + + $payload = json_encode([ + "chatId" => $chat_id, + "text" => $text, + "session" => "default" + ]); + + $ch = curl_init($endpoint); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); + curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); + curl_setopt($ch, CURLOPT_TIMEOUT, 1); + curl_exec($ch); + curl_close($ch); + } + } catch(Exception $e) {} +} diff --git a/index.php b/index.php index b2dfe5e..39303ef 100644 --- a/index.php +++ b/index.php @@ -39,6 +39,8 @@ if ($action === 'api') { $status = $_POST['status'] ?? null; $stmt = $pdo->prepare("UPDATE tasks SET status = ?, status_updated_at = CURRENT_TIMESTAMP WHERE id = ?"); $stmt->execute([$status, $task_id]); + $task_to_upd = query("SELECT title FROM tasks WHERE id=?", [$task_id])->fetch(); + if($task_to_upd) notify_waha('Moved to '.$status, 'Task Status', $task_to_upd['title']); echo json_encode(['status'=>'ok']); exit; } diff --git a/views/admin.php b/views/admin.php index 5cae6fd..6dccc92 100644 --- a/views/admin.php +++ b/views/admin.php @@ -7,6 +7,9 @@ try { $pdo->exec("CREATE TABLE IF NOT EXISTS system_config (k TEXT PRIMARY KEY, v TEXT)"); $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('completed_days', '7')"); $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('archived_days', '90')"); + $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('waha_endpoint', '')"); + $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('waha_chat_id', '')"); + $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('waha_template', '')"); } catch(Exception $e) {} // ── Handle POST ─────────────────────────────────────────────────────────────── @@ -83,8 +86,11 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { if(isset($_POST['update_sys_config'])) { $stmt = $pdo->prepare("UPDATE system_config SET v=? WHERE k=?"); - $stmt->execute([$_POST['completed_days'], 'completed_days']); - $stmt->execute([$_POST['archived_days'], 'archived_days']); + $stmt->execute([$_POST['completed_days'] ?? 7, 'completed_days']); + $stmt->execute([$_POST['archived_days'] ?? 90, 'archived_days']); + $stmt->execute([$_POST['waha_endpoint'] ?? '', 'waha_endpoint']); + $stmt->execute([$_POST['waha_chat_id'] ?? '', 'waha_chat_id']); + $stmt->execute([$_POST['waha_template'] ?? '', 'waha_template']); $success_msg = "System configuration saved!"; } } @@ -94,6 +100,9 @@ $users = query("SELECT id, username, is_admin, notify_channels, telegram_id, ema $all_groups = query("SELECT * FROM groups ORDER BY name")->fetchAll(); $conf_comp = query("SELECT v FROM system_config WHERE k='completed_days'")->fetchColumn() ?: 7; $conf_arch = query("SELECT v FROM system_config WHERE k='archived_days'")->fetchColumn() ?: 90; +$waha_endpoint = query("SELECT v FROM system_config WHERE k='waha_endpoint'")->fetchColumn() ?: ''; +$waha_chat_id = query("SELECT v FROM system_config WHERE k='waha_chat_id'")->fetchColumn() ?: ''; +$waha_template = query("SELECT v FROM system_config WHERE k='waha_template'")->fetchColumn() ?: ''; // Activity stats for admin $total_users = count($users); @@ -436,6 +445,31 @@ $active_tab = $_GET['tab'] ?? 'overview'; +
Configure centralized WhatsApp notifications globally via WAHA (WhatsApp HTTP API).
+ diff --git a/views/notes.php b/views/notes.php index dcf5d1b..9795423 100644 --- a/views/notes.php +++ b/views/notes.php @@ -43,6 +43,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { } $stmt = $pdo->prepare("INSERT INTO notes (title, content, owner_id, color, image_path, label_name) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$_POST['title'] ?? 'Untitled', $_POST['content'], $user_id, $_POST['color'] ?? null, $image_path, trim($_POST['label_name'] ?? '') ?: null]); + notify_waha('Created', 'Note', $_POST['title'] ?? 'Untitled'); } if(isset($_POST['update_note'])) { @@ -67,14 +68,16 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { } $stmt = $pdo->prepare("UPDATE notes SET title=?, content=?, color=?, image_path=?, label_name=?, updated_at=CURRENT_TIMESTAMP WHERE id=? AND owner_id=?"); $stmt->execute([$_POST['title'] ?? 'Untitled', $_POST['content'], $_POST['color'] ?? null, $image_path, trim($_POST['label_name'] ?? '') ?: null, $_POST['note_id'], $user_id]); + notify_waha('Updated', 'Note', $_POST['title'] ?? 'Untitled'); } } if(isset($_POST['delete_note'])) { - $n = query("SELECT owner_id, image_path FROM notes WHERE id=?", [$_POST['note_id']])->fetch(); + $n = query("SELECT owner_id, image_path, title FROM notes WHERE id=?", [$_POST['note_id']])->fetch(); if($n && $n['owner_id'] == $user_id) { if($n['image_path'] && file_exists($n['image_path'])) @unlink($n['image_path']); query("DELETE FROM notes WHERE id=? AND owner_id=?", [$_POST['note_id'], $user_id]); + notify_waha('Deleted', 'Note', $n['title'] ?? 'Untitled'); } } @@ -89,6 +92,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { $msg = "A note '{$n['title']}' has been shared with you."; if($parts[0] === 'user') notify_user($parts[1], $msg); else notify_group($parts[1], $msg); + notify_waha('Shared', 'Note', $n['title'] ?? 'Untitled'); } } diff --git a/views/passwords.php b/views/passwords.php index 5b98378..d4b4600 100644 --- a/views/passwords.php +++ b/views/passwords.php @@ -28,6 +28,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { if(isset($_POST['create_password'])) { $stmt = $pdo->prepare("INSERT INTO passwords (title, username, password, url, notes, owner_id, folder_id, tags) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$_POST['title'], $_POST['username'], $_POST['password'], $_POST['url'], $_POST['notes'], $user_id, $_POST['folder_id'] ?: null, trim($_POST['tags'] ?? '')]); + notify_waha('Created', 'Password Entry', $_POST['title']); } if(isset($_POST['update_password'])) { @@ -35,13 +36,15 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { if($p && $p['owner_id'] == $user_id) { $stmt = $pdo->prepare("UPDATE passwords SET title=?, username=?, password=?, url=?, notes=?, folder_id=?, tags=? WHERE id=? AND owner_id=?"); $stmt->execute([$_POST['title'], $_POST['username'], $_POST['password'], $_POST['url'], $_POST['notes'], $_POST['folder_id'] ?: null, trim($_POST['tags'] ?? ''), $_POST['password_id'], $user_id]); + notify_waha('Updated', 'Password Entry', $_POST['title']); } } if(isset($_POST['delete_password'])) { - $p = query("SELECT owner_id FROM passwords WHERE id=?", [$_POST['password_id']])->fetch(); + $p = query("SELECT owner_id, title FROM passwords WHERE id=?", [$_POST['password_id']])->fetch(); if($p && $p['owner_id'] == $user_id) { query("DELETE FROM passwords WHERE id=? AND owner_id=?", [$_POST['password_id'], $user_id]); + notify_waha('Deleted', 'Password Entry', $p['title']); } } @@ -57,8 +60,11 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['bulk_action']; if($action === 'delete') { foreach($selected as $p_id) { - $p = query("SELECT owner_id FROM passwords WHERE id=?", [$p_id])->fetch(); - if($p && $p['owner_id']==$user_id) query("DELETE FROM passwords WHERE id=?", [$p_id]); + $p = query("SELECT owner_id, title FROM passwords WHERE id=?", [$p_id])->fetch(); + if($p && $p['owner_id']==$user_id) { + query("DELETE FROM passwords WHERE id=?", [$p_id]); + notify_waha('Deleted', 'Password Entry', $p['title']); + } } } elseif($action === 'share') { $share_target = $_POST['share_target']; @@ -72,6 +78,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { $msg = "A password '{$p['title']}' has been shared with you."; if($parts[0] === 'user') notify_user($parts[1], $msg); else notify_group($parts[1], $msg); + notify_waha('Shared', 'Password Entry', $p['title']); } } } diff --git a/views/projects.php b/views/projects.php index 490dcf4..62a6f00 100644 --- a/views/projects.php +++ b/views/projects.php @@ -4,16 +4,20 @@ $parent_id = $_GET['folder'] ?? null; if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_folder'])) { $stmt = $pdo->prepare("INSERT INTO projects (name, is_folder, parent_id, owner_id) VALUES (?, 1, ?, ?)"); $stmt->execute([$_POST['name'], $parent_id, $user_id]); + notify_waha('Created', 'Folder', $_POST['name']); } if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_item'])) { + $item = query("SELECT name FROM projects WHERE id=?", [$_POST['item_id']])->fetch(); $stmt = $pdo->prepare("DELETE FROM projects WHERE id=? AND owner_id=?"); $stmt->execute([$_POST['item_id'], $user_id]); + if($item) notify_waha('Deleted', 'File/Folder', $item['name']); } if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['edit_item'])) { $stmt = $pdo->prepare("UPDATE projects SET name=? WHERE id=? AND owner_id=?"); $stmt->execute([$_POST['new_name'], $_POST['item_id'], $user_id]); + notify_waha('Renamed', 'File/Folder', $_POST['new_name']); } if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['upload_file']) && isset($_FILES['file'])) { @@ -24,6 +28,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['upload_file']) && isse move_uploaded_file($tmp_name, $path); $stmt = $pdo->prepare("INSERT INTO projects (name, is_folder, parent_id, file_path, owner_id) VALUES (?, 0, ?, ?, ?)"); $stmt->execute([$name, $parent_id, $path, $user_id]); + notify_waha('Uploaded', 'File', $name); echo "OK"; exit; } @@ -38,6 +43,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['share_project'])) { $msg = "A project/file '{$pr['name']}' has been shared with you."; if($parts[0] === 'user') notify_user($parts[1], $msg); else notify_group($parts[1], $msg); + notify_waha('Shared', 'File/Folder', $pr['name']); } } diff --git a/views/tasks.php b/views/tasks.php index 41d444a..4b53d21 100644 --- a/views/tasks.php +++ b/views/tasks.php @@ -38,7 +38,9 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_task'])) { } if($can_delete) { + $task_to_del = query("SELECT title FROM tasks WHERE id=?", [$del_id])->fetch(); query("DELETE FROM tasks WHERE id=?", [$del_id]); + if($task_to_del) notify_waha('Deleted', 'Task', $task_to_del['title']); } } @@ -155,6 +157,8 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_task'])) { } } + notify_waha('Created', 'Task', $title); + if(isset($_POST['ajax_submit'])) { echo json_encode(['success'=>true, 'redirect'=>'?action=tasks&msg_title='.urlencode('Task Created').'&msg_body='.urlencode('Task successfully created.')]); exit;