Move !ping to redis rails

This commit is contained in:
eleksir
2021-12-19 14:42:23 +03:00
parent e74a3e46c1
commit 1d287f853f
7 changed files with 85 additions and 40 deletions

View File

@@ -92,3 +92,7 @@ lib_sections = NAME | VERSION | DESCRIPTION | AUTHOR | LICENSE AND COPYRIGHT
[-ControlStructures::ProhibitDeepNests] [-ControlStructures::ProhibitDeepNests]
# Have to use it, so fuckoff # Have to use it, so fuckoff
[-ControlStructures::ProhibitUntilBlocks]
# Until is really useful if condition is simple, so let's assume condition is
# always simple to read

View File

@@ -13,17 +13,18 @@ mature enough, maybe I release it separately.
Bot config located in **data/config.json**, sample config provided as Bot config located in **data/config.json**, sample config provided as
**data/sample_config.json**. **data/sample_config.json**.
Bot can be run via **bin/aleesa-telegram-bot** and acts as daemon (double fork() Bot can be run via **bin/aleesa-telegram-bot** and acts as daemon (double
and detaches stdio). fork() and detaches stdio).
## Installation ## Installation
In order to run this application, you need to "bootstrap" it - download and build In order to run this application, you need to "bootstrap" it - download and
all required dependencies and libraries. build all required dependencies and libraries.
You'll need perl-5.18 or newer, "Development Tools" or similar group of You'll need perl-5.18 or newer, "Development Tools" or similar group of
packages, perl, perl-devel, perl-local-lib, perl-app-cpanm, sqlite-devel, packages, perl, perl-devel, perl-local-lib, perl-app-cpanm, sqlite-devel,
zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make. zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make,
hiredis-devel.
After installing required dependencies it is possible to run: After installing required dependencies it is possible to run:

View File

@@ -24,7 +24,7 @@ metacpan.org
Понадобится perl-5.18, а желательно новее, "Development Tools" или подобная Понадобится perl-5.18, а желательно новее, "Development Tools" или подобная
группа пакетов , perl, perl-devel, perl-local-lib, perl-app-cpanm, sqlite-devel, группа пакетов , perl, perl-devel, perl-local-lib, perl-app-cpanm, sqlite-devel,
zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make. zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make, hiredis-devel.
После установки этих пакетов, можно будет запустить: После установки этих пакетов, можно будет запустить:

View File

@@ -26,9 +26,10 @@ requires 'Log::Any::For::Std';
requires 'Math::Random::Secure'; requires 'Math::Random::Secure';
requires 'Mojo::Base'; requires 'Mojo::Base';
requires 'Mojo::IOLoop'; requires 'Mojo::IOLoop';
requires 'Mojo::Redis' requires 'Mojo::Redis';
requires 'Mojo::UserAgent'; requires 'Mojo::UserAgent';
requires 'Mojo::UserAgent::Cached'; requires 'Mojo::UserAgent::Cached';
requires 'Protocol::Redis::XS';
requires 'String::Random'; requires 'String::Random';
requires 'Text::Fuzzy'; requires 'Text::Fuzzy';
requires 'URI::Encode::XS'; requires 'URI::Encode::XS';

View File

