Move !ping to redis rails
This commit is contained in:
@@ -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
|
||||||
11
README.md
11
README.md
@@ -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:
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
После установки этих пакетов, можно будет запустить:
|
После установки этих пакетов, можно будет запустить:
|
||||||
|
|
||||||
|
|||||||
3
cpanfile
3
cpanfile
@@ -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';
|
||||||
|
|||||||
@@ -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') {
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user