mirror of
https://github.com/ellite/Wallos.git
synced 2025-12-23 23:18:07 -05:00
add support for mattermost notifications (#923)
Signed-off-by: Daniela Filipe Bento <danibento@overdestiny.com>
This commit is contained in:
@@ -89,6 +89,8 @@ See instructions to run Wallos below.
|
||||
- openssl
|
||||
- sqlite3
|
||||
- zip
|
||||
- mbstring
|
||||
- fpm
|
||||
|
||||
#### Docker
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ while ($userToNotify = $usersToNotify->fetchArray(SQLITE3_ASSOC)) {
|
||||
$telegramNotificationsEnabled = false;
|
||||
$webhookNotificationsEnabled = false;
|
||||
$pushoverNotificationsEnabled = false;
|
||||
$pushplusNotificationsEnabled = false;
|
||||
$mattermostNotificationsEnabled = false;
|
||||
$discordNotificationsEnabled = false;
|
||||
$ntfyNotificationsEnabled = false;
|
||||
|
||||
@@ -74,7 +76,6 @@ while ($userToNotify = $usersToNotify->fetchArray(SQLITE3_ASSOC)) {
|
||||
$days = $row['days'];
|
||||
}
|
||||
|
||||
|
||||
// Check if email notifications are enabled and get the settings
|
||||
$query = "SELECT * FROM email_notifications WHERE user_id = :userId";
|
||||
$stmt = $db->prepare($query);
|
||||
@@ -141,6 +142,19 @@ while ($userToNotify = $usersToNotify->fetchArray(SQLITE3_ASSOC)) {
|
||||
$pushplusNotificationsEnabled = $row['enabled'];
|
||||
$pushplus['token'] = $row["token"];
|
||||
}
|
||||
// Check if Mattermost notifications are enabled and get the settings
|
||||
$query = "SELECT * FROM mattermost_notifications WHERE user_id = :userID";
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindValue(':userID', $userId, SQLITE3_INTEGER);
|
||||
$result = $stmt->execute();
|
||||
|
||||
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||
$mattermostNotificationsEnabled = $row['enabled'];
|
||||
$mattermost['webhook_url'] = $row['webhook_url'];
|
||||
$mattermost['bot_username'] = $row['bot_username'];
|
||||
$mattermost['bot_icon_emoji'] = $row['bot_icon_emoji'];
|
||||
}
|
||||
|
||||
// Check if Pushover notifications are enabled and get the settings
|
||||
$query = "SELECT * FROM pushover_notifications WHERE user_id = :userId";
|
||||
$stmt = $db->prepare($query);
|
||||
@@ -184,7 +198,7 @@ while ($userToNotify = $usersToNotify->fetchArray(SQLITE3_ASSOC)) {
|
||||
|
||||
$notificationsEnabled = $emailNotificationsEnabled || $gotifyNotificationsEnabled || $telegramNotificationsEnabled ||
|
||||
$webhookNotificationsEnabled || $pushoverNotificationsEnabled || $discordNotificationsEnabled ||$pushplusNotificationsEnabled||
|
||||
$ntfyNotificationsEnabled;
|
||||
$mattermostNotificationsEnabled || $ntfyNotificationsEnabled;
|
||||
|
||||
// If no notifications are enabled, no need to run
|
||||
if (!$notificationsEnabled) {
|
||||
@@ -569,6 +583,69 @@ while ($userToNotify = $usersToNotify->fetchArray(SQLITE3_ASSOC)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Mattermost notifications if enabled
|
||||
if ($mattermostNotificationsEnabled) {
|
||||
foreach ($notify as $userId => $perUser) {
|
||||
// Get name of user from household table
|
||||
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
|
||||
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
|
||||
$result = $stmt->execute();
|
||||
$user = $result->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
// Build Message Content
|
||||
$messageContent = "";
|
||||
if ($user['name']) {
|
||||
$messageContent = $user['name'] . ", the following subscriptions are up for renewal:\n";
|
||||
} else {
|
||||
$messageContent = "The following subscriptions are up for renewal:\n";
|
||||
}
|
||||
|
||||
foreach ($perUser as $subscription) {
|
||||
$dayText = getDaysText($subscription['days']);
|
||||
$messageContent .= $subscription['name'] . " for " . $subscription['formatted_price'] . " (" . $dayText . ")\n";
|
||||
}
|
||||
|
||||
// Prepare Mattermost Data
|
||||
$webhook_url = $mattermost['webhook_url'];
|
||||
$data = array(
|
||||
'username' => $mattermost['bot_username'],
|
||||
'icon_emoji' => $mattermost['bot_icon_emoji'],
|
||||
'text' => mb_convert_encoding($messageContent, 'UTF-8', 'auto'),
|
||||
);
|
||||
|
||||
$data_string = json_encode($data);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $webhook_url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_HTTPHEADER,
|
||||
array(
|
||||
'Content-Type: application/json'
|
||||
),
|
||||
);
|
||||
|
||||
$result = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($result === false) {
|
||||
echo "Error sending Mattermost notifications: " . curl_error($ch) . "<br />";
|
||||
} else {
|
||||
$resultData = json_decode($result, true);
|
||||
if (isset($resultData['code']) && $resultData['code'] == 200) {
|
||||
echo "Mattermost Notifications sent successfully<br />";
|
||||
} else {
|
||||
$errorMsg = isset($resultData['msg']) ? $resultData['msg'] : 'Unknown error';
|
||||
echo "Mattermost API error: " . $errorMsg . "<br />";
|
||||
}
|
||||
}
|
||||
curl_close($ch);
|
||||
}
|
||||
}
|
||||
|
||||
// Pushover notifications if enabled
|
||||
if ($pushoverNotificationsEnabled) {
|
||||
foreach ($notify as $userId => $perUser) {
|
||||
|
||||
72
endpoints/notifications/savemattermostnotifications.php
Executable file
72
endpoints/notifications/savemattermostnotifications.php
Executable file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
require_once '../../includes/connect_endpoint.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate('session_expired', $i18n)
|
||||
]));
|
||||
}
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$postData = file_get_contents("php://input");
|
||||
$data = json_decode($postData, true);
|
||||
|
||||
if (!isset($data["webhook_url"]) || $data["webhook_url"] == "") {
|
||||
$response = [
|
||||
"success" => false,
|
||||
"message" => translate('fill_mandatory_fields', $i18n)
|
||||
];
|
||||
echo json_encode($response);
|
||||
} else {
|
||||
$enabled = $data["enabled"];
|
||||
$webhook_url = $data["webhook_url"];
|
||||
$bot_username = $data["bot_username"];
|
||||
$bot_iconemoji = $data["bot_icon_emoji"];
|
||||
|
||||
$query = "SELECT COUNT(*) FROM mattermost_notifications WHERE user_id = :userId";
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
|
||||
$result = $stmt->execute();
|
||||
|
||||
if ($result === false) {
|
||||
$response = [
|
||||
"success" => false,
|
||||
"message" => translate('error_saving_notifications', $i18n)
|
||||
];
|
||||
echo json_encode($response);
|
||||
} else {
|
||||
$row = $result->fetchArray();
|
||||
$count = $row[0];
|
||||
if ($count == 0) {
|
||||
$query = "INSERT INTO mattermost_notifications (enabled, webhook_url, user_id, bot_username, bot_icon_emoji)
|
||||
VALUES (:enabled, :webhook_url, :userId, :bot_username, :bot_icon_emoji)";
|
||||
} else {
|
||||
$query = "UPDATE mattermost_notifications
|
||||
SET enabled = :enabled, webhook_url = :webhook_url WHERE user_id = :userId";
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':webhook_url', $webhook_url, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':bot_username', $bot_username, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':bot_icon_emoji', $bot_iconemoji, SQLITE3_TEXT);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$response = [
|
||||
"success" => true,
|
||||
"message" => translate('notifications_settings_saved', $i18n)
|
||||
];
|
||||
echo json_encode($response);
|
||||
} else {
|
||||
$response = [
|
||||
"success" => false,
|
||||
"message" => translate('error_saving_notifications', $i18n)
|
||||
];
|
||||
echo json_encode($response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
97
endpoints/notifications/testmattermostnotifications.php
Executable file
97
endpoints/notifications/testmattermostnotifications.php
Executable file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
require_once '../../includes/connect_endpoint.php';
|
||||
|
||||
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate('session_expired', $i18n)
|
||||
]));
|
||||
}
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$postData = file_get_contents("php://input");
|
||||
$data = json_decode($postData, true);
|
||||
|
||||
if (
|
||||
!isset($data["webhook_url"]) || $data["webhook_url"] == "" ||
|
||||
!isset($data["bot_username"]) || $data["bot_username"] == "" ||
|
||||
!isset($data["bot_icon_emoji"]) || $data["bot_icon_emoji"] == ""
|
||||
) {
|
||||
$response = [
|
||||
"success" => false,
|
||||
"message" => translate('fill_mandatory_fields', $i18n)
|
||||
];
|
||||
echo json_encode($response);
|
||||
} else {
|
||||
// Set the message parameters
|
||||
$title = translate('wallos_notification', $i18n);
|
||||
$message = translate('test_notification', $i18n);
|
||||
|
||||
$webhook_url = $data["webhook_url"];
|
||||
$bot_username = $data["bot_username"];
|
||||
$bot_icon_emoji = $data["bot_icon_emoji"];
|
||||
|
||||
// Validate URL scheme
|
||||
$parsedUrl = parse_url($webhook_url);
|
||||
if (
|
||||
!isset($parsedUrl['scheme']) ||
|
||||
!in_array(strtolower($parsedUrl['scheme']), ['http', 'https']) ||
|
||||
!filter_var($webhook_url, FILTER_VALIDATE_URL)
|
||||
) {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate("error", $i18n)
|
||||
]));
|
||||
}
|
||||
|
||||
$postfields = [
|
||||
'text' => $message,
|
||||
];
|
||||
|
||||
if (!empty($bot_username)) {
|
||||
$postfields['username'] = $bot_username;
|
||||
}
|
||||
|
||||
if (!empty($bot_icon_emoji)) {
|
||||
$postfields['icon_emoji'] = $bot_icon_emoji;
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
|
||||
// Set the URL and other options
|
||||
curl_setopt($ch, CURLOPT_URL, $webhook_url);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postfields));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
// Execute the request
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Close the cURL session
|
||||
curl_close($ch);
|
||||
|
||||
// Check if the message was sent successfully
|
||||
if ($response === false) {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate('notification_failed', $i18n)
|
||||
]));
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => true,
|
||||
"message" => translate('notification_sent_successfuly', $i18n)
|
||||
]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate("invalid_request_method", $i18n)
|
||||
]));
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -196,6 +196,10 @@ $i18n = [
|
||||
"telegram_chat_id" => "Telegram Chat ID",
|
||||
"pushplus" => "Pushplus",
|
||||
"pushplus_token" => "Pushplus Token",
|
||||
"mattermost" => "Mattermost",
|
||||
"mattermost_webhook_url" => "WebHook URL",
|
||||
"mattermost_bot_username" => "Bot Username",
|
||||
"mattermost_bot_icon_emoji" => "Bot Icon Emoji",
|
||||
"webhook" => "Webhook",
|
||||
"webhook_url" => "Webhook URL",
|
||||
"request_method" => "Request Method",
|
||||
|
||||
@@ -195,6 +195,10 @@ $i18n = [
|
||||
"telegram_chat_id" => "ID do Chat Telegram",
|
||||
"pushplus" => "Pushplus",
|
||||
"pushplus_token" => "Token do Pushplus",
|
||||
"mattermost" => "Mattermost",
|
||||
"mattermost_webhook_url" => "URL do Hook",
|
||||
"mattermost_bot_username" => "Nome de Utilizador do Bot",
|
||||
"mattermost_bot_icon_emoji" => "Icon Emoji do Bot",
|
||||
"webhook" => "Webhook",
|
||||
"webhook_url" => "URL do Webhook",
|
||||
"request_method" => "Método de Pedido",
|
||||
|
||||
16
migrations/000041.php
Executable file
16
migrations/000041.php
Executable file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
// This migration adds a mattermost_notifications table to store Mattermost notification settings.
|
||||
|
||||
$tableQuery = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='mattermost_notifications'");
|
||||
$tableExists = $tableQuery->fetchArray(SQLITE3_ASSOC);
|
||||
if ($tableExists === false) {
|
||||
$db->exec("
|
||||
CREATE TABLE mattermost_notifications (
|
||||
enabled INTEGER NOT NULL DEFAULT 0,
|
||||
user_id INTEGER,
|
||||
webhook_url TEXT DEFAULT '',
|
||||
bot_username TEXT DEFAULT '',
|
||||
bot_icon_emoji TEXT DEFAULT ''
|
||||
);
|
||||
");
|
||||
}
|
||||
@@ -216,6 +216,44 @@ function saveNotificationsPushPlusButton() {
|
||||
makeFetchCall('endpoints/notifications/savepushplusnotifications.php', data, button);
|
||||
}
|
||||
|
||||
function testNotificationsMattermostButton() {
|
||||
const button = document.getElementById("testNotificationsMattermost");
|
||||
button.disabled = true;
|
||||
|
||||
const enabled = document.getElementById("mattermostenabled").checked ? 1 : 0;
|
||||
const webhook_url = document.getElementById("mattermostwebhookurl").value;
|
||||
const bot_username = document.getElementById("mattermostbotusername").value;
|
||||
const bot_icon_emoji = document.getElementById("mattermostboticonemoji").value;
|
||||
|
||||
const data = {
|
||||
enabled: enabled,
|
||||
webhook_url: webhook_url,
|
||||
bot_username: bot_username,
|
||||
bot_icon_emoji: bot_icon_emoji
|
||||
};
|
||||
|
||||
makeFetchCall('endpoints/notifications/testmattermostnotifications.php', data, button);
|
||||
}
|
||||
|
||||
function saveNotificationsMattermostButton() {
|
||||
const button = document.getElementById("saveNotificationsMattermost");
|
||||
button.disabled = true;
|
||||
|
||||
const enabled = document.getElementById("mattermostenabled").checked ? 1 : 0;
|
||||
const webhook_url = document.getElementById("mattermostwebhookurl").value;
|
||||
const bot_username = document.getElementById("mattermostbotusername").value;
|
||||
const bot_icon_emoji = document.getElementById("mattermostboticonemoji").value;
|
||||
|
||||
const data = {
|
||||
enabled: enabled,
|
||||
webhook_url: webhook_url,
|
||||
bot_username: bot_username,
|
||||
bot_icon_emoji: bot_icon_emoji
|
||||
};
|
||||
|
||||
makeFetchCall('endpoints/notifications/savemattermostnotifications.php', data, button);
|
||||
}
|
||||
|
||||
function saveNotificationsGotifyButton() {
|
||||
const button = document.getElementById("saveNotificationsGotify");
|
||||
button.disabled = true;
|
||||
|
||||
60
settings.php
60
settings.php
@@ -240,6 +240,28 @@ $userData['currency_symbol'] = $currencies[$main_currency]['symbol'];
|
||||
$notificationsPushPlus['token'] = "";
|
||||
}
|
||||
|
||||
// Mattermost notifications
|
||||
$sql = "SELECT * FROM mattermost_notifications WHERE user_id = :userID LIMIT 1";
|
||||
$stmt = $db->prepare($sql);
|
||||
$stmt->bindValue(':userID', $userId, SQLITE3_INTEGER);
|
||||
$result = $stmt->execute();
|
||||
|
||||
$rowCount = 0;
|
||||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||
$notificationsMattermost['enabled'] = $row['enabled'];
|
||||
$notificationsMattermost['webhook_url'] = $row['webhook_url'];
|
||||
$notificationsMattermost['bot_username'] = $row['bot_username'];
|
||||
$notificationsMattermost['bot_icon_emoji'] = $row['bot_icon_emoji'];
|
||||
$rowCount++;
|
||||
}
|
||||
|
||||
if ($rowCount == 0) {
|
||||
$notificationsMattermost['enabled'] = 0;
|
||||
$notificationsMattermost['webhook_url'] = "";
|
||||
$notificationsMattermost['bot_username'] = "";
|
||||
$notificationsMattermost['bot_icon_emoji'] = "";
|
||||
}
|
||||
|
||||
// Ntfy notifications
|
||||
$sql = "SELECT * FROM ntfy_notifications WHERE user_id = :userId LIMIT 1";
|
||||
$stmt = $db->prepare($sql);
|
||||
@@ -597,6 +619,44 @@ $userData['currency_symbol'] = $currencies[$main_currency]['symbol'];
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="account-notifications-section">
|
||||
<header class="account-notification-section-header" onclick="openNotificationsSettings('mattermost');">
|
||||
<h3>
|
||||
<i class="fa-solid fa-bell"></i>
|
||||
<?= translate('mattermost', $i18n) ?>
|
||||
</h3>
|
||||
</header>
|
||||
<div class="account-notification-section-settings" data-type="mattermost">
|
||||
<div class="form-group-inline">
|
||||
<input type="checkbox" id="mattermostenabled" name="mattermostenabled"
|
||||
<?= $notificationsMattermost['enabled'] ? "checked" : "" ?>>
|
||||
<label for="mattermostenabled" class="capitalize"><?= translate('enabled', $i18n) ?></label>
|
||||
</div>
|
||||
<div class="form-group-inline">
|
||||
<input type="text" name="mattermostwebhookurl" id="mattermostwebhookurl"
|
||||
placeholder="<?= translate('mattermost_webhook_url', $i18n) ?>"
|
||||
value="<?= $notificationsMattermost['webhook_url'] ? $notificationsMattermost['webhook_url'] : '' ?>" />
|
||||
</div>
|
||||
<div class="form-group-inline">
|
||||
<input type="text" name="mattermostbotusername" id="mattermostbotusername"
|
||||
placeholder="<?= translate('mattermost_bot_username', $i18n) ?>"
|
||||
value="<?= $notificationsMattermost['bot_username'] ? $notificationsMattermost['bot_username'] : '' ?>" />
|
||||
</div>
|
||||
<div class="form-group-inline">
|
||||
<input type="text" name="mattermostboticonemoji" id="mattermostboticonemoji"
|
||||
placeholder="<?= translate('mattermost_bot_icon_emoji', $i18n) ?>"
|
||||
value="<?= $notificationsMattermost['bot_icon_emoji'] ? $notificationsMattermost['bot_icon_emoji'] : '' ?>" />
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="button" class="secondary-button thin mobile-grow"
|
||||
value="<?= translate('test', $i18n) ?>" id="testNotificationsMattermost"
|
||||
onClick="testNotificationsMattermostButton()" />
|
||||
<input type="submit" class="thin mobile-grow" value="<?= translate('save', $i18n) ?>"
|
||||
id="saveNotificationsMattermost" onClick="saveNotificationsMattermostButton()" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="account-notifications-section">
|
||||
<header class="account-notification-section-header" onclick="openNotificationsSettings('ntfy');">
|
||||
<h3>
|
||||
|
||||
Reference in New Issue
Block a user