Added support for Telegram (#554)

Added support for Telegram. Notifications can be received in private chat or in groupchat.

This will close #389 and is a preview of what's coming next (#459) 😉.
This commit is contained in:
Tim 2018-02-26 23:23:50 +01:00 committed by Timz99
parent b0fee68f6e
commit 6eda990ed0
No known key found for this signature in database
GPG Key ID: 4D8268DC68E8339D
23 changed files with 328 additions and 28 deletions

View File

@ -491,6 +491,17 @@ function psm_build_pushover() {
return $pushover;
}
/**
*
* @return \psm\Txtmsg\TxtmsgInterface
*/
function psm_build_telegram() {
$telegram = new \Telegram();
$telegram->setToken(psm_get_conf('telegram_api_token'));
return $telegram;
}
/**
* Prepare a new SMS util.
*
@ -712,7 +723,7 @@ function psm_password_decrypt($key, $encryptedString)
if (empty($key))
throw new \InvalidArgumentException('invalid_encryption_key');
$data = base64_decode($encryptedString);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
@ -728,4 +739,41 @@ function psm_password_decrypt($key, $encryptedString)
);
return $decrypted;
}
}
/**
* Send notification to Telegram
*
* @return string
* @author Tim Zandbergen <tim@xervion.nl>
*/
class telegram
{
private $_token;
private $_user;
private $_message;
private $_url;
public function setToken ($token) {
$this->_token = (string)$token;
}
public function setUser ($user) {
$this->_user = (string)$user;
}
public function setMessage ($message) {
$this->_message = (string)$message;
}
public function send () {
if(!Empty($this->_token) && !Empty($this->_user) && !Empty($this->_message)) {
$this->_url = 'https://api.telegram.org/bot' . urlencode($this->_token) . '/sendMessage?chat_id=' . urlencode($this->_user) . '&text=' . urlencode($this->_message);
}
$con = curl_init($this->_url);
curl_setopt($con, CURLOPT_RETURNTRANSFER, true);
curl_setopt($con, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($con, CURLOPT_TIMEOUT, 60);
$response = curl_exec($con);
$response = json_decode($response, true);
return $response;
}
}

View File

@ -107,6 +107,11 @@ define('PSM_CURL_TIMEOUT', 10);
*/
define('PSM_PUSHOVER_CLONE_URL', 'https://pushover.net/apps/clone/php_server_monitor');
/**
* Get chat id for Telegram service.
*/
define('PSM_TELEGRAM_GET_ID_URL', 'https://telegram.me/cid_bot');
/**
* By defining the PSM_BASE_URL, you will force the psm_build_url() to use this.
* Useful for cronjobs if it cannot be auto-detected.

View File

@ -88,6 +88,11 @@ $sm_lang = array(
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Device name to send the message to. Leave empty to send it to all devices.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to get real-time notifications. Visit the <a href="http://docs.phpservermonitor.org/">documentation</a> for more info and an install guide.',
'telegram_chat_id' => 'Telegram chat id',
'telegram_chat_id_description' => 'The message will be send to the corresponding chat.',
'telegram_get_chat_id' => 'Click here to get your chat id',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
@ -112,6 +117,7 @@ $sm_lang = array(
'email' => 'Email',
'sms' => 'SMS',
'pushover' => 'Pushover',
'telegram' => 'Telegram',
'no_logs' => 'No logs',
'clear' => 'Clear log',
'delete_title' => 'Delete log',
@ -153,6 +159,7 @@ $sm_lang = array(
'sms' => 'SMS',
'send_sms' => 'Send SMS',
'pushover' => 'Pushover',
'telegram' => 'Telegram',
'users' => 'Users',
'delete_title' => 'Delete server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
@ -181,6 +188,7 @@ $sm_lang = array(
'warning_notifications_disabled_sms' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover notifications are disabled.',
'warning_notifications_disabled_telegram' => 'Telegram notifications are disabled.',
'error_server_no_match' => 'Server not found.',
'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.',
'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.',
@ -234,6 +242,10 @@ $sm_lang = array(
'pushover_clone_app' => 'Click here to create your Pushover app',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank">register an App</a> at their website and enter the App API Token here.',
'telegram_status' => 'Allow sending Telegram messages',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to get real-time notifications. Visit the <a href="http://docs.phpservermonitor.org/">documentation</a> for more info and an install guide.',
'telegram_api_token' => 'Telegram API Token',
'telegram_api_token_description' => 'Before you can use Telegram, you need to get a API token. Open your Telegram app and search for @Botfather.',
'alert_type' => 'Select when you\'d like to be notified.',
'alert_type_description' => '<b>Status change:</b> '.
'You will receive a notifcation when a server has a change in status. So from online -> offline or offline -> online.<br/>'.
@ -253,13 +265,16 @@ $sm_lang = array(
'log_email' => 'Log emails sent by the script',
'log_sms' => 'Log text messages sent by the script',
'log_pushover' => 'Log pushover messages sent by the script',
'log_telegram' => 'Log Telegram messages sent by the script',
'updated' => 'The configuration has been updated.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_pushover' => 'Pushover',
'tab_telegram' => 'Telegram',
'settings_email' => 'Email settings',
'settings_sms' => 'Text message settings',
'settings_pushover' => 'Pushover settings',
'settings_telegram' => 'Telegram settings',
'settings_notification' => 'Notification settings',
'settings_log' => 'Log settings',
'settings_proxy' => 'Proxy settings',
@ -274,6 +289,7 @@ $sm_lang = array(
'test_email' => 'An email will be sent to the address specified in your user profile.',
'test_sms' => 'An SMS will be sent to the phone number specified in your user profile.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'test_telegram' => 'A Telegram notification will be sent to the chat id specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
@ -286,6 +302,10 @@ $sm_lang = array(
'pushover_error' => 'An error has occurred while sending the Pushover notification: %s',
'pushover_error_noapp' => 'Unable to send test notification: no Pushover App API token found in the global configuration.',
'pushover_error_nokey' => 'Unable to send test notification: no Pushover key found in your profile.',
'telegram_sent' => 'Telegram notification sent',
'telegram_error' => 'An error has occurred while sending the Telegram notification: %s',
'telegram_error_notoken' => 'Unable to send test notification: no Telegram API token found in the global configuration.',
'telegram_error_noid' => 'Unable to send test notification: no chat id found in your profile.',
'log_retention_period' => 'Log retention period',
'log_retention_period_description' => 'Number of days to keep logs of notifications and archives of server uptime. Enter 0 to disable log cleanup.',
'log_retention_days' => 'days',
@ -297,11 +317,13 @@ $sm_lang = array(
'off_email_body' => "Failed to connect to the following server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'off_pushover_title' => 'Server \'%LABEL%\' is DOWN',
'off_pushover_message' => "Failed to connect to the following server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'off_telegram_message' => "Failed to connect to the following server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'on_sms' => 'Server \'%LABEL%\' is RUNNING: ip=%IP%, port=%PORT%',
'on_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is RUNNING',
'on_email_body' => "Server '%LABEL%' is running again:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%",
'on_pushover_title' => 'Server \'%LABEL%\' is RUNNING',
'on_pushover_message' => 'Server \'%LABEL%\' is running again:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%',
'on_telegram_message' => 'Server \'%LABEL%\' is running again:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%',
),
'login' => array(
'welcome_usermenu' => 'Welcome, %user_name%',

View File

@ -41,10 +41,12 @@ class ConfigController extends AbstractController {
'email_smtp',
'sms_status',
'pushover_status',
'telegram_status',
'log_status',
'log_email',
'log_sms',
'log_pushover',
'log_telegram',
'show_update',
);
@ -66,6 +68,7 @@ class ConfigController extends AbstractController {
'sms_gateway_password',
'sms_from',
'pushover_api_token',
'telegram_api_token',
);
private $default_tab = 'general';
@ -135,7 +138,7 @@ class ConfigController extends AbstractController {
$tpl_data[$this->default_tab . '_active'] = 'active';
$testmodals = array('email', 'sms', 'pushover');
$testmodals = array('email', 'sms', 'pushover', 'telegram');
foreach($testmodals as $modal_id) {
$modal = new \psm\Util\Module\Modal($this->twig, 'test' . ucfirst($modal_id), \psm\Util\Module\Modal::MODAL_TYPE_OKCANCEL);
$this->addModal($modal);
@ -186,6 +189,8 @@ class ConfigController extends AbstractController {
$this->testSMS();
} elseif(!empty($_POST['test_pushover'])) {
$this->testPushover();
} elseif(!empty($_POST['test_telegram'])) {
$this->testTelegram();
}
if($language_refresh) {
@ -201,6 +206,8 @@ class ConfigController extends AbstractController {
$this->default_tab = 'sms';
} elseif(isset($_POST['pushover_submit']) || !empty($_POST['test_pushover'])) {
$this->default_tab = 'pushover';
} elseif(isset($_POST['telegram_submit']) || !empty($_POST['test_telegram'])) {
$this->default_tab = 'telegram';
}
}
return $this->runAction('index');
@ -287,14 +294,49 @@ class ConfigController extends AbstractController {
}
}
/**
* Execute telegram test
*
* @todo move test to separate class
*/
protected function testTelegram() {
$telegram = psm_build_telegram();
$user = $this->getUser()->getUser();
$api_token = psm_get_conf('telegram_api_token');
if(empty($api_token)) {
$this->addMessage(psm_get_lang('config', 'telegram_error_notoken'), 'error');
} elseif(empty($user->telegram_id)) {
$this->addMessage(psm_get_lang('config', 'telegram_error_noid'), 'error');
} else {
$telegram->setMessage(psm_get_lang('config', 'test_message'));
$telegram->setUser($user->telegram_id);
$result = $telegram->send();
if(isset($result['ok']) && $result['ok'] != false) {
$this->addMessage(psm_get_lang('config', 'telegram_sent'), 'success');
} else {
if(isset($result['description'])) {
$error = $result['description'];
} else {
$error = 'Unknown';
}
$this->addMessage(sprintf(psm_get_lang('config', 'telegram_error'), $error), 'error');
}
}
}
protected function getLabels() {
return array(
'label_tab_email' => psm_get_lang('config', 'tab_email'),
'label_tab_sms' => psm_get_lang('config', 'tab_sms'),
'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'),
'label_tab_telegram' => psm_get_lang('config', 'tab_telegram'),
'label_settings_email' => psm_get_lang('config', 'settings_email'),
'label_settings_sms' => psm_get_lang('config', 'settings_sms'),
'label_settings_pushover' => psm_get_lang('config', 'settings_pushover'),
'label_settings_telegram' => psm_get_lang('config', 'settings_telegram'),
'label_settings_notification' => psm_get_lang('config', 'settings_notification'),
'label_settings_log' => psm_get_lang('config', 'settings_log'),
'label_settings_proxy' => psm_get_lang('config', 'settings_proxy'),
@ -346,6 +388,10 @@ class ConfigController extends AbstractController {
psm_get_lang('config', 'pushover_api_token_description'),
PSM_PUSHOVER_CLONE_URL
),
'label_telegram_description' => psm_get_lang('config', 'telegram_description'),
'label_telegram_status' => psm_get_lang('config', 'telegram_status'),
'label_telegram_api_token' => psm_get_lang('config', 'telegram_api_token'),
'label_telegram_api_token_description' => psm_get_lang('config', 'telegram_api_token_description'),
'label_alert_type' => psm_get_lang('config', 'alert_type'),
'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'),
'label_alert_type_status' => psm_get_lang('config', 'alert_type_status'),
@ -356,6 +402,7 @@ class ConfigController extends AbstractController {
'label_log_email' => psm_get_lang('config', 'log_email'),
'label_log_sms' => psm_get_lang('config', 'log_sms'),
'label_log_pushover' => psm_get_lang('config', 'log_pushover'),
'label_log_telegram' => psm_get_lang('config', 'log_telegram'),
'label_alert_proxy' => psm_get_lang('config', 'alert_proxy'),
'label_alert_proxy_url' => psm_get_lang('config', 'alert_proxy_url'),
'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'),
@ -368,4 +415,4 @@ class ConfigController extends AbstractController {
'label_log_retention_days' => psm_get_lang('config', 'log_retention_days'),
);
}
}
}

