Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add telegram notifications #2997

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/admin/settings/index.php
Expand Up @@ -541,6 +541,16 @@
</td>
</tr>

<!-- Telegram API settings -->
<tr>
<td class="title"><?php print _('Telegram bot API Token'); ?></td>
<td>
<input type="text" class="form-control input-sm" name="telegramBotCode" value="<?php print $settings['telegramBotCode']; ?>">
</td>
<td class="info2">
<?php print _('Set Telegram bot API Token'); ?>
</td>
</tr>

<!-- ICPM -->
<tr class="settings-title">
Expand Down
4 changes: 3 additions & 1 deletion app/admin/settings/settings-save.php
Expand Up @@ -103,7 +103,9 @@
"pingStatus" =>@$_POST['pingStatus'],
"scanPingPath" =>@$_POST['scanPingPath'],
"scanFPingPath" =>@$_POST['scanFPingPath'],
"scanMaxThreads" =>@$_POST['scanMaxThreads']
"scanMaxThreads" =>@$_POST['scanMaxThreads'],
// telegram token
"telegramBotCode" =>isset($_POST) && isset($_POST['telegramBotCode']) ? $_POST['telegramBotCode'] : null
);
// Update linked_field indexes
$Tools->verify_linked_field_indexes($_POST['link_field']);
Expand Down
5 changes: 4 additions & 1 deletion app/admin/users/edit-result.php
Expand Up @@ -113,7 +113,10 @@
"mailNotify" =>$_POST['mailNotify'],
"mailChangelog" =>$_POST['mailChangelog'],
"theme" =>$_POST['theme']=="default" ? "" : $_POST['theme'],
"disabled" =>$_POST['disabled']=="Yes" ? "Yes" : "No"
"disabled" =>$_POST['disabled']=="Yes" ? "Yes" : "No",
"telegramId" => isset($_POST['telegramId']) ? intval($_POST['telegramId']) : null,
"telegramNotify" => isset($_POST['telegramNotify']) && $_POST['telegramNotify']=="Yes" ? "Yes" : "No",
"telegramChangelog" => isset($_POST['telegramChangelog']) && $_POST['telegramChangelog']=="Yes" ? "Yes" : "No"
);


Expand Down
32 changes: 29 additions & 3 deletions app/admin/users/edit.php
Expand Up @@ -266,11 +266,37 @@
</td>
<td class="info2"><?php print _('Select yes to receive notification change mail for changelog'); ?></td>
</tr>
</tbody>




<!-- Telegram User Id -->
<tr>
<td><?php print _('Telegram User Id'); ?></td>
<td><input type="text" class="form-control input-sm" name="telegramId" value="<?php print isset($user['telegramId']) ? $user['telegramId'] : ''; ?>"></td>
<td class="info2"><?php print _('Enter telegram User Id'); ?></td>
</tr>

<tr>
<td><?php print _('Telegram State changes'); ?></td>
<td>
<select name="telegramNotify" class="form-control input-sm input-w-auto">
<option value="No"><?php print _('No'); ?></option>
<option value="Yes" <?php if (isset($user['telegramNotify']) && $user['telegramNotify'] == "Yes") print "selected='selected'"; ?>><?php print _('Yes'); ?></option>
</select>
</td>
<td class="info2"><?php print _('Select yes to receive notification change telegram for State change'); ?></td>
</tr>

<tr>
<td><?php print _('Telegram Changelog'); ?></td>
<td>
<select name="telegramChangelog" class="form-control input-sm input-w-auto">
<option value="No"><?php print _('No'); ?></option>
<option value="Yes" <?php if (isset($user['telegramChangelog']) && $user['telegramChangelog'] == "Yes") print "selected='selected'"; ?>><?php print _('Yes'); ?></option>
</select>
</td>
<td class="info2"><?php print _('Select yes to receive notification change telegram for changelog'); ?></td>
</tr>
</tbody>

<!-- groups -->
<?php
Expand Down
3 changes: 2 additions & 1 deletion app/admin/users/print-user/index.php
Expand Up @@ -34,7 +34,8 @@
"modules" => "Module permissions",
"authentication" => "Authentication",
"display" => "Display settings",
"mail" => "Mail settings"
"mail" => "Mail settings",
"telegram" => "Telegram settings"
];

