centreon-plugins/notification/telegram/mode/alert.pm

277 lines
9.3 KiB
Perl

#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package notification::telegram::mode::alert;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use centreon::plugins::http;
use JSON::XS;
my %telegram_icon_host = (
up => "\x{2705}",
down => "\x{1F525}",
unreachable => "\x{2753}",
);
my %telegram_icon_service = (
ok => "\x{2705}",
warning => "\x{26A0}",
critical => "\x{1F525}",
unknown => "\x{2753}",
);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
"hostname:s" => { name => 'hostname', default => 'api.telegram.org' },
"port:s" => { name => 'port', default => 443 },
"proto:s" => { name => 'proto', default => 'https' },
"urlpath:s" => { name => 'url_path', default => "/sendMessage" },
"chat-id:s" => { name => 'chat_id' },
"bot-token:s" => { name => 'bot_token' },
"host-name:s" => { name => 'host_name' },
"host-state:s" => { name => 'host_state' },
"host-output:s" => { name => 'host_output' },
"service-description:s" => { name => 'service_description' },
"service-state:s" => { name => 'service_state' },
"service-output:s" => { name => 'service_output' },
"graph-url:s" => { name => 'graph_url' },
"link-url:s" => { name => 'link_url' },
"centreon-url:s" => { name => 'centreon_url' },
"centreon-token:s" => { name => 'centreon_token' },
"timeout:s" => { name => 'timeout' },
});
$self->{http} = centreon::plugins::http->new(%options);
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (!defined($self->{option_results}->{chat_id})) {
$self->{output}->add_option_msg(short_msg => "You need to set --chat-id option");
$self->{output}->option_exit();
}
if (!defined($self->{option_results}->{bot_token})) {
$self->{output}->add_option_msg(short_msg => "You need to set --bot-token option");
$self->{output}->option_exit();
}
if (!defined($self->{option_results}->{host_name}) || $self->{option_results}->{host_name} eq '') {
$self->{output}->add_option_msg(short_msg => "You need to specify --host-name option.");
$self->{output}->option_exit();
}
foreach (('graph_url', 'link_url')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{option_results}->{$1}/g;
eval "\$self->{option_results}->{\$_} = \"$self->{option_results}->{$_}\"";
}
}
$self->{http}->set_options(%{$self->{option_results}});
}
sub host_message {
my ($self, %options) = @_;
if (defined($self->{option_results}->{host_state}) && $self->{option_results}->{host_state} ne '') {
if (defined($telegram_icon_host{lc($self->{option_results}->{host_state})})) {
$self->{message} = $telegram_icon_host{lc($self->{option_results}->{host_state})};
}
}
$self->{message} .= " Host <i>" . $self->{option_results}->{host_name} . "</i>";
if (defined($self->{option_results}->{host_state}) && $self->{option_results}->{host_state} ne '') {
$self->{message} .= ' is <b>' . $self->{option_results}->{host_state} . '</b>';
} else {
$self->{message} .= ' alert';
}
if (defined($self->{option_results}->{host_output}) && $self->{option_results}->{host_output} ne '') {
$self->{message} .= "\n " . $self->{option_results}->{host_output};
}
if (defined($self->{option_results}->{link_url}) && $self->{option_results}->{link_url} ne '') {
$self->{message} .= "\n <a href=\"" . $self->{option_results}->{link_url} . "\">Link</a>";
}
}
sub service_message {
my ($self, %options) = @_;
if (defined($self->{option_results}->{service_state}) && $self->{option_results}->{service_state} ne '') {
if (defined($telegram_icon_service{lc($self->{option_results}->{service_state})})) {
$self->{message} = $telegram_icon_service{lc($self->{option_results}->{service_state})};
}
}
$self->{message} .= " Host <i>" . $self->{option_results}->{host_name} . " | Service " . $self->{option_results}->{service_description} . "</i>";
if (defined($self->{option_results}->{service_state}) && $self->{option_results}->{service_state} ne '') {
$self->{message} .= ' is <b>' . $self->{option_results}->{service_state} . '</b>';
} else {
$self->{message} .= ' alert';
}
if (defined($self->{option_results}->{service_output}) && $self->{option_results}->{service_output} ne '') {
$self->{message} .= "\n ". $self->{option_results}->{service_output};
}
if (defined($self->{option_results}->{link_url}) && $self->{option_results}->{link_url} ne '') {
$self->{message} .= "\n <a href=\"" . $self->{option_results}->{link_url} . "\">Link</a>";
}
if (defined($self->{option_results}->{graph_url}) && $self->{option_results}->{graph_url} ne '') {
$self->{message} .= "\n <a href=\"" . $self->{option_results}->{graph_url} . "\">Graph</a>";
}
}
sub set_payload {
my ($self, %options) = @_;
if (defined($self->{option_results}->{service_description}) && $self->{option_results}->{service_description} ne '') {
$self->service_message();
} else {
$self->host_message();
}
}
sub format_payload {
my ($self, %options) = @_;
my $json = JSON::XS->new->utf8;
my $payload = { chat_id =>$self->{option_results}->{chat_id},
parse_mode => 'HTML',
text => $self->{message} };
eval {
$self->{payload_str} = $json->encode($payload);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot encode json request");
$self->{output}->option_exit();
}
}
sub run {
my ($self, %options) = @_;
$self->{http}->add_header(key => 'Content-Type', value => 'application/json');
$self->{http}->add_header(key => 'Accept', value => 'application/json');
$self->set_payload();
$self->format_payload();
my $url_path = '/bot' . $self->{option_results}->{bot_token} . $self->{option_results}->{url_path};
my $response = $self->{http}->request(url_path => $url_path,
method => 'POST', query_form_post => $self->{payload_str});
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($response);
};
if ($@) {
$self->{output}->output_add(long_msg => $response, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
if (!defined($decoded->{result}->{message_id})) {
$self->{output}->output_add(long_msg => $decoded, debug => 1);
$self->{output}->add_option_msg(short_msg => "Error sending message");
$self->{output}->option_exit();
}
$self->{output}->output_add(short_msg => 'Message ID : ' . $decoded->{result}->{message_id});
$self->{output}->display(force_ignore_perfdata => 1);
$self->{output}->exit();
}
1;
__END__
=head1 MODE
Send message with Telegram API.
=over 6
=item B<--chat-id>
Telegram Chat ID (Negative Integer for Group)
Use Telegram CLI for getting Chat ID
=item B<--bot-token>
Telegram Bot Token (Check Telegram Doc for Creating Bot)
https://core.telegram.org/bots#3-how-do-i-create-a-bot
=item B<--host-state>
Specify host server state for the alert.
=item B<--host-output>
Specify host server output message for the alert.
=item B<--host-name>
Specify host server name for the alert (Required).
=item B<--service-description>
Specify service description name for the alert.
=item B<--service-state>
Specify service state for the alert.
=item B<--service-output>
Specify service output message for the alert.
=item B<--centreon-url>
Specify the centreon url macro (could be used in link-url and graph-url option).
=item B<--centreon-token>
Specify the centreon token for autologin macro (could be used in link-url and graph-url option).
=item B<--graph-url>
Specify the graph url (Example: %{centreon_url}/include/views/graphs/generateGraphs/generateImage.php?username=myuser&token=%{centreon_token}&hostname=%{host_name}&service=%{service_description}).
=item B<--link-url>
Specify the link url (Example: %{centreon_url}/main.php?p=20201&o=svc&host_search=%{host_name}&svc_search=%{service_description})
=item B<--timeout>
Threshold for HTTP timeout.
=back
=cut