diff --git a/db.php b/db.php index fa069f6..9e7b362 100644 --- a/db.php +++ b/db.php @@ -56,41 +56,47 @@ function notify_group($group_id, $message) { function notify_waha($action, $module, $item_name) { global $pdo; try { - $u_id = $_SESSION['user_id'] ?? 0; + // Fetch all users with WhatsApp channel enabled and WAHA configured + $stmt = $pdo->query("SELECT id, username, waha_endpoint, waha_chat_id, waha_template, waha_session, waha_api_key FROM users WHERE notify_channels LIKE '%whatsapp%' AND waha_endpoint IS NOT NULL AND waha_endpoint != ''"); + $wa_users = $stmt->fetchAll(); + if (empty($wa_users)) return; + $current_user_name = "System"; - if($u_id) { - $u = get_user($u_id); - if($u) $current_user_name = $u['username']; + if (isset($_SESSION['user_id'])) { + $u = get_user($_SESSION['user_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; - + + foreach ($wa_users as $wu) { + $endpoint = $wu['waha_endpoint']; + $chat_id = $wu['waha_chat_id']; + if (!$endpoint || !$chat_id) continue; + + $template = $wu['waha_template'] ?: "*Update:* {action} on {module} '{item}' by {user}"; $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" + "chatId" => $chat_id, + "text" => $text, + "session" => $wu['waha_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); + $headers = ['Content-Type: application/json']; + if (!empty($wu['waha_api_key'])) { + $headers[] = 'X-Api-Key: ' . $wu['waha_api_key']; + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_TIMEOUT, 2); curl_exec($ch); curl_close($ch); } - } catch(Exception $e) {} + } catch (Exception $e) {} } diff --git a/views/admin.php b/views/admin.php index 6dccc92..7379180 100644 --- a/views/admin.php +++ b/views/admin.php @@ -3,13 +3,15 @@ if(empty($_SESSION['is_admin'])) die("Access Denied"); // ── DB Migrations ───────────────────────────────────────────────────────────── try { $pdo->exec("ALTER TABLE users ADD COLUMN profile_pic TEXT DEFAULT NULL"); } catch(Exception $e) {} +try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_endpoint TEXT DEFAULT NULL"); } catch(Exception $e) {} +try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_chat_id TEXT DEFAULT NULL"); } catch(Exception $e) {} +try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_template TEXT DEFAULT NULL"); } catch(Exception $e) {} +try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_session TEXT DEFAULT 'default'"); } catch(Exception $e) {} +try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_api_key TEXT DEFAULT NULL"); } catch(Exception $e) {} 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 ─────────────────────────────────────────────────────────────── @@ -79,8 +81,13 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { if(isset($_POST['update_user_channels'])) { $ch = $_POST['channels'] ?? []; $ch_str = is_array($ch) ? implode(',', $ch) : ''; - $stmt = $pdo->prepare("UPDATE users SET notify_channels=?, telegram_id=?, email=?, whatsapp_number=? WHERE id=?"); - $stmt->execute([$ch_str, $_POST['telegram_id'], $_POST['email'], $_POST['whatsapp_number'], $_POST['user_id']]); + $waha_ep = trim($_POST['waha_endpoint'] ?? ''); + $waha_cid = trim($_POST['waha_chat_id'] ?? ''); + $waha_tpl = trim($_POST['waha_template'] ?? ''); + $waha_ses = trim($_POST['waha_session'] ?? '') ?: 'default'; + $waha_key = trim($_POST['waha_api_key'] ?? ''); + $stmt = $pdo->prepare("UPDATE users SET notify_channels=?, telegram_id=?, email=?, whatsapp_number=?, waha_endpoint=?, waha_chat_id=?, waha_template=?, waha_session=?, waha_api_key=? WHERE id=?"); + $stmt->execute([$ch_str, $_POST['telegram_id'], $_POST['email'], $_POST['whatsapp_number'], $waha_ep ?: null, $waha_cid ?: null, $waha_tpl ?: null, $waha_ses, $waha_key ?: null, $_POST['user_id']]); $success_msg = "User notification preferences updated!"; } @@ -88,15 +95,12 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { $stmt = $pdo->prepare("UPDATE system_config SET v=? WHERE k=?"); $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!"; } } // ── Fetch Data ──────────────────────────────────────────────────────────────── -$users = query("SELECT id, username, is_admin, notify_channels, telegram_id, email, whatsapp_number, profile_pic FROM users ORDER BY is_admin DESC, username ASC")->fetchAll(); +$users = query("SELECT id, username, is_admin, notify_channels, telegram_id, email, whatsapp_number, profile_pic, waha_endpoint, waha_chat_id, waha_template, waha_session, waha_api_key FROM users ORDER BY is_admin DESC, username ASC")->fetchAll(); $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; @@ -368,60 +372,100 @@ $active_tab = $_GET['tab'] ?? 'overview';

User Notification Channels

-

Configure notification channels (Native, Telegram, Email, WhatsApp) per user.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - +

Configure notification channels per user. WAHA settings appear when WhatsApp is enabled.

+ + +
+
+ + + +
+ +
+ + + + + +
+ + +
+
+
+
+ + + +
+ + +
+ + -
-
UserRoleChannelsTelegram IDEmailWhatsAppSave
-
-
- - - - - -
- -
-
-
- - - -
-
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
WAHA WhatsApp API Settings
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
Variables: {action} {module} {item} {user}
+
+
+ +
+
@@ -445,31 +489,6 @@ $active_tab = $_GET['tab'] ?? 'overview'; -

WAHA WhatsApp Notifications

-

Configure centralized WhatsApp notifications globally via WAHA (WhatsApp HTTP API).

-
- - - -
-
- - -
The full /api/sendText HTTP API endpoint where WAHA is hosted. Leave blank to disable WhatsApp Notification feature.
-
-
- - -
The centralized group or destination ID.
-
-
- - -
Available Variables: {action}, {module}, {item}, {user}
-
-
- -
@@ -493,9 +512,22 @@ function switchTab(name) { document.querySelectorAll('.admin-tab-pane').forEach(p => p.classList.remove('active')); document.querySelector(`[onclick="switchTab('${name}')"]`).classList.add('active'); document.getElementById('tab-'+name).classList.add('active'); - // Update URL without reload const url = new URL(window.location); url.searchParams.set('tab', name); history.replaceState({}, '', url); } + +function toggleWAHA(uid, enabled) { + const section = document.getElementById('waha-section-' + uid); + if (!section) return; + if (enabled) { + section.style.display = 'block'; + section.style.animation = 'fadeIn 0.25s ease'; + } else { + section.style.display = 'none'; + } +} +