@@ -9,6 +9,8 @@ use open qw (:std :utf8);
use English qw ( -no_match_vars ); use English qw ( -no_match_vars );
use Carp qw (carp); use Carp qw (carp);
use Math::Random::Secure qw (irand); use Math::Random::Secure qw (irand);
use Data::Dumper;
use Log::Any qw ($log);
use BotLib::Conf qw (LoadConf); use BotLib::Conf qw (LoadConf);
use BotLib::Admin qw (@ForbiddenMessageTypes GetForbiddenTypes AddForbiddenType use BotLib::Admin qw (@ForbiddenMessageTypes GetForbiddenTypes AddForbiddenType
@@ -60,11 +62,35 @@ sub Command {
my $msg = shift; my $msg = shift;
my $text = shift; my $text = shift;
my $chatid = shift; my $chatid = shift;
my $reply; my $reply;
my ($userid, $username, $fullname, $highlight, $visavi) = Highlight ($msg); my ($userid, $username, $fullname, $highlight, $visavi) = Highlight ($msg);
my $rmsg->{from} = 'telegram';
$rmsg->{userid} = $userid;
$rmsg->{chatid} = $chatid;
$rmsg->{plugin} = 'telegram';
if ($chatid >= 0) {
$rmsg->{mode} = 'private';
} else {
$rmsg->{mode} = 'public';
}
if (substr ($text, 1) eq 'ping') { if (substr ($text, 1) eq 'ping') {
$reply = 'Pong.'; $rmsg->{message} = $text;
$self->log->debug ('[DEBUG] Sending message to redis ' . Dumper ($rmsg));
until (eval { Mojo::Redis::Connection->is_connected ($main::REDIS); }) {
$log->info ('[INFO] Not yet connected to redis');
sleep 1;
}
my $pubsub = $main::REDIS->pubsub;
$pubsub->json ($c->{'redis_router_channel'})->notify (
$c->{'redis_router_channel'} => $rmsg
);
} elsif (substr ($text, 1) eq 'пинг') { } elsif (substr ($text, 1) eq 'пинг') {
$reply = 'Понг.'; $reply = 'Понг.';
} elsif (substr ($text, 1) eq 'pong') { } elsif (substr ($text, 1) eq 'pong') {

View File

@@ -15,11 +15,24 @@ our @EXPORT_OK = qw (redis_parse_message);
sub redis_parse_message { sub redis_parse_message {
my $self = shift; my $self = shift;
my $m = shift; my $m = shift;
my $answer = $m;
my $send_to = $answer->{from};
$log->error (Dumper $self); $log->error (Dumper $self);
# We cannot send message if we're not connected to telegram
# TODO: Queue messages properly.
until (defined $main::TGM) {
sleep 1;
}
# TODO: add some checks, at least that the bot is not muted in chat
$main::TGM->sendMessage (
{
chat_id => $m->{chatid},
text => $m->{message}
}
);
return; return;
}; };

View File

@@ -13,6 +13,8 @@ use Hailo;
use Log::Any qw ($log); use Log::Any qw ($log);
use Math::Random::Secure qw (irand); use Math::Random::Secure qw (irand);
use Mojo::Base 'Teapot::Bot::Brain'; use Mojo::Base 'Teapot::Bot::Brain';
# Чтобы "уж точно" использовать hiredis-биндинги, загрузим этот модуль перед Mojo::Redis
use Protocol::Redis::XS;
use Mojo::Redis; use Mojo::Redis;
use Mojo::Redis::Connection; use Mojo::Redis::Connection;
use BotLib::Admin qw (FortuneToggleList); use BotLib::Admin qw (FortuneToggleList);
@@ -21,7 +23,7 @@ use BotLib::Conf qw (LoadConf);
use BotLib::Fortune qw (Fortune); use BotLib::Fortune qw (Fortune);
use BotLib::Karma qw (KarmaSet); use BotLib::Karma qw (KarmaSet);
use BotLib::Util qw (trim fmatch); use BotLib::Util qw (trim fmatch);
use RedisLib qw (redisListener); use RedisLib qw (redis_parse_message);
use version; our $VERSION = qw (1.0); use version; our $VERSION = qw (1.0);
use Exporter qw (import); use Exporter qw (import);
@@ -372,13 +374,16 @@ sub __on_msg {
} }
sub __redisListener { sub __redisListener {
$log->error ('Run redis listener');
# If we already connected there is no point to disconnect # If we already connected there is no point to disconnect
if (defined $main::REDIS) { if (defined $main::REDIS) {
my $connected = eval { Mojo::Redis::Connection->is_connected ($main::REDIS); }; my $connected = eval { Mojo::Redis::Connection->is_connected ($main::REDIS); };
if ($connected) { if ($connected) {
$log->notice ('[NOTICE] Redis client already running and connected');
return; return;
} else { } else {
$log->notice ('[NOTICE] Redis client registered, but looks like it is not connected, try to re-connect');
$main::REDIS = undef; $main::REDIS = undef;
} }
} }
@@ -387,45 +392,40 @@ sub __redisListener {
sprintf 'redis://%s:%s/1', $c->{redis_server}, $c->{redis_port} sprintf 'redis://%s:%s/1', $c->{redis_server}, $c->{redis_port}
); );
$log->notice ('[NOTICE] New redis client registered, registering callbacks');
# Don't forget to update global ref to our redis context # Don't forget to update global ref to our redis context
$main::REDIS = $r; $main::REDIS = $r;
$r->on (
error => sub {
my ($conn, $error) = @_;
$log->error ("Redis connection error: $error");
# TODO: maintain list of callbacks and clean them up?
my $redis = Mojo::Redis->new (
sprintf 'redis://%s:%s/1', $c->{redis_server}, $c->{redis_port}
);
# Don't forget to update global ref to our redis context
$main::REDIS = $redis;
return;
}
);
$r->on ( $r->on (
connection => sub { connection => sub {
my ($redis, $connection) = @_; my ($redis, $connection) = @_;
my $pubsub = $redis->pubsub;
my $sub;
foreach my $channel (@{$c->{redis_channels}}) { # Log error
$log->info ("Subscribing to $channel"); $connection->on (
error => sub {
$sub->{$channel} = $pubsub->json ($channel)->listen ( my ($conn, $error) = @_;
$channel => sub { \&redis_parse_message->(@_); } $log->error ("[ERROR] Redis connection error: $error");
); return;
} }
);
return; return;
} }
); );
# Subscribe to channels
my $pubsub = $r->pubsub;
my $sub;
$log->notice ('[NOTICE] Subscribing to redis channels');
foreach my $channel (@{$c->{redis_channels}}) {
$log->info ("[INFO] Subscribing to $channel");
$sub->{$channel} = $pubsub->json ($channel)->listen (
$channel => sub { \&redis_parse_message->(@_); }
);
}
return; return;
} }
@@ -445,8 +445,8 @@ sub init {
} }
$self->add_listener (\&__on_msg); $self->add_listener (\&__on_msg);
$self->add_listener (\&__redisListener);
$self->add_repeating_task (900, \&__cron); $self->add_repeating_task (900, \&__cron);
__redisListener ();
return; return;
} }