// default tab
Expand Down
15 changes: 15 additions & 0 deletions app/admin/users/print-user/telegram.php
@@ -0,0 +1,15 @@
<tr>
<td colspan="2"><h4><?php print _('Telegram settings'); ?></h4><hr></td>
</tr>
<tr>
<td><?php print _('Telegram user id'); ?></td>
<td><?php if ($user->telegramId) { ?><a href="tg://user?id=<?php print $user->telegramId; ?>"><?php print $user->telegramId; ?></a><?php } else { print _("No"); } ?></td>
</tr>
<tr>
<td><?php print _('Telegram notifications'); ?></td>
<td><?php print $user->role == "Administrator" ? _($user->telegramNotify) : _("No"); ?></td>
</tr>
<tr>
<td><?php print _('Changelog Telegram notifications'); ?></td>
<td><?php print $user->role == "Administrator" ? _($user->telegramChangelog) : _("No"); ?></td>
</tr>
1 change: 1 addition & 0 deletions app/subnets/addresses/address-modify-submit.php
Expand Up @@ -279,6 +279,7 @@
$Log->user = $User->user;

$Log->changelog_send_mail ("Address range $address[start] - $address[stop] $action");
$Log->changelog_send_telegram ("Address range $address[start] - $address[stop] $action");
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions app/tools/user-menu/account.php
Expand Up @@ -140,6 +140,39 @@
<?php } ?>
</tr>

<!-- Telegram User Id -->
<tr>
<td><?php print _('Telegram User Id'); ?></td>
<td><input type="text" class="form-control input-sm" name="telegramId" value="<?php property_exists($User->user, 'telegramId') ? print $User->user->telegramId : ''; ?>"></td>
<td class="info2"><?php print _('Enter telegram User Id'); ?></td>
</tr>

<tr>
<td><?php print _('Telegram notifications'); ?></td>
<td>
<select name="telegramNotify" class="form-control input-sm input-w-auto">
<option value="No"><?php print _('No'); ?></option>
<option value="Yes" <?php if (property_exists($User->user, 'telegramNotify') && $User->user->telegramNotify == "Yes") print "selected='selected'"; ?>><?php print _('Yes'); ?></option>
</select>
</td>
<?php if($User->user->role=="Administrator") { ?>
<td class="info2"><?php print _('Select yes to receive telegram notification changes (IP state change, new hosts, requests)'); ?></td>
<?php } else { ?>
<td class="info2"><?php print _('Select yes to receive telegram notifications for IP requests'); ?></td>
<?php } ?>
</tr>

<tr>
<td><?php print _('Telegram Changelog'); ?></td>
<td>
<select name="telegramChangelog" class="form-control input-sm input-w-auto">
<option value="No"><?php print _('No'); ?></option>
<option value="Yes" <?php if (property_exists($User->user, 'telegramChangelog') && $User->user->telegramChangelog == "Yes") print "selected='selected'"; ?>><?php print _('Yes'); ?></option>
</select>
</td>
<td class="info2"><?php print _('Select yes to receive notification change telegram for changelog'); ?></td>
</tr>


