First karma working achieved.
This commit is contained in:
parent
1cc0432e97
commit
06f832d8eb
@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Data::Dumper;
|
||||
use JSON;
|
||||
|
||||
use DoctorKarma::Config;
|
||||
use DoctorKarma::Telegram;
|
||||
use DoctorKarma::Logger;
|
||||
|
||||
my $config = DoctorKarma::Config->new;
|
||||
my $logger = DoctorKarma::Logger->new;
|
||||
my $telegram =
|
||||
DoctorKarma::Telegram->new( telegram_token => $config->telegram_token );
|
||||
while (1) {
|
||||
my $updates = $telegram->get_updates;
|
||||
for my $update ($updates->@*) {
|
||||
if (exists $update->{message}{text}) {
|
||||
my $message = $update->{message}{text};
|
||||
my $user_id = $update->{message}{from}{id};
|
||||
my $username = $update->{message}{from}{username};
|
||||
$logger->log_info("'$message' received from $username:$user_id");
|
||||
}
|
||||
}
|
||||
}
|
118
bin/doctor_karma.pl
Executable file
118
bin/doctor_karma.pl
Executable file
@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Data::Dumper;
|
||||
use JSON;
|
||||
|
||||
use DoctorKarma::Config;
|
||||
use DoctorKarma::Telegram;
|
||||
use DoctorKarma::Logger;
|
||||
use DoctorKarma::DB;
|
||||
|
||||
use DoctorKarma::DAO::User;
|
||||
use DoctorKarma::Model::User;
|
||||
|
||||
my $config = DoctorKarma::Config->new;
|
||||
my $logger = DoctorKarma::Logger->new;
|
||||
my $telegram =
|
||||
DoctorKarma::Telegram->new( telegram_token => $config->telegram_token );
|
||||
my $db = DoctorKarma::DB->dbh;
|
||||
|
||||
while (1) {
|
||||
my $updates = $telegram->get_updates;
|
||||
for my $update ( $updates->@* ) {
|
||||
my $message = $update->{message};
|
||||
if ( defined $message ) {
|
||||
proccess_new_message($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub proccess_new_message {
|
||||
my $message = shift;
|
||||
my $reply_to_message = $message->{reply_to_message};
|
||||
|
||||
update_user ($message);
|
||||
if ( defined $message->{text} ) {
|
||||
process_message_with_text($message);
|
||||
}
|
||||
}
|
||||
|
||||
sub process_message_with_text {
|
||||
my $message = shift;
|
||||
|
||||
my $text = $message->{text};
|
||||
my $username = $message->{from}{username};
|
||||
my $user_id = $message->{from}{id};
|
||||
my $first_name = $message->{from}{first_name};
|
||||
my $reply_to_message = $message->{reply_to_message};
|
||||
|
||||
my $log_username = defined $username ? "\@$username" : '';
|
||||
$logger->log_info(
|
||||
"'$message->{text}' received from $first_name:$log_username:$user_id");
|
||||
if ( $text eq '+1' && defined $reply_to_message ) {
|
||||
add_karma_to_replied_message_user ($message);
|
||||
}
|
||||
}
|
||||
|
||||
sub add_karma_to_replied_message_user {
|
||||
my $message = shift;
|
||||
|
||||
my $reply_to_message = $message->{reply_to_message};
|
||||
my $user_giving_id = $message->{from}{id};
|
||||
my $user_receiving_id = $reply_to_message->{from}{id};
|
||||
|
||||
my $user_dao = DoctorKarma::DAO::User->new( dbh => $db );
|
||||
my $sending_karma_user = $user_dao->recover_id( id => $user_giving_id );
|
||||
|
||||
if ( $user_giving_id == $user_receiving_id ) {
|
||||
$logger->log_info(<<"EOF");
|
||||
User @{[$sending_karma_user->first_name]}:@{[$sending_karma_user->username]}:@{[$sending_karma_user->id_user]} tried to give karma to itself, refusing.
|
||||
EOF
|
||||
return;
|
||||
}
|
||||
|
||||
my $receiving_karma_user =
|
||||
$user_dao->recover_id( id => $user_receiving_id );
|
||||
if (!defined $receiving_karma_user) {
|
||||
update_user ($reply_to_message);
|
||||
$receiving_karma_user = $user_dao->recover_id (id => $user_receiving_id);
|
||||
}
|
||||
$user_dao->add_1_karma(user => $receiving_karma_user);
|
||||
|
||||
}
|
||||
|
||||
sub update_user {
|
||||
my $message = shift;
|
||||
|
||||
my $user_id = $message->{from}{id};
|
||||
my $username = $message->{from}{username};
|
||||
my $first_name = $message->{from}{first_name};
|
||||
|
||||
my $user_dao = DoctorKarma::DAO::User->new( dbh => $db );
|
||||
my $user = $user_dao->recover_id( id => $user_id );
|
||||
if ( !defined $user ) {
|
||||
$user = DoctorKarma::Model::User->new(
|
||||
id_user => $user_id,
|
||||
(defined $username) ? (username => $username) : (),
|
||||
karma => 0
|
||||
);
|
||||
$user_dao->store(user => $user);
|
||||
}
|
||||
if ( ( $user->username // '' ) ne ( $username // '' ) ) {
|
||||
$user_dao->update_username(
|
||||
user => $user,
|
||||
username => $username
|
||||
);
|
||||
}
|
||||
if ( ( $user->first_name // '' ) ne $first_name ) {
|
||||
$user_dao->update_firstname(
|
||||
user => $user,
|
||||
first_name => $first_name
|
||||
);
|
||||
}
|
||||
}
|
88
lib/DoctorKarma/Config.pm
Normal file
88
lib/DoctorKarma/Config.pm
Normal file
@ -0,0 +1,88 @@
|
||||
package DoctorKarma::Config;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Term::ReadLine;
|
||||
|
||||
use Const::Fast;
|
||||
use JSON;
|
||||
use Path::Tiny;
|
||||
|
||||
use DoctorKarma::Logger;
|
||||
|
||||
sub HOME { $ENV{HOME} }
|
||||
sub CONFIG_DIR { "@{[HOME]}/.config/doctorkarma" }
|
||||
sub CONFIG_FILE { "@{[CONFIG_DIR]}/config.json" }
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = bless {}, $class;
|
||||
$self->_create_config_file_if_not_exists;
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub logger {
|
||||
my $self = shift;
|
||||
if ( !defined $self->{logger} ) {
|
||||
my $logger = DoctorKarma::Logger->new;
|
||||
$self->{logger} = $logger;
|
||||
}
|
||||
return $self->{logger};
|
||||
}
|
||||
|
||||
sub _config {
|
||||
my $self = shift;
|
||||
if ( !defined $self->{config} ) {
|
||||
if ( !-f CONFIG_FILE ) {
|
||||
$self->logger->log_error(
|
||||
qq(@{[CONFIG_FILE]} is not a plain file, unable to read config.)
|
||||
);
|
||||
die;
|
||||
}
|
||||
my $config = decode_json( path(CONFIG_FILE)->slurp_utf8 );
|
||||
$self->{config} = $config;
|
||||
}
|
||||
return $self->{config};
|
||||
}
|
||||
|
||||
sub telegram_token {
|
||||
my $self = shift;
|
||||
if ( !defined $self->{telegram_token} ) {
|
||||
my $config = $self->_config;
|
||||
$self->{telegram_token} = $config->{telegram_token};
|
||||
}
|
||||
return $self->{telegram_token};
|
||||
}
|
||||
|
||||
sub _create_config_file_if_not_exists {
|
||||
my $self = shift;
|
||||
if ( !-e CONFIG_FILE ) {
|
||||
$self->logger->log_info(q(Config file not detected));
|
||||
$self->_create_config_file;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub _create_config_file {
|
||||
my $self = shift;
|
||||
my $logger = $self->logger;
|
||||
if ( !-e CONFIG_DIR ) {
|
||||
$logger->log_info(qq(Creating @{[CONFIG_DIR]}));
|
||||
eval { path(CONFIG_DIR)->mkpath; };
|
||||
if ($@) {
|
||||
$logger->log_error(
|
||||
qq(Unable to create directory @{[CONFIG_DIR]}: $@));
|
||||
die;
|
||||
}
|
||||
}
|
||||
my $term = Term::ReadLine->new('Doctor Agustín');
|
||||
my $token = $term->readline('Telegram token:');
|
||||
my $config_contents = { telegram_token => $token };
|
||||
$config_contents = encode_json($config_contents);
|
||||
|
||||
path(CONFIG_FILE)->spew_utf8($config_contents);
|
||||
}
|
||||
1;
|
240
lib/DoctorKarma/DAO/User.pm
Normal file
240
lib/DoctorKarma/DAO/User.pm
Normal file
@ -0,0 +1,240 @@
|
||||
package DoctorKarma::DAO::User;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Types::Standard qw/Str Int InstanceOf ArrayRef Maybe HasMethods/;
|
||||
use Params::ValidationCompiler qw(validation_for);
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
dbh => { type => HasMethods [ 'selectrow_hashref', 'do' ] }
|
||||
}
|
||||
);
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my %params = $validator->(@_);
|
||||
my $self = bless {}, $class;
|
||||
$self->{dbh} = $params{dbh};
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
sub _logger {
|
||||
my $self = shift;
|
||||
if ( !defined $self->{logger} ) {
|
||||
$self->{logger} = DoctorKarma::Logger->new;
|
||||
}
|
||||
return $self->{logger};
|
||||
}
|
||||
|
||||
sub _db {
|
||||
my $self = shift;
|
||||
return $self->{dbh};
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
user => { type => InstanceOf ['DoctorKarma::Model::User'] }
|
||||
}
|
||||
);
|
||||
|
||||
sub store {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
|
||||
my $user = $params{user};
|
||||
my $db = $self->_db;
|
||||
my $logger = $self->_logger;
|
||||
|
||||
my $insert = <<'EOF';
|
||||
INSERT INTO users (id, first_name, username, karma) VALUES (?, ?, ?, 0);
|
||||
EOF
|
||||
my $username = "\@@{[$user->username]}:" // '';
|
||||
my $user_id = $user->id_user;
|
||||
my $success = 0 +
|
||||
$db->do( $insert, {}, $user->id_user, $user->username, $user->karma );
|
||||
if ($success) {
|
||||
$logger->log_info("${username}${user_id} registered.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
user => { type => InstanceOf ['DoctorKarma::Model::User'] },
|
||||
first_name => { type => Str },
|
||||
}
|
||||
);
|
||||
|
||||
sub update_firstname {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
|
||||
my $user = $params{user};
|
||||
my $first_name = $params{first_name};
|
||||
|
||||
my $db = $self->_db;
|
||||
my $logger = $self->_logger;
|
||||
|
||||
my $success = 0 + $db->do( <<'EOF', {}, $first_name, $user->id_user );
|
||||
UPDATE users SET first_name = ? WHERE id = ?;
|
||||
EOF
|
||||
if ($success) {
|
||||
my $old_first_name = $user->first_name // 'NULL';
|
||||
$logger->log_info(<<"EOF");
|
||||
Updated first_name for id @{[$user->id_user]}
|
||||
From: ${old_first_name} -> ${first_name}.
|
||||
EOF
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
user => { type => InstanceOf ['DoctorKarma::Model::User'] },
|
||||
}
|
||||
);
|
||||
|
||||
sub add_1_karma {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
|
||||
my $user = $params{user};
|
||||
|
||||
my $db = $self->_db;
|
||||
my $logger = $self->_logger;
|
||||
|
||||
$db->do( <<'EOF', {}, $user->id_user );
|
||||
UPDATE users SET karma=karma+1 WHERE id = ?;
|
||||
EOF
|
||||
my $user_with_new_karma = $self->recover_id( id => $user->id_user );
|
||||
$user->karma( $user_with_new_karma->karma );
|
||||
$logger->log_info( 'User '
|
||||
. $user->first_name . ':'
|
||||
. $user->username . ':'
|
||||
. $user->id_user
|
||||
. ' has now '
|
||||
. $user->karma
|
||||
. ' of karma.' );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
user => { type => InstanceOf ['DoctorKarma::Model::User'] },
|
||||
username => { type => Maybe [Str] },
|
||||
}
|
||||
);
|
||||
|
||||
sub update_username {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
|
||||
my $user = $params{user};
|
||||
my $username = $params{username};
|
||||
|
||||
my $db = $self->_db;
|
||||
my $logger = $self->_logger;
|
||||
|
||||
my $success = 0 + $db->do( <<'EOF', {}, $username, $user->id_user );
|
||||
UPDATE users SET username = ? WHERE id = ?;
|
||||
EOF
|
||||
if ($success) {
|
||||
my $old_username = $user->username ? '@' . $user->username : 'NULL';
|
||||
$username = $username ? "\@$username" : 'NULL';
|
||||
$logger->log_info(<<"EOF");
|
||||
Updated username for id @{[$user->id_user]}
|
||||
From: ${old_username} -> ${username}.
|
||||
EOF
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
id => { type => Int },
|
||||
}
|
||||
);
|
||||
|
||||
sub recover_id {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
|
||||
my $user_id = $params{id};
|
||||
my $query = <<'EOF';
|
||||
SELECT id as id_user, first_name, username, karma, last_karma_given_date
|
||||
FROM users
|
||||
WHERE id = ?;
|
||||
EOF
|
||||
return $self->_recover_by_query(
|
||||
query => $query,
|
||||
arguments => [$user_id]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
username => { type => Str },
|
||||
}
|
||||
);
|
||||
|
||||
sub recover_username {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
|
||||
my $username = $params{username};
|
||||
my $query = <<'EOF';
|
||||
SELECT id as user_id, first_name, username, karma, last_karma_given_date
|
||||
FROM users
|
||||
WHERE username = ?;
|
||||
EOF
|
||||
return $self->_recover_by_query(
|
||||
query => $query,
|
||||
arguments => [$username]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
query => { type => Str },
|
||||
arguments => { type => ArrayRef },
|
||||
}
|
||||
);
|
||||
|
||||
sub _recover_by_query {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
|
||||
my $query = $params{query};
|
||||
my $arguments = $params{arguments};
|
||||
|
||||
my $db = $self->_db;
|
||||
my $user_db = $db->selectrow_hashref( $query, {}, @$arguments );
|
||||
|
||||
if ( defined $user_db ) {
|
||||
for my $key_field ( keys %$user_db ) {
|
||||
$user_db->{$key_field} // delete $user_db->{$key_field};
|
||||
}
|
||||
return DoctorKarma::Model::User->new(%$user_db);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
1
|
70
lib/DoctorKarma/DB.pm
Normal file
70
lib/DoctorKarma/DB.pm
Normal file
@ -0,0 +1,70 @@
|
||||
package DoctorKarma::DB;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use DBI;
|
||||
use Const::Fast;
|
||||
|
||||
use DoctorKarma::Config;
|
||||
|
||||
const my $dbname => "@{[DoctorKarma::Config::CONFIG_DIR()]}/database.sqlite";
|
||||
|
||||
my @migrations = (
|
||||
'CREATE TABLE options (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT
|
||||
);',
|
||||
'CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
username TEXT,
|
||||
karma INTEGER,
|
||||
last_karma_given_date TEXT
|
||||
)',
|
||||
'ALTER TABLE users
|
||||
ADD COLUMN first_name TEXT',
|
||||
);
|
||||
|
||||
sub dbh {
|
||||
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", '', '' , {
|
||||
AutoCommit => 1,
|
||||
RaiseError => 1,
|
||||
});
|
||||
state $migrations_run = 0;
|
||||
if (!$migrations_run) {
|
||||
run_migrations($dbh);
|
||||
$migrations_run = 1;
|
||||
}
|
||||
return $dbh;
|
||||
}
|
||||
|
||||
sub run_migrations {
|
||||
my $dbh = shift;
|
||||
my $current_migration = _get_current_migration_number($dbh);
|
||||
say $current_migration;
|
||||
if ($current_migration < scalar @migrations) {
|
||||
my @needed_migrations = @migrations[$current_migration .. $#migrations];
|
||||
for my $migration (@needed_migrations) {
|
||||
$dbh->do($migration);
|
||||
if (!(0+$dbh->do('UPDATE options SET value = ? WHERE key = "migration"', undef, ++$current_migration))) {
|
||||
$dbh->do('INSERT INTO options (key, value) VALUES ("migration", ?)', undef, $current_migration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub _get_current_migration_number {
|
||||
my $dbh = shift;
|
||||
local $dbh->{RaiseError} = 0;
|
||||
my $migration = $dbh->selectrow_hashref(<<'EOF', {});
|
||||
SELECT value FROM options WHERE key = 'migration'
|
||||
EOF
|
||||
my $value = 0;
|
||||
if (defined $migration) {
|
||||
$value = $migration->{value};
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
1;
|
39
lib/DoctorKarma/Logger.pm
Normal file
39
lib/DoctorKarma/Logger.pm
Normal file
@ -0,0 +1,39 @@
|
||||
package DoctorKarma::Logger;
|
||||
|
||||
use Carp;
|
||||
use Sys::Syslog;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = bless {}, $class;
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _log {
|
||||
my $self = shift;
|
||||
my $level = shift;
|
||||
my $message = shift;
|
||||
my $critical = shift;
|
||||
|
||||
openlog ('DoctorKarma', $critical ? '': 'perror', 'user');
|
||||
syslog ($level, $message);
|
||||
closelog();
|
||||
}
|
||||
|
||||
sub log_error {
|
||||
my $self = shift;
|
||||
$self->_log (LOG_ERR, shift);
|
||||
}
|
||||
|
||||
sub log_critical {
|
||||
my $self = shift;
|
||||
my $error = shift;
|
||||
$self->_log (LOG_ERR, $error, 1);
|
||||
confess $error;
|
||||
}
|
||||
|
||||
sub log_info {
|
||||
my $self = shift;
|
||||
$self->_log (LOG_INFO, shift);
|
||||
}
|
||||
1;
|
79
lib/DoctorKarma/Model/User.pm
Normal file
79
lib/DoctorKarma/Model/User.pm
Normal file
@ -0,0 +1,79 @@
|
||||
package DoctorKarma::Model::User;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Types::Standard qw/Str Int InstanceOf/;
|
||||
use Params::ValidationCompiler qw(validation_for);
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
id_user => { type => Int },
|
||||
username => { type => Str, optional => 1 },
|
||||
first_name => { type => Str, optional => 1 },
|
||||
karma => { type => Int },
|
||||
last_karma_given_date => { type => InstanceOf ['DateTime'], optional => 1 },
|
||||
}
|
||||
);
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my %params = $validator->(@_);
|
||||
my $self = bless \%params, $class;
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub first_name {
|
||||
my $self = shift;
|
||||
if (exists $self->{first_name}) {
|
||||
return $self->{first_name};
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sub id_user {
|
||||
my $self = shift;
|
||||
return $self->{id_user};
|
||||
}
|
||||
|
||||
{
|
||||
my $validator =
|
||||
validation_for( params => [ { type => Str, optional => 1 } ] );
|
||||
|
||||
sub username {
|
||||
my $self = shift;
|
||||
my ($new_username) = $validator->(@_);
|
||||
if ( defined $new_username ) {
|
||||
$self->{username} = $new_username;
|
||||
}
|
||||
if ( exists $self->{username} ) {
|
||||
return $self->{username};
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sub last_karma_given_date {
|
||||
my $self = shift;
|
||||
return $self->{last_karma_given_date};
|
||||
}
|
||||
|
||||
{
|
||||
my $validator =
|
||||
validation_for( params => [ { type => Int, optional => 1 } ] );
|
||||
|
||||
sub karma {
|
||||
my $self = shift;
|
||||
my ($new_karma) = $validator->(@_);
|
||||
if ( defined $new_karma ) {
|
||||
$self->{new_karma} = $new_karma;
|
||||
}
|
||||
return $self->{karma};
|
||||
}
|
||||
}
|
||||
1;
|
130
lib/DoctorKarma/Telegram.pm
Normal file
130
lib/DoctorKarma/Telegram.pm
Normal file
@ -0,0 +1,130 @@
|
||||
package DoctorKarma::Telegram;
|
||||
|
||||
use v5.30.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Types::Standard qw/Str Int Ref/;
|
||||
use Params::ValidationCompiler qw(validation_for);
|
||||
|
||||
use Mojo::UserAgent;
|
||||
use JSON;
|
||||
|
||||
use DoctorKarma::Logger;
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
telegram_token => { type => Str },
|
||||
}
|
||||
);
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = bless {}, $class;
|
||||
my %params = $validator->(@_);
|
||||
my $telegram_token = $params{telegram_token};
|
||||
$self->{telegram_token} = $telegram_token;
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
sub _logger {
|
||||
my $self = shift;
|
||||
if (!defined $self->{logger}) {
|
||||
$self->{logger} = DoctorKarma::Logger->new;
|
||||
}
|
||||
return $self->{logger};
|
||||
}
|
||||
|
||||
sub _user_agent {
|
||||
my $self = shift;
|
||||
if ( !defined $self->{user_agent} ) {
|
||||
$self->{user_agent} = Mojo::UserAgent->new;
|
||||
}
|
||||
return $self->{user_agent};
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
method => { type => Str },
|
||||
body => { type => Ref },
|
||||
}
|
||||
);
|
||||
|
||||
sub _request {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
my $method = $params{method};
|
||||
my $body = $params{body};
|
||||
my $ua = $self->_user_agent;
|
||||
my $logger = $self->_logger;
|
||||
my $url = $self->_generate_url( method => $method );
|
||||
my $response = decode_json(
|
||||
$ua->post( $url => {} => json => $body )->result->body );
|
||||
unless ($response->{ok}) {
|
||||
$logger->log_critical($response->{description});
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
sub get_updates {
|
||||
my $self = shift;
|
||||
my $last_update = $self->_last_update;
|
||||
if ( !defined $last_update ) {
|
||||
$last_update = 0;
|
||||
}
|
||||
my $response = $self->_request(
|
||||
method => q/getUpdates/,
|
||||
body => { offset => $last_update + 1 }
|
||||
);
|
||||
if ( scalar $response->{result}->@* ) {
|
||||
$last_update = $response->{result}[-1]{update_id};
|
||||
$self->_set_last_update($last_update);
|
||||
}
|
||||
return $response->{result};
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for(
|
||||
params => {
|
||||
method => { type => Str },
|
||||
}
|
||||
);
|
||||
|
||||
sub _generate_url {
|
||||
my $self = shift;
|
||||
my %params = $validator->(@_);
|
||||
my $method = $params{method};
|
||||
my $telegram_token = $self->_telegram_token;
|
||||
my $url = qq(https://api.telegram.org/bot$telegram_token/$method);
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $validator = validation_for( params => [ { type => Int } ] );
|
||||
|
||||
sub _set_last_update {
|
||||
my $self = shift;
|
||||
my ($last_update) = $validator->(@_);
|
||||
$self->{last_update} = $last_update;
|
||||
}
|
||||
}
|
||||
|
||||
sub _last_update {
|
||||
my $self = shift;
|
||||
if ( !exists $self->{last_update} ) {
|
||||
return undef;
|
||||
}
|
||||
return $self->{last_update};
|
||||
}
|
||||
|
||||
sub _telegram_token {
|
||||
my $self = shift;
|
||||
return $self->{telegram_token};
|
||||
}
|
||||
1;
|
Loading…
Reference in New Issue
Block a user