View File

@ -214,6 +214,7 @@ class InstallController extends AbstractController {
'level' => PSM_USER_ADMIN,
'pushover_key' => '',
'pushover_device' => '',
'telegram_id' => '',
);
$validator = $this->container->get('util.user.validator');

View File

@ -75,6 +75,7 @@ abstract class AbstractServerController extends AbstractController {
`s`.`email`,
`s`.`sms`,
`s`.`pushover`,
`s`.`telegram`,
`s`.`warning_threshold`,
`s`.`warning_threshold_counter`,
`s`.`timeout`,
@ -106,6 +107,7 @@ abstract class AbstractServerController extends AbstractController {
$server['email'] = psm_get_lang('system', $server['email']);
$server['sms'] = psm_get_lang('system', $server['sms']);
$server['pushover'] = psm_get_lang('system', $server['pushover']);
$server['telegram'] = psm_get_lang('system', $server['telegram']);
if($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) {
$server['status'] = 'warning';

View File

@ -51,6 +51,7 @@ class LogController extends AbstractServerController {
'label_email' => psm_get_lang('log', 'email'),
'label_sms' => psm_get_lang('log', 'sms'),
'label_pushover' => psm_get_lang('log', 'pushover'),
'label_telegram' => psm_get_lang('log', 'telegram'),
'label_title' => psm_get_lang('log', 'title'),
'label_server' => psm_get_lang('servers', 'server'),
'label_type' => psm_get_lang('log', 'type'),
@ -71,7 +72,7 @@ class LogController extends AbstractServerController {
$tpl_data['has_admin_actions'] = true;
}
$log_types = array('status', 'email', 'sms', 'pushover');
$log_types = array('status', 'email', 'sms', 'pushover', 'telegram');
foreach($log_types as $key) {
$records = $this->getEntries($key);

View File

@ -92,6 +92,7 @@ class ServerController extends AbstractServerController {
'email' => 'icon-envelope',
'sms' => 'icon-mobile',
'pushover' => 'icon-pushover',
'telegram' => 'icon-telegram',
);
$servers = $this->getServers();
@ -208,10 +209,11 @@ class ServerController extends AbstractServerController {
'edit_email_selected_' . $edit_server['email'] => 'selected="selected"',
'edit_sms_selected_' . $edit_server['sms'] => 'selected="selected"',
'edit_pushover_selected_' . $edit_server['pushover'] => 'selected="selected"',
'edit_telegram_selected_' . $edit_server['telegram'] => 'selected="selected"',
));
}
$notifications = array('email', 'sms', 'pushover');
$notifications = array('email', 'sms', 'pushover', 'telegram');
foreach($notifications as $notification) {
if(psm_get_conf($notification . '_status') == 0) {
$tpl_data['warning_' . $notification] = true;
@ -272,6 +274,7 @@ class ServerController extends AbstractServerController {
'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : 'no',
'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no',
'pushover' => in_array($_POST['pushover'], array('yes', 'no')) ? $_POST['pushover'] : 'no',
'telegram' => in_array($_POST['telegram'], array('yes', 'no')) ? $_POST['telegram'] : 'no',
);
// make sure websites start with http://
if($clean['type'] == 'website' && substr($clean['ip'], 0, 4) != 'http') {
@ -479,6 +482,7 @@ class ServerController extends AbstractServerController {
'label_sms' => psm_get_lang('servers', 'sms'),
'label_send_sms' => psm_get_lang('servers', 'send_sms'),
'label_pushover' => psm_get_lang('servers', 'pushover'),
'label_telegram' => psm_get_lang('servers', 'telegram'),
'label_users' => psm_get_lang('servers', 'users'),
'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'),
'label_warning_threshold_description' => psm_get_lang('servers', 'warning_threshold_description'),

View File

@ -35,7 +35,7 @@ class ProfileController extends AbstractController {
* Editable fields for the profile
* @var array $profile_fields
*/
protected $profile_fields = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'email');
protected $profile_fields = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id', 'email');
function __construct(Database $db, \Twig_Environment $twig) {
parent::__construct($db, $twig);
@ -66,6 +66,12 @@ class ProfileController extends AbstractController {
'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_chat_id' => psm_get_lang('users', 'telegram_chat_id'),
'label_telegram_chat_id_description' => psm_get_lang('users', 'telegram_chat_id_description'),
'label_telegram_get_chat_id' => psm_get_lang('users', 'telegram_get_chat_id'),
'telegram_get_chat_id_url' => PSM_TELEGRAM_GET_ID_URL,
'label_email' => psm_get_lang('users', 'email'),
'label_save' => psm_get_lang('system', 'save'),
'form_action' => psm_build_url(array(
@ -135,4 +141,4 @@ class ProfileController extends AbstractController {
return $this->executeIndex();
}
}
}

View File

@ -89,7 +89,7 @@ class UserController extends AbstractController {
$users = $this->db->select(
PSM_DB_PREFIX.'users',
null,
array('user_id', 'user_name', 'level', 'name', 'mobile', 'pushover_key', 'pushover_device', 'email'),
array('user_id', 'user_name', 'level', 'name', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id', 'email'),
null,
array('name')
);
@ -133,7 +133,7 @@ class UserController extends AbstractController {
*/
protected function executeEdit() {
$user_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$fields_prefill = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'email');
$fields_prefill = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id', 'email');
if($user_id == 0) {
// insert mode
@ -215,7 +215,7 @@ class UserController extends AbstractController {
}
$user_id = (isset($_GET['id'])) ? intval($_GET['id']) : 0;
$fields = array('name', 'user_name', 'password', 'password_repeat', 'level', 'mobile', 'pushover_key', 'pushover_device', 'email');
$fields = array('name', 'user_name', 'password', 'password_repeat', 'level', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id', 'email');
$clean = array();
foreach($fields as $field) {
if(isset($_POST[$field])) {
@ -333,6 +333,10 @@ class UserController extends AbstractController {
'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_id' => psm_get_lang('users', 'telegram_id'),
'label_telegram_id_description' => psm_get_lang('users', 'telegram_id_description'),
'label_email' => psm_get_lang('users', 'email'),
'label_servers' => psm_get_lang('menu', 'server'),
'label_action' => psm_get_lang('system', 'action'),

View File

@ -126,7 +126,7 @@ class Installer {
$this->log('Populating database...');
$queries = array();
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` (`ip`, `port`, `label`, `type`, `pattern`, `status`, `active`, `email`, `sms`, `pushover`) VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '', 'on', 'yes', 'yes', 'yes', 'yes'), ('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '', 'on', 'yes', 'yes', 'yes', 'yes')";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` (`ip`, `port`, `label`, `type`, `pattern`, `status`, `active`, `email`, `sms`, `pushover`, `telegram`) VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '', 'on', 'yes', 'yes', 'yes', 'yes', 'yes'), ('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '', 'on', 'yes', 'yes', 'yes', 'yes', 'yes')";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users_servers` (`user_id`,`server_id`) VALUES (1, 1), (1, 2);";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('language', 'en_US'),
@ -150,12 +150,15 @@ class Installer {
('sms_from', '1234567890'),
('pushover_status', '0'),
('pushover_api_token', ''),
('telegram_status', '0'),
('telegram_api_token', ''),
('password_encrypt_key', '" . sha1(microtime()) . "'),
('alert_type', 'status'),
('log_status', '1'),
('log_email', '1'),
('log_sms', '1'),
('log_pushover', '1'),
('log_telegram', '1'),
('log_retention_period', '365'),
('version', '" . PSM_VERSION . "'),
('version_update_check', '" . PSM_VERSION . "'),
@ -189,6 +192,7 @@ class Installer {
`mobile` varchar(15) NOT NULL,
`pushover_key` varchar(255) NOT NULL,
`pushover_device` varchar(255) NOT NULL,
`telegram_id` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `unique_username` (`user_name`)
@ -207,7 +211,7 @@ class Installer {
PSM_DB_PREFIX . 'log' => "CREATE TABLE `" . PSM_DB_PREFIX . "log` (
`log_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`type` enum('status','email','sms','pushover') NOT NULL,
`type` enum('status','email','sms','pushover','telegram') NOT NULL,
`message` varchar(255) NOT NULL,
`datetime` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`log_id`)
@ -235,10 +239,11 @@ class Installer {
`email` enum('yes','no') NOT NULL default 'yes',
`sms` enum('yes','no') NOT NULL default 'no',
`pushover` enum('yes','no') NOT NULL default 'yes',
`warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1',
`warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0',
`timeout` smallint(1) unsigned NULL DEFAULT NULL,
`website_username` varchar(255) DEFAULT NULL,
`telegram` enum('yes','no') NOT NULL default 'yes',
`warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1',
`warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0',
`timeout` smallint(1) unsigned NULL DEFAULT NULL,
`website_username` varchar(255) DEFAULT NULL,
`website_password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
@ -299,6 +304,9 @@ class Installer {
if(version_compare($version_from, '3.2.1', '<')) {
$this->upgrade321();
}
if(version_compare($version_from, '3.2.2', '<')) {
$this->upgrade322();
}
psm_update_conf('version', $version_to);
}
@ -492,4 +500,19 @@ class Installer {
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD COLUMN `header_name` VARCHAR(255) AFTER `pattern`, ADD COLUMN `header_value` VARCHAR(255) AFTER `header_name`";
$this->execSQL($queries);
}
/**
* Upgrade for v3.2.2 release
*/
protected function upgrade322() {
$queries = array();
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` ADD `telegram_id` VARCHAR( 255 ) NOT NULL AFTER `pushover_device`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `telegram` ENUM( 'yes','no' ) NOT NULL DEFAULT 'yes' AFTER `pushover`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "log` CHANGE `type` `type` ENUM( 'status', 'email', 'sms', 'pushover', 'telegram' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('telegram_status', '0'),
('log_telegram', '1'),
('telegram_api_token', '');";
$this->execSQL($queries);
}
}

View File

@ -56,13 +56,13 @@ class UpdateManager extends ContainerAware {
)";
}
$sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`header_name`,`s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`
$sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`header_name`,`s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram`
FROM `".PSM_DB_PREFIX."servers` AS `s`
{$sql_join}
WHERE `active`='yes' ";
$servers = $this->container->get('db')->query($sql);
$updater = new Updater\StatusUpdater($this->container->get('db'));
$notifier = new Updater\StatusNotifier($this->container->get('db'));
@ -78,4 +78,4 @@ class UpdateManager extends ContainerAware {
$archive->archive();
$archive->cleanup();
}
}
}

View File

@ -60,6 +60,12 @@ class StatusNotifier {
*/
protected $send_pushover = false;
/**
* Send telegram?
* @var boolean $send_telegram
*/
protected $send_telegram = false;
/**
* Save log records?
* @var boolean $save_log
@ -96,6 +102,7 @@ class StatusNotifier {
$this->send_emails = psm_get_conf('email_status');
$this->send_sms = psm_get_conf('sms_status');
$this->send_pushover = psm_get_conf('pushover_status');
$this->send_telegram = psm_get_conf('telegram_status');
$this->save_logs = psm_get_conf('log_status');
}
@ -121,7 +128,7 @@ class StatusNotifier {
$this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array(
'server_id' => $server_id,
), array(
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'header_name', 'header_value', 'error', 'active', 'email', 'sms', 'pushover',
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'header_name', 'header_value', 'error', 'active', 'email', 'sms', 'pushover', 'telegram',
));
if(empty($this->server)) {
return false;
@ -188,6 +195,12 @@ class StatusNotifier {
$this->notifyByPushover($users);
}
// check if telegram is enabled for this server
if($this->send_telegram && $this->server['telegram'] == 'yes') {
// yay lets wake those nerds up!
$this->notifyByTelegram($users);
}
return $notify;
}
@ -313,6 +326,43 @@ class StatusNotifier {
return $result;
}
/**
* This functions performs the telegram notifications
*
* @param array $users
* @return boolean
*/
protected function notifyByTelegram($users) {
// Remove users that have no telegram_id
foreach($users as $k => $user) {
if (trim($user['telegram_id']) == '') {
unset($users[$k]);
}
}
// Validation
if (empty($users)) {
return;
}
// Telegram
$message = psm_parse_msg($this->status_new, 'telegram_message', $this->server);
$telegram = psm_build_telegram();
$telegram->setMessage(str_replace('<br/>', "\n", $message));
// Log
if(psm_get_conf('log_telegram')) {
$log_id = psm_add_log($this->server_id, 'telegram', $message);
}
foreach($users as $user) {
// Log
if(!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']);
}
$telegram->setUser($user['telegram_id']);
$telegram->send();
}
}
/**
* Get all users for the provided server id
* @param int $server_id
@ -321,7 +371,7 @@ class StatusNotifier {
public function getUsers($server_id) {
// find all the users with this server listed
$users = $this->db->query("
SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`, `u`.`pushover_device`
SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`, `u`.`pushover_device`, `u`.`telegram_id`
FROM `".PSM_DB_PREFIX."users` AS `u`
JOIN `".PSM_DB_PREFIX."users_servers` AS `us` ON (
`us`.`user_id`=`u`.`user_id`

View File

@ -5,6 +5,7 @@
<li class="{{ email_active }}"><a href="#config-email" data-toggle="tab">{{ label_tab_email }}</a></li>
<li class="{{ sms_active }}"><a href="#config-sms" data-toggle="tab">{{ label_tab_sms }}</a></li>
<li class="{{ pushover_active }}"><a href="#config-pushover" data-toggle="tab">{{ label_tab_pushover }}</a></li>
<li class="{{ telegram_active }}"><a href="#config-telegram" data-toggle="tab">{{ label_tab_telegram }}</a></li>
</ul>
<div class="tab-content well">
<div id="config-general" class="tab-pane {{ general_active }}">
@ -266,6 +267,38 @@
</div>
</fieldset>
</div>
<div id="config-telegram" class="tab-pane {{ telegram_active }}">
<fieldset>
<legend>{{ label_settings_telegram }}</legend>
<div class="control-group">
<div class="controls">
<label class="checkbox" for="telegram_status"><input type="checkbox" id="telegram_status" name="telegram_status[]" {{ telegram_status_checked|raw }} /> {{ label_telegram_status }}</label>
<p class="help-block">{{ label_telegram_description|raw }}</p>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox"><input type="checkbox" id="log_telegram" name="log_telegram[]" {{ log_telegram_checked|raw }} /> {{ label_log_telegram }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label" for="telegram_api_token">{{ label_telegram_api_token }}</label>
<div class="controls">
<input type="text" id="telegram_api_token" name="telegram_api_token" value="{{ telegram_api_token }}" maxlength="255" />
<p class="help-block">{{ label_telegram_api_token_description|raw }}</p>
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn btn-primary show-modal" data-modal-id="testTelegram">{{ label_test }}</button>
<input type="hidden" name="test_telegram" value="0" />
</div>
</div>
<div class="form-actions">
<button class="btn btn-success" type="submit" name="telegram_submit">{{ label_save }}</button>
</div>
</fieldset>
</div>
</div>
{{ macro.csrf_input() }}
</form>

View File

@ -10,6 +10,7 @@
<li><a href="#log_email_content" data-toggle="tab">{{ label_email }}</a></li>
<li><a href="#log_sms_content" data-toggle="tab">{{ label_sms }}</a></li>
<li><a href="#log_pushover_content" data-toggle="tab">{{ label_pushover }}</a></li>
<li><a href="#log_telegram_content" data-toggle="tab">{{ label_telegram }}</a></li>
</ul>
<div class="tab-content well">
{% for tab in tabs %}

View File

@ -23,7 +23,15 @@
<td class="nowrap visible-desktop"><div class="table-cell-title">{{ server.type }}</div></td>
<td class="nowrap hidden-phone"><div class="table-cell-title">{{ server.rtime }} s</div></td>
<td class="nowrap hidden-phone"><div class="table-cell-title">{{ server.last_online }}</div></td>
<td class="tight hidden-phone"><div class="table-cell-title"><i class="{{ server.active_icon }}" title="{{ server.active_title }}"></i> <i class="{{ server.email_icon }}" title="{{ label_email }}"></i> <i class="{{ server.sms_icon }}" title="{{ label_sms }}"></i> <i class="{{ server.pushover_icon }}" title="Pushover"></i></div></td>
<td class="tight hidden-phone">
<div class="table-cell-title">
<i class="{{ server.active_icon }}" title="{{ server.active_title }}"></i>
<i class="{{ server.email_icon }}" title="{{ label_email }}"></i>
<i class="{{ server.sms_icon }}" title="{{ label_sms }}"></i>
<i class="{{ server.pushover_icon }}" title="Pushover"></i>
<i class="{{ server.telegram_icon }}" title="Telegram"></i>
</div>
</td>
<td class="tight hidden-phone">
<div class="table-cell-title">
<a class="btn btn-small" href="{{ server.url_view|raw }}"><i class="icon-chart"></i></a>
@ -51,7 +59,11 @@
<div class="table-row">
<div class="table-cell"><i class="{{ server.type_icon }}" title="{{ server.type }}"></i> {{ server.ip_short|raw }}</div>
<div class="table-cell tight">
<i class="{{ server.active_icon }}" title="{{ server.active_title }}"></i> <i class="{{ server.email_icon }}" title="{{ label_email }}"></i> <i class="{{ server.sms_icon }}" title="{{ label_sms }}"></i> <i class="{{ server.pushover_icon }}" title="Pushover"></i>
<i class="{{ server.active_icon }}" title="{{ server.active_title }}"></i>
<i class="{{ server.email_icon }}" title="{{ label_email }}"></i>
<i class="{{ server.sms_icon }}" title="{{ label_sms }}"></i>
<i class="{{ server.pushover_icon }}" title="Pushover"></i>
<i class="{{ server.telegram_icon }}" title="Telegram"></i>
</div>
</div>
</div>
@ -63,4 +75,4 @@
</tr>
{% endfor %}
</tbody>
</table>
</table>

View File

@ -146,6 +146,17 @@
</select>
</div>
</div>
<div class="control-group {{ control_class_telegram }}">
<label class="control-label" for="telegram">{{ label_telegram }}
{% if warning_telegram %} <p class="help-inline"><i class="icon-warning-sign" data-toggle="tooltip" title="{{ label_warning_telegram }}"></i></p> {% endif %}
</label>
<div class="controls">
<select id="telegram" name="telegram">
<option value="yes" {{ edit_telegram_selected_yes|raw }}>{{ label_yes }}</option>
<option value="no" {{ edit_telegram_selected_no|raw }}>{{ label_no }}</option>
</select>
</div>
</div>
</fieldset>
<fieldset>

View File

@ -69,6 +69,10 @@
<td>{{ label_pushover }}:</td>
<td>{{ pushover }}</td>
</tr>
<tr>
<td>{{ label_telegram }}:</td>
<td>{{ telegram }}</td>
</tr>
<tr>
<td>{{ label_timeout }}:</td>
<td>{{ timeout }} s</td>
@ -100,4 +104,4 @@
{% endif %}
</tbody>
</table>
{{ html_history|raw }}
{{ html_history|raw }}

View File

@ -62,6 +62,18 @@
<input type="text" id="pushover_device" name="pushover_device" value="{{ pushover_device }}" maxlength="255" data-toggle="tooltip" title="{{ label_pushover_device_description }}" />
</div>
</div>
<div class="control-group">
</div>
<div class="control-group">
<label class="control-label">{{ label_telegram }}</label>
<div class="controls">{{ label_telegram_description|raw }} <br><p><button class="btn btn-primary" onclick="window.open('{{ telegram_get_chat_id_url }}');return false;">{{ label_telegram_get_chat_id }}</button></p></div>
</div>
<div class="control-group">
<label class="control-label" for="mobile">{{ label_telegram_chat_id }}</label>
<div class="controls">
<input type="text" id="telegram_id" name="telegram_id" maxlength="255" data-toggle="tooltip" title="{{ label_telegram_chat_id_description }}" />
</div>
</div>
</div>
</div>
<div class="row-fluid">
@ -70,4 +82,4 @@
</div>
</div>
</fieldset>
</form>
</form>

View File

@ -66,6 +66,16 @@
<input type="text" id="pushover_device" name="pushover_device" value="{{ edit_value_pushover_device }}" maxlength="255" data-toggle="tooltip" title="{{ label_pushover_device_description }}" />
</div>
</div>
<div class="control-group">
<label class="control-label">{{ label_telegram }}</label>
<div class="controls">{{ label_telegram_description|raw }} </div>
</div>
<div class="control-group">
<label class="control-label" for="telegram_id">{{ label_telegram_id }}</label>
<div class="controls">
<input type="text" id="telegram_id" name="telegram_id" value="{{ edit_value_telegram_id }}" maxlength="255" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="server_id">{{ label_servers }}</label>
<div class="controls">

View File

@ -671,4 +671,8 @@ legend{
.icon-pushover {
background-position: -72px -168px;
}
}
.icon-telegram {
background-position: -96px -168px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 43 KiB