<!-- display settings -->
<tr>
Expand Down
4 changes: 4 additions & 0 deletions db/SCHEMA.sql
Expand Up @@ -222,6 +222,7 @@ CREATE TABLE `settings` (
`2fa_name` VARCHAR(32) NULL DEFAULT 'phpipam',
`2fa_length` INT(2) NULL DEFAULT '16',
`2fa_userchange` BOOL NOT NULL DEFAULT '1',
`telegramBotCode` VARCHAR(128) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/* insert default values */
Expand Down Expand Up @@ -395,6 +396,9 @@ CREATE TABLE `users` (
`token_valid_until` DATETIME NULL,
`module_permissions` varchar(255) COLLATE utf8_bin DEFAULT '{"vlan":"1","l2dom":"1","vrf":"1","pdns":"1","circuits":"1","racks":"1","nat":"1","pstn":"1","customers":"1","locations":"1","devices":"1"}',
`compress_actions` TINYINT(1) NULL DEFAULT '1',
`telegramId` BIGINT(20) UNSIGNED DEFAULT NULL,
`telegramNotify` SET('Yes','No') NULL DEFAULT 'No',
`telegramChangelog` SET('Yes','No') NULL DEFAULT 'No',
PRIMARY KEY (`username`),
UNIQUE KEY `id_2` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
Expand Down
61 changes: 40 additions & 21 deletions functions/classes/class.Addresses.php
Expand Up @@ -26,14 +26,14 @@ class Addresses extends Common_functions {
public $address_types = array();

/**
* Mail changelog or not
* Send changelog by email/telegram or not
*
* (default value: true)
*
* @var bool
* @access public
*/
public $mail_changelog = true;
public $send_changelog = true;

/**
* Last insert id
Expand Down Expand Up @@ -335,12 +335,12 @@ public function search_similar_addresses ($address, $linked_field, $value) {
*
* @access public
* @param mixed $address
* @param bool $mail_changelog (default: true)
* @param bool $send_changelog (default: true)
* @return void
*/
public function modify_address ($address, $mail_changelog = true) {
public function modify_address ($address, $send_changelog = true) {
# save changelog
$this->mail_changelog = $mail_changelog;
$this->send_changelog = $send_changelog;
# null empty values
$address = $this->reformat_empty_array_fields ($address, null);
# strip tags
Expand Down Expand Up @@ -418,7 +418,7 @@ protected function modify_address_add ($address) {
# log and changelog
$address['id'] = $this->lastId;
$this->Log->write( "Address created", "New address created<hr>".$this->array_to_log($this->reformat_empty_array_fields ($address, "NULL")), 0);
$this->Log->write_changelog('ip_addr', "add", 'success', array(), $address, $this->mail_changelog);
$this->Log->write_changelog('ip_addr', "add", 'success', array(), $address, $this->send_changelog);

# edit DNS PTR record
$this->ptr_modify ("add", $address);
Expand Down Expand Up @@ -474,7 +474,7 @@ protected function modify_address_edit ($address) {

# log and changelog
$this->Log->write( "Address updated", "Address $address[ip_addr] updated<hr>".$this->array_to_log($this->reformat_empty_array_fields ($address, "NULL")), 0);
$this->Log->write_changelog('ip_addr', "edit", 'success', (array) $address_old, $address, $this->mail_changelog);
$this->Log->write_changelog('ip_addr', "edit", 'success', (array) $address_old, $address, $this->send_changelog);

# edit DNS PTR record
$this->ptr_modify ("edit", $address);
Expand Down Expand Up @@ -513,7 +513,7 @@ protected function modify_address_delete ($address) {

# log and changelog
$this->Log->write( "Address deleted", "Address $address[ip_addr] deleted<hr>".$this->array_to_log((array) $address_old), 0);
$this->Log->write_changelog('ip_addr', "delete", 'success', (array) $address_old, array(), $this->mail_changelog);
$this->Log->write_changelog('ip_addr', "delete", 'success', (array) $address_old, array(), $this->send_changelog);

# edit DNS PTR record
$this->ptr_modify ("delete", $address);
Expand Down Expand Up @@ -619,7 +619,7 @@ public function update_address_hostname ($ip, $id, $hostname = "") {
}
// save log
$this->Log->write( "Address DNS resolved", "Address $ip resolved<hr>".$this->array_to_log((array) $hostname), 0);
$this->Log->write_changelog('ip_addr', "edit", 'success', array ("id"=>$id, "hostname"=>""), array("id"=>$id, "hostname"=>$hostname), $this->mail_changelog);
$this->Log->write_changelog('ip_addr', "edit", 'success', array ("id"=>$id, "hostname"=>""), array("id"=>$id, "hostname"=>$hostname), $this->send_changelog);
}
}

Expand All @@ -634,6 +634,7 @@ private function threshold_check ($address) {
$address = (object) $address;
$content = array();
$content_plain = array();
$content_telegram = array();

# fetch settings
$this->get_settings ();
Expand All @@ -652,29 +653,47 @@ private function threshold_check ($address) {
$admins = $Tools->fetch_multiple_objects ("users", "role", "Administrator");
// if some recipients
if ($admins !== false) {
# try to send
try {
// mail settings
$mail_settings = $Tools->fetch_object ("settingsMail", "id", 1);
// mail class
$phpipam_mail = new phpipam_mail ($this->settings, $mail_settings);

// set parameters

// set parameters
$subject = "Subnet threshold limit reached"." (".$this->transform_address($subnet->subnet,"dotted")."/".$subnet->mask.")";
$content[] = "<table style='margin-left:10px;margin-top:5px;width:auto;padding:0px;border-collapse:collapse;'>";
$content[] = "<tr><td style='padding:5px;margin:0px;color:#333;font-size:16px;text-shadow:1px 1px 1px white;border-bottom:1px solid #eeeeee;' colspan='2'>$this->mail_font_style<strong>$subject</font></td></tr>";
$content[] = '<tr><td style="padding: 0px;padding-left:10px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''._('Subnet').'</a></font></td> <td style="padding: 0px;padding-left:15px;margin:0px;line-height:18px;text-align:left;padding-top:10px;"><a href="'.$this->createURL().''.create_link("subnets",$subnet->sectionId, $subnet->id).'">'.$this->mail_font_style_href . $this->transform_address($subnet->subnet,"dotted")."/".$subnet->mask .'</font></a></td></tr>';
$content[] = '<tr><td style="padding: 0px;padding-left:10px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''._('Description').'</font></td> <td style="padding: 0px;padding-left:15px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''. $subnet->description .'</font></td></tr>';
$content[] = '<tr><td style="padding: 0px;padding-left:10px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''._('Subnet').'</font></td> <td style="padding: 0px;padding-left:15px;margin:0px;line-height:18px;text-align:left;padding-top:10px;"><a href="'.$this->createURL().create_link("subnets",$subnet->sectionId, $subnet->id).'">'.$this->mail_font_style_href . $this->transform_address($subnet->subnet,"dotted")."/".$subnet->mask .'</font></a></td></tr>';
if ($subnet->description) {
$content[] = '<tr><td style="padding: 0px;padding-left:10px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''._('Description').'</font></td> <td style="padding: 0px;padding-left:15px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''. $subnet->description .'</font></td></tr>';
}
$content[] = '<tr><td style="padding: 0px;padding-left:10px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''._('Usage').' (%)</font></td> <td style="padding: 0px;padding-left:15px;margin:0px;line-height:18px;text-align:left;">'.$this->mail_font_style.''. gmp_strval(gmp_sub(100,(int) round($subnet_usage['freehosts_percent'], 0))) .'</font></td></tr>';
$content[] = "</table>";
// plain
$content_plain[] = "$subject"."\r\n------------------------------\r\n";
$content_plain[] = _("Subnet").": ".$this->transform_address($subnet->subnet,"dotted")."/".$subnet->mask;
$content_plain[] = _("Usage")." (%) : ".gmp_strval(gmp_sub(100,(int) round($subnet_usage['freehosts_percent'], 0)));

$content_telegram[] = "*{$subject}*\r\n";
$content_telegram[] = _('Subnet')." [{$this->transform_address($subnet->subnet,"dotted")}/{$subnet->mask}](".$this->createURL().create_link("subnets",$subnet->sectionId, $subnet->id).")";
if ($subnet->description) {
$content_telegram[] = _('Description')." {$subnet->description}";
}
$content_telegram[] = _('Usage')." ".gmp_strval(gmp_sub(100,(int) round($subnet_usage['freehosts_percent'], 0)))."%";

$recipients = $this->changelog_telegram_get_recipients ($subnet->id);
if ($recipients!==false) {
$content_telegram = implode("\r\n",$content_telegram);
foreach($recipients as $a) {
$this->sendTelegramMessage($a->telegramId, $content_telegram);
}
}

# try to send
try {
// mail settings
$mail_settings = $Tools->fetch_object ("settingsMail", "id", 1);
// mail class
$phpipam_mail = new phpipam_mail ($this->settings, $mail_settings);

# set content
$content = $phpipam_mail->generate_message (implode("\r\n", $content));
$content_plain = implode("\r\n",$content_plain);
$content = $phpipam_mail->generate_message (implode("\r\n", $content));
$content_plain = implode("\r\n",$content_plain);

$phpipam_mail->Php_mailer->setFrom($mail_settings->mAdminMail, $mail_settings->mAdminName);
//add all admins to CC
Expand Down
71 changes: 71 additions & 0 deletions functions/classes/class.Common.php
Expand Up @@ -394,6 +394,44 @@ public function changelog_mail_get_recipients ($subnetId = false) {
}
}

/**
* Get all admins that are set to receive changelog by Telegram
*
* @access public
* @param bool|mixed $subnetId
* @return bool|array
*/
public function changelog_telegram_get_recipients ($subnetId = false) {
// fetch all users with telegramNotify
$notification_users = $this->fetch_multiple_objects ("users", "telegramChangelog", "Yes", "id", true);
// recipients array
$recipients = array();
// any ?
if (is_array($notification_users)) {
if(sizeof($notification_users)>0) {
foreach ($notification_users as $u) {
if ($u->telegramId) {
// if subnetId is set check who has permissions
if (isset($subnetId)) {
// inti object
$Subnets = new Subnets ($this->Database);
//check permissions
$subnet_permission = $Subnets->check_permission($u, $subnetId);
// if 3 than add
if ($subnet_permission==3) {
$recipients[] = $u;
}
} elseif($u->role=="Administrator") {
$recipients[] = $u;
}
}
}
}
}

return sizeof($recipients)>0 ? $recipients : false;
}




Expand Down Expand Up @@ -2104,4 +2142,37 @@ private function print_actions_buttons ($items = []) {
// result
return implode("\n", $html);
}

/**
* Send Telegram message
*
* @method sendTelegramMessage
* @param int $telegramUserId
* @param string $text
* @return bool
*/
public function sendTelegramMessage($telegramUserId, $text)
{
$this->get_settings();

if ($this->settings->telegramBotCode) {
try {
file_get_contents(
"https://api.telegram.org/bot{$this->settings->telegramBotCode}/sendMessage",
false,
stream_context_create(
array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL,
'content' => http_build_query(array('chat_id' => $telegramUserId, 'text' => $text, 'parse_mode' => 'Markdown'))
)
)
)
);
} catch(Exception $e) { /** do nothing, maybe user stop the bot **/ }
}

return true;
}
}