|
|
@@ -1,9 +1,7 @@
|
|
|
#!/usr/bin/perl
|
|
|
|
|
|
-# Бот и рассыльщик сообщений для Телеграм
|
|
|
-# Ю. Жиловец, 6 ноября 2016 года
|
|
|
-# 311683401 - это я
|
|
|
-# -166458164 - чат MOL Prog
|
|
|
+# Бот-исполнитель запросов техподдержки
|
|
|
+# Ю. Жиловец, 11 января 2023 года
|
|
|
|
|
|
use Modern::Perl;
|
|
|
use utf8;
|
|
|
@@ -18,7 +16,7 @@ use Mojo::JSON qw/j/;
|
|
|
use NetAddr::IP;
|
|
|
use HTML::Restrict;
|
|
|
|
|
|
-my $NAME = "telegram";
|
|
|
+my $NAME = "djinn";
|
|
|
my $confdir = "config/".app->mode;
|
|
|
|
|
|
use FindBin qw/$Bin/;
|
|
|
@@ -33,8 +31,6 @@ plugin yaml_config => {
|
|
|
|
|
|
our $config = app->config;
|
|
|
|
|
|
-$config->{_alert_allowed} = [ grep {$_} map {new NetAddr::IP($_)} @{$config->{alert_allowed}} ];
|
|
|
-
|
|
|
app->secrets(["Marsz, Marsz, Dabrowski"]);
|
|
|
|
|
|
my $log = new Mojo::Log;
|
|
|
@@ -59,22 +55,11 @@ my $term;
|
|
|
my $int;
|
|
|
my $hup;
|
|
|
|
|
|
-my $rabbit;
|
|
|
Mojo::IOLoop->next_tick(sub
|
|
|
{
|
|
|
$term = AnyEvent->signal(signal => "TERM", cb => \&terminate);
|
|
|
$int = AnyEvent->signal(signal => "INT", cb => \&terminate);
|
|
|
$hup = AnyEvent->signal(signal => "HUP", cb => \&terminate);
|
|
|
-
|
|
|
- $config->{rabbit}->{on_error} = sub { $log->error("[rabbit]".@_); terminate() };
|
|
|
-
|
|
|
- my $rabbit_args = $config->{rabbit};
|
|
|
- $rabbit_args->{product} = $NAME;
|
|
|
-
|
|
|
- $rabbit = new rabbit_async_rec($rabbit_args, sub
|
|
|
- {
|
|
|
- $rabbit->listen_queue($config->{queue}, $config->{bind}, \&incoming_message);
|
|
|
- });
|
|
|
});
|
|
|
|
|
|
##########################
|
|
|
@@ -84,7 +69,7 @@ $ua->max_redirects(5);
|
|
|
|
|
|
##########################
|
|
|
|
|
|
-=cut
|
|
|
+#=cut
|
|
|
hook before_dispatch => sub
|
|
|
{
|
|
|
my $c = shift;
|
|
|
@@ -96,65 +81,13 @@ hook after_dispatch => sub
|
|
|
my $c = shift;
|
|
|
say $c->res->to_string;
|
|
|
};
|
|
|
-=cut
|
|
|
+#=cut
|
|
|
|
|
|
##########################
|
|
|
|
|
|
get "/health" => sub
|
|
|
{
|
|
|
- shift->render(text => "Telegram OK");
|
|
|
-};
|
|
|
-
|
|
|
-sub check_ip
|
|
|
-{
|
|
|
- my $c = shift;
|
|
|
- my $remip = new NetAddr::IP($c->tx->remote_address);
|
|
|
-
|
|
|
- for (@{$config->{_alert_allowed}})
|
|
|
- {
|
|
|
- return 1 if $_->contains($remip);
|
|
|
- }
|
|
|
-
|
|
|
- $c->render(status => 403, text => "Неизвестный IP-адрес " . $c->tx->remote_address);
|
|
|
- return undef;
|
|
|
-}
|
|
|
-
|
|
|
-post "/alert" => sub
|
|
|
-{
|
|
|
- my $c = shift;
|
|
|
- return unless check_ip($c);
|
|
|
-
|
|
|
- my $channel = $c->param("to");
|
|
|
- my $params = j($c->req->body);
|
|
|
-
|
|
|
- for my $alert (@{$params->{alerts}})
|
|
|
- {
|
|
|
- my $icon = "\x{2753}";
|
|
|
- if ($alert->{status} eq "resolved")
|
|
|
- {
|
|
|
- $icon = "\x{1F197}";
|
|
|
- }
|
|
|
- elsif ($alert->{labels}->{severity} && $alert->{labels}->{severity} eq "critical")
|
|
|
- {
|
|
|
- $icon = "\x{1F534}";
|
|
|
- }
|
|
|
- elsif ($alert->{labels}->{severity} && $alert->{labels}->{severity} eq "warning")
|
|
|
- {
|
|
|
- $icon = "\x{26A0}";
|
|
|
- }
|
|
|
-
|
|
|
- my $message .= "$icon <code> [" . ($alert->{labels}->{server}||$alert->{labels}->{location}||"") . "] " . $alert->{labels}->{alertname} . " " .$alert->{labels}->{job}
|
|
|
- . " " . $alert->{labels}->{instance} . "</code>\n";
|
|
|
- $message .= $alert->{annotations}->{summary} . "\n" . "<i>" . $alert->{annotations}->{description} . "</i>";
|
|
|
-
|
|
|
- my $rest = {};
|
|
|
-
|
|
|
- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
|
|
- $rest->{silent} = 1 if $hour < 9 || $hour > 23;
|
|
|
- notify($channel, $message, $rest);
|
|
|
- }
|
|
|
-
|
|
|
- $c->render(text=>"ok");
|
|
|
+ shift->render(text => "Djinn OK");
|
|
|
};
|
|
|
|
|
|
post "/:token" => sub
|
|
|
@@ -179,130 +112,7 @@ post "/:token" => sub
|
|
|
do_command($cmd, $chatid, {msgid=>$msgid, from=>$from});
|
|
|
};
|
|
|
|
|
|
-sub incoming_message
|
|
|
-{
|
|
|
- my $m = shift;
|
|
|
- my $body = $m->{content};
|
|
|
- $log->debug($m->{routing_key}." ".Dumper($m->{content})) if $config->{debug};
|
|
|
-
|
|
|
- my $rk = $m->{routing_key};
|
|
|
- $rk =~ s/\./::/g;
|
|
|
- my $sub = reference($rk);
|
|
|
-
|
|
|
- unless ($sub)
|
|
|
- {
|
|
|
- $log->error("Unknown message: ".$rk);
|
|
|
- $rabbit->reply($m, "Unknown message") if $m->{header}->{reply_to};
|
|
|
- $rabbit->reject($m);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- my $res;
|
|
|
- eval {
|
|
|
- $res = $sub->($body,$m);
|
|
|
- };
|
|
|
-
|
|
|
- if (ref $res eq "Promises::Promise")
|
|
|
- {
|
|
|
- $res->then(sub
|
|
|
- {
|
|
|
- my $result = shift;
|
|
|
- handle_reply($m, undef, $result);
|
|
|
- })
|
|
|
- ->catch(sub
|
|
|
- {
|
|
|
- my $err = shift;
|
|
|
- handle_reply($m, $err, undef);
|
|
|
- })
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- handle_reply($m, $@, $res);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-sub handle_reply
|
|
|
-{
|
|
|
- my $m = shift;
|
|
|
- my $err = shift;
|
|
|
- my $res = shift;
|
|
|
-
|
|
|
- if ($err)
|
|
|
- {
|
|
|
- $log->error(Dumper $@);
|
|
|
- $rabbit->reply($m, $@) if $m->{header}->{reply_to};
|
|
|
- $rabbit->reject($m);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- $rabbit->ack($m);
|
|
|
- $rabbit->reply($m, $res) if $m->{header}->{reply_to};
|
|
|
- $log->debug("acknowledged") if $config->{debug};
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-sub notify::telegram::send
|
|
|
-{
|
|
|
- my $body = shift;
|
|
|
- my $to = $body->{to};
|
|
|
- $to = [ $to ] unless ref($to) eq "ARRAY";
|
|
|
- $body->{disable_error_handler} = 1;
|
|
|
-
|
|
|
- my @results;
|
|
|
-
|
|
|
- my @promises = map {
|
|
|
- notify($_, $body->{message}, $body)->then(sub
|
|
|
- {
|
|
|
- my $reply = shift;
|
|
|
- push @results, { success=>1, msgid=>$reply->{result}->{message_id}, chat=>$reply->{result}->{chat}->{id} };
|
|
|
- })
|
|
|
- ->catch(sub
|
|
|
- {
|
|
|
- my $reply = shift;
|
|
|
- push @results, {success=>0, error => ref($reply) ? "$reply->{code}: $reply->{body}->{description}" : $reply};
|
|
|
- })
|
|
|
- } @$to;
|
|
|
-
|
|
|
- return collect(@promises)->then(sub
|
|
|
- {
|
|
|
- return \@results;
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-sub notify::telegram::delete
|
|
|
-{
|
|
|
- my $body = shift;
|
|
|
- my $chat = $body->{chat};
|
|
|
- my $msg = $body->{msgid};
|
|
|
-
|
|
|
- return request("deleteMessage", {chat_id => $chat, message_id => $msg});
|
|
|
-}
|
|
|
-
|
|
|
-sub notify::telegram::update
|
|
|
-{
|
|
|
- my $body = shift;
|
|
|
- my $chat = $body->{chat};
|
|
|
- my $msg = $body->{msgid};
|
|
|
- my $message = $body->{message};
|
|
|
-
|
|
|
- my $params = {
|
|
|
- chat_id => $chat,
|
|
|
- message_id => $msg,
|
|
|
- text => $message,
|
|
|
- disable_web_page_preview => 1,
|
|
|
- };
|
|
|
-
|
|
|
- $params->{parse_mode} ||= "HTML";
|
|
|
-
|
|
|
- if ($params->{parse_mode} eq "HTML")
|
|
|
- {
|
|
|
- $params->{text} = $html_strip->process($params->{text});
|
|
|
- }
|
|
|
-
|
|
|
- return request("editMessageText", $params);
|
|
|
-}
|
|
|
-
|
|
|
-############################
|
|
|
+##################################
|
|
|
|
|
|
sub command::help
|
|
|
{
|
|
|
@@ -311,17 +121,17 @@ sub command::help
|
|
|
my $chatid = shift;
|
|
|
my $rest = shift;
|
|
|
|
|
|
- notify($chatid,"*/my_id* Узнать свой идентификатор в Телеграме", $rest);
|
|
|
+ notify($chatid,"*/purge-tree* Очистить дерево PON", $rest);
|
|
|
}
|
|
|
|
|
|
-sub command::my_id
|
|
|
+sub command::purge_tree
|
|
|
{
|
|
|
my $cmd = shift;
|
|
|
my $args = shift;
|
|
|
my $chatid = shift;
|
|
|
my $rest = shift;
|
|
|
|
|
|
- notify($chatid,"Ваш идентификатор в Телеграме: *$chatid*", $rest);
|
|
|
+ notify($chatid,"Команда purge-tree: ".Dumper($args, $chatid, $rest), $rest);
|
|
|
}
|
|
|
|
|
|
sub command::start
|
|
|
@@ -334,7 +144,6 @@ sub command::start
|
|
|
notify($chatid, "$config->{title}.\nДля получения списка команд наберите */help*");
|
|
|
}
|
|
|
|
|
|
-
|
|
|
############################
|
|
|
|
|
|
sub do_command
|
|
|
@@ -366,7 +175,7 @@ sub do_command
|
|
|
|
|
|
sub terminate
|
|
|
{
|
|
|
- request("setWebhook",{url=>""})->then(sub
|
|
|
+ request("setWebhook", {url=>""})->then(sub
|
|
|
{
|
|
|
exit(0);
|
|
|
})->catch(sub
|
|
|
@@ -462,7 +271,7 @@ $log->info("Started (".app->mode.")");
|
|
|
request("setWebhook",{url=>""})->then(sub
|
|
|
{
|
|
|
$log->info("Webhook to $config->{webhook}");
|
|
|
- return request("setWebhook",{url=>"$config->{webhook}/$config->{token}"});
|
|
|
+ return request("setWebhook", {url=>"$config->{webhook}/$config->{token}"});
|
|
|
})->catch(sub
|
|
|
{
|
|
|
$log->error(Dumper @_);
|