allerta-vvf/backend/telegramBotRouter.php

374 lines
15 KiB
PHP
Raw Normal View History

2022-01-04 15:02:40 +01:00
<?php
use skrtdev\NovaGram\Bot;
use skrtdev\Telegram\Message;
2022-03-12 20:58:49 +01:00
use skrtdev\Telegram\CallbackQuery;
2022-01-04 15:02:40 +01:00
require_once 'utils.php';
2022-01-05 18:31:03 +01:00
define('NONE', 0);
define('WEBHOOK', 1);
$Bot = null;
function initializeBot($mode = WEBHOOK) {
global $Bot;
if (is_null($Bot)) {
if(defined("BASE_PATH")){
$base_path = "/".BASE_PATH."api/bot/telegram";
} else {
$base_path = "/api/bot/telegram";
}
$_SERVER['SCRIPT_URL'] = $base_path;
$NovagramConfig = [
"disable_ip_check" => true, //TODO: fix NovaGram ip check and enable it again
"parse_mode" => "HTML",
"mode" => $mode
];
if(defined("BOT_TELEGRAM_DEBUG_USER")){
$NovagramConfig["debug"] = BOT_TELEGRAM_DEBUG_USER;
}
$Bot = new Bot(BOT_TELEGRAM_API_KEY, $NovagramConfig);
}
}
2022-03-12 20:58:49 +01:00
function getUserIdByFrom($from_id)
2022-01-05 00:51:59 +01:00
{
global $db;
2022-03-12 20:58:49 +01:00
return $db->selectValue("SELECT user FROM `".DB_PREFIX."_bot_telegram` WHERE `chat_id` = ?", [$from_id]);
}
function getUserIdByMessage(Message $message)
{
return getUserIdByFrom($message->from->id);
2022-01-05 00:51:59 +01:00
}
function requireBotLogin(Message $message)
{
2022-02-10 09:46:40 +01:00
global $users;
2022-01-05 00:51:59 +01:00
$userId = getUserIdByMessage($message);
if ($userId === null) {
$message->reply(
"Non hai ancora collegato il tuo account Allerta al bot.".
"\nPer farlo, premere su <strong>\"Collega l'account al bot Telegram\"</strong>."
);
exit();
2022-02-10 09:46:40 +01:00
} else {
if($users->auth->hasRole(\Delight\Auth\Role::CONSULTANT)) {
//Migrate to new user roles
$users->auth->admin()->removeRoleForUserById($users->auth->getUserId(), \Delight\Auth\Role::CONSULTANT);
$users->auth->admin()->addRoleForUserById($users->auth->getUserId(), Role::SUPER_EDITOR);
}
2022-01-05 00:51:59 +01:00
}
}
2022-03-12 20:58:49 +01:00
function sendTelegramNotification($message, $do_not_send_if_same=true)
2022-01-05 18:31:03 +01:00
{
global $Bot, $db;
if(is_null($Bot)) initializeBot(NONE);
2022-03-12 20:58:49 +01:00
$sentMessages = [];
2022-01-05 18:31:03 +01:00
//TODO: implement different types of notifications
//TODO: add command for subscribing to notifications
2022-01-10 12:30:44 +01:00
$chats = $db->select("SELECT * FROM `".DB_PREFIX."_bot_telegram_notifications`");
2022-01-05 18:31:03 +01:00
if(!is_null($chats)) {
foreach ($chats as $chat) {
2022-03-12 20:58:49 +01:00
if($do_not_send_if_same && urldecode($chat['last_notification']) === $message) continue;
2022-01-05 18:31:03 +01:00
$chat = $chat['chat_id'];
2022-03-12 20:58:49 +01:00
$sendMessage = $Bot->sendMessage([
2022-01-05 18:31:03 +01:00
"chat_id" => $chat,
"text" => $message
]);
2022-01-10 12:30:44 +01:00
$db->update(
DB_PREFIX."_bot_telegram_notifications",
2022-01-12 21:24:12 +01:00
["last_notification" => urlencode($message)],
["chat_id" => $chat]
2022-01-10 12:30:44 +01:00
);
2022-03-13 00:36:35 +01:00
$sentMessages[$chat] = $sendMessage->message_id;
2022-01-05 18:31:03 +01:00
}
}
2022-03-12 20:58:49 +01:00
return $sentMessages;
2022-01-05 18:31:03 +01:00
}
2022-03-12 20:58:49 +01:00
function sendTelegramNotificationToUser($message, $userId, $options = [])
{
global $Bot, $db;
if(is_null($Bot)) initializeBot(NONE);
$chat = $db->selectValue("SELECT `chat_id` FROM `".DB_PREFIX."_bot_telegram` WHERE `user` = ?", [$userId]);
if(!is_null($chat)) {
2022-03-12 20:58:49 +01:00
$message_response = $Bot->sendMessage(array_merge([
"chat_id" => $chat,
"text" => $message
2022-03-12 20:58:49 +01:00
], $options));
return [$message_response->message_id, $chat];
}
}
2022-03-14 00:13:45 +01:00
function generateAlertMessage($alertType, $alertEnabled, $alertNotes, $alertCreatedBy, $alertDeleted=false) {
2022-03-12 20:58:49 +01:00
global $users;
$message =
2022-03-14 00:13:45 +01:00
"<b><i><u>".($alertEnabled ? "Allertamento in corso" : ($alertDeleted ? "Allertamento completato" : "Allerta rimossa")).":</u></i></b> ".
2022-03-13 18:44:39 +01:00
($alertType === "full" ? "Richiesta <b>squadra completa 🚒</b>" : "<b>Supporto 🧯</b>\n");
if(!is_null($alertNotes) && $alertNotes !== "") {
$message .= "Note:\n<b>".$alertNotes."</b>\n";
}
if(!is_null($alertCreatedBy)) {
$message .= "Lanciata da: <b>".$users->getName($alertCreatedBy)."</b>\n";
}
return $message;
}
2022-03-14 00:13:45 +01:00
function generateAlertReportMessage($alertType, $crew, $alertEnabled, $alertNotes, $alertCreatedBy, $alertDeleted=false) {
2022-03-13 18:44:39 +01:00
global $users;
$message = generateAlertMessage($alertType, $alertEnabled, $alertNotes, $alertCreatedBy);
$message .= "\nSquadra:\n";
2022-03-13 00:36:35 +01:00
2022-03-12 20:58:49 +01:00
foreach($crew as $member) {
2022-03-14 00:13:45 +01:00
if((!$alertEnabled || $alertDeleted) && $member["response"] === "waiting") continue;
2022-03-12 20:58:49 +01:00
$user = $users->getUserById($member['id']);
$message .= "<i>".$user["name"]."</i> ";
if($user["chief"]) $message .= "CS";
if($user["driver"]) $message .= "🚒";
$message .= "- ";
2022-03-13 00:36:35 +01:00
if($member["response"] === "waiting") {
$message .= "In attesa 🟡";
} else if($member["response"] === true) {
$message .= "Presente 🟢";
} else if($member["response"] === false) {
$message .= "Assente 🔴";
2022-03-12 20:58:49 +01:00
}
$message .= "\n";
}
return $message;
}
2022-03-14 00:13:45 +01:00
function sendAlertReportMessage($alertType, $crew, $alertEnabled, $alertNotes, $alertCreatedBy, $alertDeleted = false) {
$message = generateAlertReportMessage($alertType, $crew, $alertEnabled, $alertNotes, $alertCreatedBy, $alertDeleted);
2022-03-12 20:58:49 +01:00
return sendTelegramNotification($message, false);
}
2022-03-14 00:13:45 +01:00
function sendAlertRequestMessage($alertType, $userId, $alertId, $alertNotes, $alertCreatedBy, $alertDeleted = false) {
return sendTelegramNotificationToUser(generateAlertMessage($alertType, true, $alertNotes, $alertCreatedBy, $alertDeleted), $userId, [
2022-03-12 20:58:49 +01:00
'reply_markup' => [
'inline_keyboard' => [
[
[
'text' => '✅ Partecipo',
2022-03-13 18:44:39 +01:00
'callback_data' => "alert_yes_".$alertId
2022-03-12 20:58:49 +01:00
],
[
'text' => 'Non partecipo ❌',
2022-03-13 18:44:39 +01:00
'callback_data' => "alert_no_".$alertId
2022-03-12 20:58:49 +01:00
]
]
]
]
]);
}
2022-01-05 00:51:59 +01:00
function yesOrNo($value)
{
return ($value === 1 || $value) ? '<b>SI</b>' : '<b>NO</b>';
}
2022-01-04 15:02:40 +01:00
function telegramBotRouter() {
2022-01-05 18:31:03 +01:00
global $Bot;
2022-01-04 15:02:40 +01:00
2022-01-05 23:10:13 +01:00
define("running_telegram_bot_webhook", true);
2022-01-05 18:31:03 +01:00
initializeBot();
2022-01-04 15:02:40 +01:00
$Bot->addErrorHandler(function ($e) {
print('Caught '.get_class($e).' exception from general handler'.PHP_EOL);
print($e.PHP_EOL);
});
$Bot->onCommand('start', function (Message $message, array $args = []) {
2022-01-05 00:51:59 +01:00
global $db;
if(isset($args[0])) {
$registered_chats = $db->select("SELECT * FROM `".DB_PREFIX."_bot_telegram` WHERE `chat_id` = ?", [$message->from->id]);
if(!is_null($registered_chats) && count($registered_chats) > 1) {
$message->chat->sendMessage(
"⚠️ Questo account Allerta è già associato ad un'altro utente Telegram.".
"\nContattare un amministratore."
);
return;
}
$response = $db->update(
DB_PREFIX.'_bot_telegram',
['chat_id' => $message->from->id],
['tmp_login_token' => $args[0]]
);
if($response === 1) {
2022-01-05 23:10:13 +01:00
logger("Utente collegato ad account telegram (".$message->from->id.")");
2022-01-05 00:51:59 +01:00
$message->chat->sendMessage(
"✅ Login avvenuto con successo!".
"\nPer ottenere informazioni sul profilo, utilizzare il comando /info".
"\nPer ricevere informazioni sui comandi, utilizzare il comando /help o visualizzare il menu dei comandi da Telegram"
);
} else {
$message->chat->sendMessage(
"⚠️ Chiave di accesso non valida, impossibile eseguire il login.".
"\nRiprovare o contattare un amministratore."
);
}
} else {
$message->chat->sendMessage(
"Per iniziare, è necessario collegare l'account di Allerta con Telegram.".
"\nPer farlo, premere su <strong>\"Collega l'account al bot Telegram\"</strong>."
);
}
});
$Bot->onCommand('help', function (Message $message, array $args = []) {
$message->chat->sendMessage(
" Elenco dei comandi disponibili:".
"\n/info - Ottieni informazioni sul profilo connesso".
"\n/help - Ottieni informazioni sui comandi".
"\n/attiva - Modifica la tua disponibilità in \"reperibile\"".
"\n/disattiva - Modifica la tua disponibilità in \"non reperibile\"".
2022-01-07 00:28:25 +01:00
"\n/programma - Abilita programmazione oraria".
"\n/disponibili - Mostra un elenco dei vigili attualmente disponibili".
"\n/stato - Mostra lo stato della disponibilità della squadra"
2022-01-05 00:51:59 +01:00
);
2022-01-04 15:02:40 +01:00
});
2022-03-15 14:11:07 +01:00
$Bot->onCommand('debug_userid', function (Message $message) {
2022-03-15 14:14:48 +01:00
global $Bot;
2022-03-15 14:11:07 +01:00
$messageText = "🔎 ID utente Telegram: <b>".$message->from->id."</b>";
if(isset($message->from->username)) {
$messageText .= "\n💬 Username: <b>".$message->from->username."</b>";
}
if(isset($message->from->first_name)) {
$messageText .= "\n🔎 Nome: <b>".$message->from->first_name."</b>";
}
if(isset($message->from->last_name)) {
$messageText .= "\n🔎 Cognome: <b>".$message->from->last_name."</b>";
}
if(isset($message->from->language_code)) {
$messageText .= "\n🌐 Lingua: <b>".$message->from->language_code."</b>";
}
if(isset($message->from->is_bot)) {
$messageText .= "\n🤖 Bot: <b>".yesOrNo($message->from->is_bot)."</b>";
}
$message->reply($messageText);
2022-03-15 14:14:48 +01:00
if(defined("BOT_TELEGRAM_DEBUG_USER")){
$messageText .= "\n\n🔎 JSON del messaggio: <b>".json_encode($message)."</b>";
$Bot->sendMessage(BOT_TELEGRAM_DEBUG_USER, $messageText);
}
2022-03-15 14:11:07 +01:00
});
2022-01-04 15:02:40 +01:00
$Bot->onCommand('info', function (Message $message) {
2022-01-05 00:51:59 +01:00
global $users;
$user_id = getUserIdByMessage($message);
if(is_null($user_id)) {
$message->chat->sendMessage('⚠️ Questo account Telegram non è associato a nessun utente di Allerta.');
} else {
2022-03-12 20:58:49 +01:00
$user = $users->getUserById($user_id);
2022-01-05 00:51:59 +01:00
$message->chat->sendMessage(
" Informazioni sul profilo:".
"\n<i>Nome:</i> <b>".$user["name"]."</b>".
2022-01-05 12:24:44 +01:00
"\n<i>Disponibile:</i> ".yesOrNo($user["available"]).
2022-01-05 00:51:59 +01:00
"\n<i>Caposquadra:</i> ".yesOrNo($user["chief"] === 1).
"\n<i>Autista:</i> ".yesOrNo($user["driver"] === 1).
"\n<i>Interventi svolti:</i> <b>".$user["services"]."</b>".
"\n<i>Esercitazioni svolte:</i> <b>".$user["trainings"]."</b>".
"\n<i>Minuti di disponibilità:</i> <b>".$user["availability_minutes"]."</b>"
);
}
});
//Too difficult and "spaghetti to explain it here in comments, please use https://regexr.com/
//Jokes apart, checks if text contains something like "Attiva", "attiva", "Disponibile", "disponibile" but not "Non ", "non ", "Non_", "non_", "Dis" or "dis"
2022-01-05 14:37:33 +01:00
$Bot->onText("/\/?(Sono |sono |Io sono |Io sono )?(?<!non( |_))(?<!dis)(?<!Non( |_))(?<!Dis)(Attiva|Attivami|Attivo|Disponibile|Operativo|attiva|attivami|attivo|disponibile|operativo)/", function (Message $message, $matches = []) {
2022-01-05 22:54:05 +01:00
global $Bot, $availability;
2022-01-05 00:51:59 +01:00
requireBotLogin($message);
2022-01-05 14:37:33 +01:00
if(count(explode(" ", $message->text)) > 3) return;
2022-01-05 00:51:59 +01:00
$user_id = getUserIdByMessage($message);
2022-01-06 22:16:15 +01:00
$availability->change(1, $user_id, true);
$Bot->sendMessage($message->from->id, "Disponibilità aggiornata con successo.\nOra sei <b>operativo</b>.");
2022-01-05 00:51:59 +01:00
});
2022-01-05 22:54:05 +01:00
$Bot->onText("/\/?(Io |Io sono )?(Disattiva|Disattivo|Disattivami|Non( |_)attivo|Non( |_)(Sono |sono )?disponibile|Non( |_)(Sono |sono )?operativo|disattiva|disattivo|sisattivami|non( |_)(Sono |sono )?attivo|non( |_)(Sono |sono )?disponibile|non( |_)(Sono |sono )?operativo)/", function (Message $message, $matches = []) {
global $Bot, $availability;
2022-01-05 00:51:59 +01:00
requireBotLogin($message);
2022-01-05 14:37:33 +01:00
if(count(explode(" ", $message->text)) > 4) return;
2022-01-05 00:51:59 +01:00
$user_id = getUserIdByMessage($message);
2022-01-06 22:16:15 +01:00
$availability->change(0, $user_id, true);
$Bot->sendMessage($message->from->id, "Disponibilità aggiornata con successo.\nOra sei <b>non operativo</b>.");
});
$Bot->onText("/\/?(Abilita( |_)|abilita( |_)|Attiva( |_)|attiva( |_))?(Programma|Programmazione|programmazione|Programmazione( |_)oraria|programma|programmazione( |_)oraria)/", function (Message $message, $matches = []) {
global $Bot, $availability;
requireBotLogin($message);
if(count(explode(" ", $message->text)) > 3) return;
2022-01-07 00:38:43 +01:00
$userId = getUserIdByMessage($message);
$availability->change_manual_mode(0, $userId);
$Bot->sendMessage($message->from->id, "Programmazione oraria <b>abilitata</b>.\nPer disabilitarla (e tornare in modalità manuale), cambiare la disponbilità usando i comandi \"/attiva\" e \"/disattiva\"");
2022-01-05 00:51:59 +01:00
});
2022-01-07 00:09:57 +01:00
$Bot->onText("/\/?(Stato|stato)( |_)?(Distaccamento|distaccamento)?/", function (Message $message, $matches = []) {
global $db;
requireBotLogin($message);
if(count(explode(" ", $message->text)) > 2) return;
$available_users_count = $db->selectValue("SELECT COUNT(id) FROM `".DB_PREFIX."_profiles` WHERE `available` = 1 AND `hidden` = 0");
2022-01-07 00:38:43 +01:00
if($available_users_count >= 5) {
2022-01-07 22:09:57 +01:00
$message->reply("🚒 Distaccamento operativo con squadra completa");
2022-01-07 00:38:43 +01:00
} else if($available_users_count >= 2) {
2022-01-07 00:09:57 +01:00
$message->reply("🧯 Distaccamento operativo per supporto");
2022-01-07 00:38:43 +01:00
} else if($available_users_count >= 0) {
2022-01-07 00:09:57 +01:00
$message->reply("⚠️ Distaccamento non operativo");
}
});
$Bot->onText("/\/?(Elenco|elenco|Elenca|elenca)?(_| )?(Disponibili|disponibili)/", function (Message $message, $matches = []) {
2022-01-05 00:51:59 +01:00
global $db, $users;
requireBotLogin($message);
2022-01-05 14:37:33 +01:00
if(count(explode(" ", $message->text)) > 2) return;
2022-01-08 20:31:13 +01:00
$result = $db->select("SELECT `chief`, `driver`, `available`, `name` FROM `".DB_PREFIX."_profiles` WHERE available = 1 and hidden = 0 ORDER BY chief DESC, services ASC, trainings DESC, availability_minutes DESC, name ASC");
2022-01-05 00:51:59 +01:00
if(!is_null($result) && count($result) > 0) {
$msg = " Vigili attualmente disponibili:";
foreach($result as $user) {
$msg .= "\n<b>".$user["name"]."</b>";
if($user["driver"]) $msg .= " 🚒";
if($user["chief"]) {
2022-01-05 22:32:03 +01:00
$msg .= " CS";
2022-01-05 00:51:59 +01:00
}
}
} else {
$msg = "⚠️ Nessun vigile disponibile.";
}
$message->reply($msg);
2022-01-04 15:02:40 +01:00
});
2022-03-12 20:58:49 +01:00
$Bot->onCallbackQuery(function (CallbackQuery $callback_query) use ($Bot) {
$user = $callback_query->from;
$message = $callback_query->message;
$chat = $message->chat;
if(strpos($callback_query->data, 'alert_') === 0) {
$data = explode("_", str_replace("alert_", "", $callback_query->data));
2022-03-13 18:44:39 +01:00
$alert_id = $data[1];
2022-03-12 20:58:49 +01:00
setAlertResponse($data[0] === "yes", getUserIdByFrom($user->id), $alert_id);
return;
}
});
2022-01-04 15:02:40 +01:00
$Bot->start();
2022-03-12 20:58:49 +01:00
}