Compare commits
65 Commits
35104f883c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65a3382bb0 | ||
|
|
8f6ccfba04 | ||
|
|
2d0ad8560d | ||
|
|
c24644b10e | ||
|
|
f97557868b | ||
|
|
b024d5f13a | ||
|
|
bc270457a4 | ||
|
|
ba4ff36daf | ||
|
|
ec59703000 | ||
|
|
59a1a3538b | ||
|
|
6e76d85899 | ||
|
|
d21bab68ef | ||
|
|
408dccd1b5 | ||
|
|
a568c6f146 | ||
|
|
5448c9bfdb | ||
|
|
da182ae62f | ||
|
|
82df563f40 | ||
|
|
7bd0c3428f | ||
|
|
7904957aaa | ||
|
|
132ebeffa4 | ||
|
|
4f9675f1d2 | ||
|
|
1667772268 | ||
|
|
ebaf2c9b38 | ||
|
|
b9c88ad4e7 | ||
|
|
6a4c2bd076 | ||
|
|
2f9b79d77d | ||
|
|
8eb83ac2b8 | ||
|
|
df3c198bce | ||
|
|
f019b98b1f | ||
|
|
ecf4f94dca | ||
|
|
cea6920d78 | ||
|
|
d4d830715b | ||
|
|
be5c654045 | ||
|
|
5edf5a7e0c | ||
|
|
780ec4fe29 | ||
|
|
fc56f99433 | ||
|
|
5b93e43280 | ||
|
|
c5b4d1c866 | ||
|
|
5a5e4b5ead | ||
|
|
e8765c0e88 | ||
|
|
3dc75936ea | ||
|
|
1f3675de8f | ||
|
|
3668620bd8 | ||
|
|
5411d6df7f | ||
|
|
f6a5a05e58 | ||
|
|
6e084995a7 | ||
|
|
43c08e156f | ||
|
|
b84f8bb245 | ||
|
|
d43cb5995b | ||
|
|
7d74a86dad | ||
|
|
d539c8c9cf | ||
|
|
bd9f66930b | ||
|
|
9618369a45 | ||
|
|
770fce4cfe | ||
|
|
80d9aeca20 | ||
|
|
548c0b3655 | ||
|
|
b4e6685213 | ||
|
|
f9658ac5e8 | ||
|
|
3a75f4c947 | ||
|
|
58128bdbdb | ||
|
|
bec963c7b3 | ||
|
|
b2af26d4e6 | ||
|
|
2708d84d8a | ||
|
|
508b749dff | ||
|
|
cefdec95c4 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,5 +4,7 @@ _Deparsed_XSubs.pm
|
|||||||
.vstags
|
.vstags
|
||||||
aleesa-telegram.pid
|
aleesa-telegram.pid
|
||||||
data/cache/**
|
data/cache/**
|
||||||
|
data/admin/**
|
||||||
data/config.json
|
data/config.json
|
||||||
|
data/chatlist.txt
|
||||||
vendor_perl/**
|
vendor_perl/**
|
||||||
|
|||||||
@@ -42,11 +42,15 @@ sub __fork;
|
|||||||
sub __signal_handler;
|
sub __signal_handler;
|
||||||
|
|
||||||
local $OUTPUT_AUTOFLUSH = 1;
|
local $OUTPUT_AUTOFLUSH = 1;
|
||||||
my $runAsUid = $UID;
|
|
||||||
|
|
||||||
my $piddir = '/var/run/' . basename (abs_path ($PROGRAM_NAME));
|
my $piddir = '/var/run/' . basename (abs_path ($PROGRAM_NAME));
|
||||||
my $C = LoadConf ();
|
my $C = LoadConf ();
|
||||||
my $loglevel = $C->{'loglevel'} // 'notice';
|
my $loglevel = 'notice';
|
||||||
|
|
||||||
|
if (defined $C->{'loglevel'}) {
|
||||||
|
$loglevel = $C->{'loglevel'};
|
||||||
|
}
|
||||||
|
|
||||||
my $logfile;
|
my $logfile;
|
||||||
|
|
||||||
if (defined $C->{'log'}) {
|
if (defined $C->{'log'}) {
|
||||||
|
|||||||
23
cpanfile
23
cpanfile
@@ -7,7 +7,7 @@ requires 'Cwd', '==3.75';
|
|||||||
requires 'Cwd::utf8', '==0.011';
|
requires 'Cwd::utf8', '==0.011';
|
||||||
requires 'Data::Dumper', '==2.183';
|
requires 'Data::Dumper', '==2.183';
|
||||||
requires 'Digest::SHA', '==6.02';
|
requires 'Digest::SHA', '==6.02';
|
||||||
requires 'Encode', '==3.16';
|
requires 'Encode', '==3.19';
|
||||||
requires 'English', '0';
|
requires 'English', '0';
|
||||||
requires 'Exporter', '==5.74';
|
requires 'Exporter', '==5.74';
|
||||||
# part of perl distribution
|
# part of perl distribution
|
||||||
@@ -15,32 +15,33 @@ requires 'IPC::Open2', '0';
|
|||||||
requires 'File::Basename', '==2.85';
|
requires 'File::Basename', '==2.85';
|
||||||
requires 'File::Path', '==2.18';
|
requires 'File::Path', '==2.18';
|
||||||
requires 'File::Spec', '==3.75';
|
requires 'File::Spec', '==3.75';
|
||||||
requires 'IO::Socket::SSL', '==2.074';
|
requires 'IO::Socket::SSL', '==2.077';
|
||||||
requires 'JSON', '==4.05';
|
requires 'JSON', '==4.10';
|
||||||
requires 'JSON::PP', '==4.07';
|
requires 'JSON::PP', '==4.12';
|
||||||
requires 'JSON::XS', '==4.03';
|
requires 'JSON::XS', '==4.03';
|
||||||
requires 'List::Util', '==1.60';
|
requires 'List::Util', '==1.60';
|
||||||
requires 'local::lib', '==2.000028';
|
requires 'local::lib', '==2.000029';
|
||||||
requires 'Log::Any', '==1.710';
|
requires 'Log::Any', '==1.711';
|
||||||
requires 'Log::Any::Adapter', '==1.710';
|
requires 'Log::Any::Adapter', '==1.711';
|
||||||
requires 'Log::Any::For::Std', '==0.05';
|
requires 'Log::Any::For::Std', '==0.05';
|
||||||
requires 'Math::Random::Secure', '==0.080001';
|
requires 'Math::Random::Secure', '==0.080001';
|
||||||
requires 'MIME::Base64', '==3.16';
|
requires 'MIME::Base64', '==3.16';
|
||||||
requires 'Mojolicious', '==9.24';
|
requires 'Mojolicious', '==9.30';
|
||||||
# part of Mojolicious
|
# part of Mojolicious
|
||||||
requires 'Mojo::Base', '0';
|
requires 'Mojo::Base', '0';
|
||||||
# part of Mojolicious
|
# part of Mojolicious
|
||||||
requires 'Mojo::IOLoop', '0';
|
requires 'Mojo::IOLoop', '0';
|
||||||
requires 'Mojo::Redis', '==3.27';
|
requires 'Mojo::Redis', '==3.29';
|
||||||
# part of Mojo::Redis
|
# part of Mojo::Redis
|
||||||
requires 'Mojo::Redis::Connection', '0';
|
requires 'Mojo::Redis::Connection', '0';
|
||||||
# part of Mojolicious
|
# part of Mojolicious
|
||||||
requires 'Mojo::UserAgent', '0';
|
requires 'Mojo::UserAgent', '0';
|
||||||
requires 'open', '==1.12';
|
# part of perl distribution
|
||||||
|
requires 'open', '0';
|
||||||
# part of perl distribution
|
# part of perl distribution
|
||||||
requires 'POSIX', '0';
|
requires 'POSIX', '0';
|
||||||
requires 'Text::Fuzzy', '==0.29';
|
requires 'Text::Fuzzy', '==0.29';
|
||||||
requires 'URI::URL', '==5.10';
|
requires 'URI::URL', '==5.17';
|
||||||
# part of perl distribution
|
# part of perl distribution
|
||||||
requires 'utf8', '0';
|
requires 'utf8', '0';
|
||||||
requires 'version', '==0.9929';
|
requires 'version', '==0.9929';
|
||||||
|
|||||||
168
export_settings.pl
Normal file
168
export_settings.pl
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
# Плагин для сохранения настроек чатов. Экспортирует настройки в json, который можно использовать для импорта в другого
|
||||||
|
# бота.
|
||||||
|
#
|
||||||
|
# Файлик data/chatlist.txt придётся добывать грепаньем дебаг-логов (через скрипт extract_chatlist.txt.pl).
|
||||||
|
# Формат 1 chatid на строку.
|
||||||
|
|
||||||
|
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use utf8;
|
||||||
|
use open qw (:std :utf8);
|
||||||
|
use English qw ( -no_match_vars );
|
||||||
|
|
||||||
|
use version; our $VERSION = qw (1.0);
|
||||||
|
|
||||||
|
my $workdir;
|
||||||
|
|
||||||
|
# before we run, change working dir
|
||||||
|
BEGIN {
|
||||||
|
use Cwd qw (chdir abs_path);
|
||||||
|
my @CWD = split /\//xms, abs_path ($PROGRAM_NAME);
|
||||||
|
|
||||||
|
if ($#CWD > 1) {
|
||||||
|
$#CWD = $#CWD - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$workdir = join '/', @CWD;
|
||||||
|
chdir $workdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
use lib ("$workdir/lib", "$workdir/vendor_perl", "$workdir/vendor_perl/lib/perl5");
|
||||||
|
no Cwd;
|
||||||
|
|
||||||
|
|
||||||
|
use Data::Dumper qw(Dumper);
|
||||||
|
use JSON::XS ();
|
||||||
|
|
||||||
|
use BotLib::Admin qw(
|
||||||
|
FortuneToggleList FortuneEnabled
|
||||||
|
ChanMsgToggleList ChanMsgEnabled
|
||||||
|
GreetMsgToggleList GreetMsgEnabled
|
||||||
|
GoodbyeMsgToggleList GoodbyeMsgEnabled
|
||||||
|
MuteByAdminToggleList MuteByAdminEnabled
|
||||||
|
PluginEnabled);
|
||||||
|
use BotLib::Conf qw(LoadConf);
|
||||||
|
|
||||||
|
my $settings;
|
||||||
|
|
||||||
|
my $chatlistfile = 'data/chatlist.txt';
|
||||||
|
|
||||||
|
my $c = LoadConf('data/config.json');
|
||||||
|
|
||||||
|
my $admin_dir = $c->{admin}->{dir};
|
||||||
|
my $cachedir = $c->{cachedir};
|
||||||
|
|
||||||
|
# Достаём список чатов, где настроена fortune-ка по утрам.
|
||||||
|
my @fortune_chats = FortuneToggleList();
|
||||||
|
|
||||||
|
foreach my $chatid (@fortune_chats) {
|
||||||
|
$settings->{$chatid}->{fortune} = FortuneEnabled($chatid);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Достаём список чатов, где настроена возможность удаления сообщений, отправленных от имени другого калана.
|
||||||
|
my @chanmsg_chats = ChanMsgToggleList();
|
||||||
|
|
||||||
|
foreach my $chatid (@chanmsg_chats) {
|
||||||
|
$settings->{$chatid}->{chanmsg} = ChanMsgEnabled($chatid);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Достаём список чатов, где настроены приветственные сообщения.
|
||||||
|
my @greetmsg_chats = GreetMsgToggleList();
|
||||||
|
|
||||||
|
foreach my $chatid (@greetmsg_chats) {
|
||||||
|
$settings->{$chatid}->{greetmsg} = GreetMsgEnabled($chatid);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Достаём список чатов, где настроены прощальные сообщения.
|
||||||
|
my @goodbyemsg_chats = GoodbyeMsgToggleList();
|
||||||
|
|
||||||
|
foreach my $chatid (@goodbyemsg_chats) {
|
||||||
|
$settings->{$chatid}->{goodbyemsg} = GoodbyeMsgEnabled($chatid);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Достаём список чатов, где настроена возможность мута администратором.
|
||||||
|
my @adminmute_chats = MuteByAdminToggleList();
|
||||||
|
|
||||||
|
foreach my $chatid (@adminmute_chats) {
|
||||||
|
$settings->{$chatid}->{adminmute} = MuteByAdminEnabled($chatid);
|
||||||
|
}
|
||||||
|
|
||||||
|
open my $F, '<', $chatlistfile or die "Unable to open $chatlistfile\n"; ## no critic (ErrorHandling::RequireUseOfExceptions,InputOutput::RequireBriefOpen)
|
||||||
|
|
||||||
|
foreach my $chatid (<$F>) { ## no critic (InputOutput::ProhibitReadlineInForLoop)
|
||||||
|
chomp $chatid;
|
||||||
|
next if $chatid eq '';
|
||||||
|
|
||||||
|
if (PluginEnabled($chatid, 'oboobs')) {
|
||||||
|
$settings->{$chatid}->{plugins}->{oboobs} = 1;
|
||||||
|
}
|
||||||
|
if (PluginEnabled($chatid, 'obutts')) {
|
||||||
|
$settings->{$chatid}->{plugins}->{obutts} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close $F;
|
||||||
|
|
||||||
|
my $data;
|
||||||
|
|
||||||
|
foreach my $chatid (keys %$settings) {
|
||||||
|
my $item->{id} = $chatid;
|
||||||
|
|
||||||
|
if ($settings->{$chatid}->{fortune}) {
|
||||||
|
$item->{fortune} = 1;
|
||||||
|
} else {
|
||||||
|
$item->{fortune} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($settings->{$chatid}->{chanmsg}) {
|
||||||
|
$item->{chanmsg} = 1;
|
||||||
|
} else {
|
||||||
|
$item->{chanmsg} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($settings->{$chatid}->{greetmsg}) {
|
||||||
|
$item->{greetmsg} = 1;
|
||||||
|
} else {
|
||||||
|
$item->{greetmsg} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($settings->{$chatid}->{goodbyemsg}) {
|
||||||
|
$item->{goodbyemsg} = 1;
|
||||||
|
} else {
|
||||||
|
$item->{goodbyemsg} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($settings->{$chatid}->{adminmute}) {
|
||||||
|
$item->{adminmute} = 1;
|
||||||
|
} else {
|
||||||
|
$item->{adminmute} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($settings->{$chatid}->{plugins}->{obutts}) {
|
||||||
|
$item->{plugins}->{obutts} = 1;
|
||||||
|
} else {
|
||||||
|
$item->{plugins}->{obutts} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($settings->{$chatid}->{plugins}->{oboobs}) {
|
||||||
|
$item->{plugins}->{oboobs} = 1;
|
||||||
|
} else {
|
||||||
|
$item->{plugins}->{oboobs} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
push @{$data}, $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $json = eval { JSON::XS->new->utf8(1)->pretty(1)->encode($data) };
|
||||||
|
|
||||||
|
if (defined $json) {
|
||||||
|
print $json . "\n";
|
||||||
|
} else {
|
||||||
|
die "Unable to generate json, something went wrong: $EVAL_ERROR\n"; ## no critic (ErrorHandling::RequireUseOfExceptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
||||||
28
extract_chatlist.txt.pl
Normal file
28
extract_chatlist.txt.pl
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
#
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
my %chats;
|
||||||
|
open my $F, '<', 'debug.log' or die "Unable to open debug.log: $!\n"; ## no critic (ErrorHandling::RequireUseOfExceptions, InputOutput::RequireBriefOpen)
|
||||||
|
|
||||||
|
foreach my $line (<$F>) { ## no critic (InputOutput::ProhibitReadlineInForLoop)
|
||||||
|
if ($line =~ /.DEBUG. In public chat .* \(\-(\d+)\) .* say:/) {
|
||||||
|
next unless defined $1;
|
||||||
|
next if $1 eq '';
|
||||||
|
|
||||||
|
$chats{$1} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close $F;
|
||||||
|
|
||||||
|
open $F, '>', 'chatlist.txt' or die "Unable to open chatlist.txt: $!\n"; ## no critic (ErrorHandling::RequireUseOfExceptions)
|
||||||
|
|
||||||
|
foreach my $chat (keys %chats) {
|
||||||
|
print $F "$chat\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
close $F;
|
||||||
|
|
||||||
|
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
||||||
340
lib/BotLib.pm
340
lib/BotLib.pm
@@ -10,6 +10,7 @@ use English qw ( -no_match_vars );
|
|||||||
|
|
||||||
use Clone qw (clone);
|
use Clone qw (clone);
|
||||||
use Data::Dumper qw (Dumper);
|
use Data::Dumper qw (Dumper);
|
||||||
|
use JSON::PP ();
|
||||||
use Log::Any qw ($log);
|
use Log::Any qw ($log);
|
||||||
use Math::Random::Secure qw (irand);
|
use Math::Random::Secure qw (irand);
|
||||||
|
|
||||||
@@ -17,17 +18,19 @@ use BotLib::Conf qw (LoadConf);
|
|||||||
use BotLib::Admin qw (@ForbiddenMessageTypes GetForbiddenTypes AddForbiddenType
|
use BotLib::Admin qw (@ForbiddenMessageTypes GetForbiddenTypes AddForbiddenType
|
||||||
DelForbiddenType ListForbidden FortuneToggle FortuneStatus
|
DelForbiddenType ListForbidden FortuneToggle FortuneStatus
|
||||||
PluginToggle PluginStatus PluginEnabled ChanMsgToggle ChanMsgStatus
|
PluginToggle PluginStatus PluginEnabled ChanMsgToggle ChanMsgStatus
|
||||||
GreetMsgToggle GreetMsgStatus GoodbyeMsgToggle GoodbyeMsgStatus);
|
GreetMsgToggle GreetMsgStatus GoodbyeMsgToggle GoodbyeMsgStatus MuteByAdminToggle
|
||||||
use BotLib::Util qw (trim);
|
MuteByAdminStatus MuteByAdminEnabled);
|
||||||
|
use BotLib::Util qw (trim Highlight);
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.1);
|
use version; our $VERSION = qw (1.1);
|
||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
our @EXPORT_OK = qw (Command Highlight BotSleep IsCensored);
|
our @EXPORT_OK = qw (Command);
|
||||||
|
|
||||||
my $c = LoadConf ();
|
my $c = LoadConf ();
|
||||||
my $csign = $c->{telegrambot}->{csign};
|
my $csign = $c->{telegrambot}->{csign};
|
||||||
|
|
||||||
my $redismsg->{from} = 'telegram';
|
my $redismsg->{from} = 'telegram';
|
||||||
|
$redismsg->{threadid} = '';
|
||||||
$redismsg->{plugin} = 'telegram';
|
$redismsg->{plugin} = 'telegram';
|
||||||
$redismsg->{misc}->{answer} = 1;
|
$redismsg->{misc}->{answer} = 1;
|
||||||
$redismsg->{misc}->{csign} = "$c->{telegrambot}->{csign}";
|
$redismsg->{misc}->{csign} = "$c->{telegrambot}->{csign}";
|
||||||
@@ -83,9 +86,10 @@ sub Command {
|
|||||||
# Полноценный поиск простой команды во входящем сообщении
|
# Полноценный поиск простой команды во входящем сообщении
|
||||||
$#cmds = -1;
|
$#cmds = -1;
|
||||||
@cmds = qw (ping пинг пинх pong понг понх coin монетка roll dice кости ver version версия хэлп halp kde кде lat
|
@cmds = qw (ping пинг пинх pong понг понх coin монетка roll dice кости ver version версия хэлп halp kde кде lat
|
||||||
лат friday пятница proverb пословица fortune фортунка f ф anek анек анекдот buni cat кис drink праздник fox лис
|
лат friday пятница proverb пословица пословиться fortune фортунка f ф anek анек анекдот buni cat кис
|
||||||
frog лягушка horse лошадь лошадка monkeyuser owl сова сыч rabbit bunny кролик snail улитка tits boobs tities
|
drink праздник fox лис frog лягушка horse лошадь лошадка monkeyuser owl сова сыч rabbit bunny кролик
|
||||||
boobies сиси сисечки butt booty ass попа попка xkcd dig копать fish fishing рыба рыбка рыбалка karma карма);
|
snail улитка tits boobs tities boobies сиси сисечки butt booty ass попа попка xkcd dig копать fish
|
||||||
|
fishing рыба рыбка рыбалка karma карма fuck w п weather погода погодка погадка);
|
||||||
|
|
||||||
my $bingo = 0;
|
my $bingo = 0;
|
||||||
|
|
||||||
@@ -130,6 +134,15 @@ sub Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Если тип группы supergroup, в ней могут быть треды, попробуем найти message_thread_id, если таковой есть
|
||||||
|
if ($msg->chat->type eq 'supergroup') {
|
||||||
|
if ($msg->can ('is_topic_message') && $msg->is_topic_message) {
|
||||||
|
if ($msg->can ('message_thread_id') && $msg->message_thread_id ne '') {
|
||||||
|
$rmsg->{threadid} = "$msg->message_thread_id";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Если соединения с редиской нету, ждём, пока оно появится. Своего рода костыль на всякий случай.
|
# Если соединения с редиской нету, ждём, пока оно появится. Своего рода костыль на всякий случай.
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
@@ -173,11 +186,11 @@ ${csign}ping | ${csign}пинг - попинговать бота
|
|||||||
${csign}roll | ${csign}dice | ${csign}кости - бросить кости
|
${csign}roll | ${csign}dice | ${csign}кости - бросить кости
|
||||||
${csign}snail | ${csign}улитка - улитка
|
${csign}snail | ${csign}улитка - улитка
|
||||||
${csign}ver | ${csign}version | ${csign}версия - что-то про версию ПО
|
${csign}ver | ${csign}version | ${csign}версия - что-то про версию ПО
|
||||||
${csign}w город | ${csign}п город - погода в указанном городе
|
${csign}w <город> | ${csign}п <город> - погода в указанном городе
|
||||||
${csign}weather город - погода в указанном городе
|
${csign}weather <город> - погода в указанном городе
|
||||||
${csign}погода город - погода в указанном городе
|
${csign}погода <город> - погода в указанном городе
|
||||||
${csign}погодка город - погода в указанном городе
|
${csign}погодка <город> - погода в указанном городе
|
||||||
${csign}погадка город - погода в указанном городе
|
${csign}погадка <город> - погода в указанном городе
|
||||||
${csign}xkcd - рандомный стрип с сайта xkcd.ru
|
${csign}xkcd - рандомный стрип с сайта xkcd.ru
|
||||||
${csign}karma фраза | ${csign}карма фраза - посмотреть карму фразы
|
${csign}karma фраза | ${csign}карма фраза - посмотреть карму фразы
|
||||||
фраза-- | фраза++ - убавить или добавить карму фразе
|
фраза-- | фраза++ - убавить или добавить карму фразе
|
||||||
@@ -185,18 +198,31 @@ ${csign}karma фраза | ${csign}карма фраза - посмотреть
|
|||||||
Но на самом деле я бот больше для общения, чем для исполнения команд.
|
Но на самом деле я бот больше для общения, чем для исполнения команд.
|
||||||
Поговоришь со мной?
|
Поговоришь со мной?
|
||||||
MYHELP
|
MYHELP
|
||||||
$msg->replyMd ("$reply");
|
my $res = $msg->replyMd ("$reply");
|
||||||
|
|
||||||
|
if ($res->{error}) {
|
||||||
|
$log->error ('[ERROR] Unable to call sendMessage BotAPI method: ' . Dumper ($res));
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
# Если команда не найдена, но это команда admin
|
# Если команда не найдена, но это команда admin :)
|
||||||
} elsif ($cmd =~ /^(admin|админ)$/u) {
|
} elsif ($cmd =~ /^(admin|админ)(\s+|\s+.*)?$/u) {
|
||||||
my $member = $self->getChatMember ({ 'chat_id' => 0 + $msg->chat->id, 'user_id' => 0 + $msg->from->id });
|
my $send_args->{chat_id} = 0 + $chatid;
|
||||||
|
$send_args->{user_id} = 0 + $msg->from->id;
|
||||||
|
my $member = $self->getChatMember ($send_args);
|
||||||
|
|
||||||
if ($member->{error}) {
|
if ($member->{error}) {
|
||||||
|
$log->error ('[ERROR] Unable to call getChatMember BotAPI method: ' . Dumper ($member));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Это должно показываться только админам чата
|
# Это должно показываться только админам чата
|
||||||
if (($member->status eq 'administrator') || ($member->status eq 'creator')) {
|
if (($member->status ne 'administrator') && ($member->status ne 'creator')) {
|
||||||
|
$log->debug ("[DEBUG] Non admin member called ${csign}admin command, " . $member->status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cmd =~ /^(admin|админ)\s*$/u) {
|
||||||
$reply = << "MYADMIN";
|
$reply = << "MYADMIN";
|
||||||
```
|
```
|
||||||
${csign}admin censor type # - где 1 - вкл, 0 - выкл цензуры для означенного типа сообщений
|
${csign}admin censor type # - где 1 - вкл, 0 - выкл цензуры для означенного типа сообщений
|
||||||
@@ -217,51 +243,78 @@ ${csign}admin obutts # - где 1 - вкл, 0 - выкл плагина o
|
|||||||
${csign}admin obutts - показываем ли попки по просьбе участников чата (команды ${csign}ass, ${csign}butt, ${csign}booty, ${csign}попа, ${csign}попка)
|
${csign}admin obutts - показываем ли попки по просьбе участников чата (команды ${csign}ass, ${csign}butt, ${csign}booty, ${csign}попа, ${csign}попка)
|
||||||
${csign}admin chan_msg - оставляем ли сообщения присланные от имени (других) каналов
|
${csign}admin chan_msg - оставляем ли сообщения присланные от имени (других) каналов
|
||||||
${csign}admin chan_msg # - где 1 - оставляем, 0 - удаляем
|
${csign}admin chan_msg # - где 1 - оставляем, 0 - удаляем
|
||||||
|
${csign}admin ban userid sec - выдаём ban указанному user-у на указанное количество секунд (от 30 сек до 1 года), доступно только создателю чата
|
||||||
${csign}admin mute userid sec - выдаём mute указанному user-у на указанное количество секунд (от 30 сек до 1 года), доступно только создателю чата
|
${csign}admin mute userid sec - выдаём mute указанному user-у на указанное количество секунд (от 30 сек до 1 года), доступно только создателю чата
|
||||||
|
${csign}admin admin mute - разрешено ли обычным админам мьютить участников чата через бота (если бот - админ), (создатель чата всегда может попросить бота-админа замьютить обычного участника чата)
|
||||||
|
${csign}admin admin mute # - где 1 - разрешено, 0 - не разрешено
|
||||||
```
|
```
|
||||||
Типы сообщений:
|
Типы сообщений:
|
||||||
audio voice photo video animation sticker dice game poll document
|
audio voice photo video animation sticker dice game poll document
|
||||||
MYADMIN
|
MYADMIN
|
||||||
|
|
||||||
$msg->replyMd ($reply);
|
my $res = $msg->replyMd ($reply);
|
||||||
|
|
||||||
|
if ($res->{error}) {
|
||||||
|
$log->error('[ERROR] Unable to call sendMessage BotAPI method: ' . Dumper($res));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
# Если строка не найдена, но это команда admin с параметрами
|
} elsif ($cmd =~ /^admin\s+(admin\s+mute)(\s*|\s+0|\s+1)$/gu) {
|
||||||
} elsif ($cmd =~ /^admin\s+.+$/u || $cmd =~ /^админ\s+.+$/u) {
|
my $arg;
|
||||||
my $member = $self->getChatMember ({ 'chat_id' => 0 + $msg->chat->id, 'user_id' => 0 + $msg->from->id });
|
$arg = trim $2 if (defined $2);
|
||||||
|
|
||||||
if ($member->{error}) {
|
if (defined $arg && $arg !~ /^\s*$/ && ($member->status eq 'creator')) {
|
||||||
return;
|
if ($arg == 1) {
|
||||||
|
$reply = MuteByAdminToggle ($chatid, 1);
|
||||||
|
} elsif ($arg == 0) {
|
||||||
|
$reply = MuteByAdminToggle ($chatid, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$reply = MuteByAdminStatus ($chatid);
|
||||||
|
}
|
||||||
|
} elsif ($cmd =~ /^(admin|админ)\s+(ban|mute)\s+(\d+)\s+(\d+)$/gu) {
|
||||||
|
if ($member->status eq 'admin' && (! MuteByAdminEnabled ($chatid))) {
|
||||||
|
return 'Не буду я для тебя никого мьтить.';
|
||||||
}
|
}
|
||||||
|
|
||||||
# Мьютить через бота можно только создателю чятика
|
my (undef, $action, $user_id_to_prosecute, $time) = split /\s+/, $cmd;
|
||||||
if (($member->status eq 'creator') && $cmd =~ /^(admin|админ)\s+mute\s+(\d+)\s+(\d+)$/gu) {
|
|
||||||
my (undef, undef, $user_id_to_mute, $time) = split /\s+/, $cmd;
|
|
||||||
|
|
||||||
# Бот должен быть админом, чтобы мьютить юзеров
|
# Бот должен быть админом, чтобы банить юзеров
|
||||||
my $me = $self->getMe ();
|
my $me = $self->getMe ();
|
||||||
|
|
||||||
if ($me->{error}) {
|
if ($me->{error}) {
|
||||||
|
$log->error ('[ERROR] Unable to call getMe BotAPI method: ' . Dumper ($member));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $myId = $me->id;
|
my $myId = $me->id;
|
||||||
|
|
||||||
if ($myId == $user_id_to_mute) {
|
if ($myId == $user_id_to_prosecute) {
|
||||||
|
if ($action eq 'mute') {
|
||||||
$reply = 'Я не буду себя мьютить.';
|
$reply = 'Я не буду себя мьютить.';
|
||||||
} else {
|
} else {
|
||||||
$me = $self->getChatMember ({'chat_id' => $chatid, 'user_id' => $me->id});
|
$reply = 'Я не буду себя банить.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$send_args = undef;
|
||||||
|
$send_args->{chat_id} = 0 + $chatid;
|
||||||
|
$send_args->{user_id} = 0 + $me->id;
|
||||||
|
$me = $self->getChatMember ($send_args);
|
||||||
|
|
||||||
if ($me->{error}) {
|
if ($me->{error}) {
|
||||||
|
$log->error ('[ERROR] Unable to call getChatMember BotAPI method: ' . Dumper ($me));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($me->status eq 'administrator') {
|
if ($me->status eq 'administrator') {
|
||||||
# Проверим, что такой юзер есть в чятике
|
# Проверим, что такой юзер есть в чятике
|
||||||
my $chatMember = $self->getChatMember ({'chat_id' => $chatid, 'user_id' => $user_id_to_mute});
|
$send_args = undef;
|
||||||
|
$send_args->{chat_id} = 0 + $chatid;
|
||||||
|
$send_args->{user_id} = 0 + $user_id_to_prosecute;
|
||||||
|
my $chatMember = $self->getChatMember ($send_args);
|
||||||
|
|
||||||
if ($chatMember->{error}) {
|
if ($chatMember->{error}) {
|
||||||
|
$log->error ('[ERROR] Unable to call getChatMember BotAPI method: ' . Dumper ($chatMember));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,27 +322,62 @@ MYADMIN
|
|||||||
my $memberStatus = $chatMember->status;
|
my $memberStatus = $chatMember->status;
|
||||||
|
|
||||||
if ($memberStatus eq 'creator') {
|
if ($memberStatus eq 'creator') {
|
||||||
|
if ($action eq 'mute') {
|
||||||
$reply = 'Ты поехал себя мьютить?';
|
$reply = 'Ты поехал себя мьютить?';
|
||||||
|
} else {
|
||||||
|
$reply = 'Ты поехал себя банить?';
|
||||||
|
}
|
||||||
} elsif ($memberStatus eq 'administrator') {
|
} elsif ($memberStatus eq 'administrator') {
|
||||||
|
if ($action eq 'mute') {
|
||||||
$reply = 'Админов мьютить не буду.';
|
$reply = 'Админов мьютить не буду.';
|
||||||
|
} else {
|
||||||
|
$reply = 'Админов банить не буду.';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($time < 30) {
|
if ($time < 30) {
|
||||||
$reply = 'Ты слишком добр.';
|
$reply = 'Ты слишком добр.';
|
||||||
} elsif ($time > (60 * 60 * 24 * 366)) {
|
} elsif ($time > (60 * 60 * 24 * 366)) {
|
||||||
|
if ($action eq 'mute') {
|
||||||
$reply = 'Мьют более чем на 366 дней - перманентный, ты слишком жесток, я так не играю.';
|
$reply = 'Мьют более чем на 366 дней - перманентный, ты слишком жесток, я так не играю.';
|
||||||
} else {
|
} else {
|
||||||
my $result = $self->banChatMember (
|
$reply = 'Бан более чем на 366 дней - перманентный, ты слишком жесток, я так не играю.';
|
||||||
{
|
}
|
||||||
'chat_id' => 0 + $chatid,
|
} else {
|
||||||
'user_id' => 0 + $user_id_to_mute,
|
my $result;
|
||||||
'until_date' => $time + time (),
|
$send_args = undef;
|
||||||
},
|
$send_args->{chat_id} = 0 + $chatid;
|
||||||
);
|
$send_args->{user_id} = 0 + $user_id_to_prosecute;
|
||||||
|
$send_args->{until_date} = $time + time ();
|
||||||
|
|
||||||
if ($result->{error}) {
|
if ($action eq 'mute') {
|
||||||
|
$result = $self->muteChatMember ($send_args);
|
||||||
|
} else {
|
||||||
|
$result = $self->banChatMember ($send_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Если всё хорошо, то возвращается true в формате JSON::PP::Boolean
|
||||||
|
if ((ref ($result) eq 'JSON::PP::Boolean') && ($result == JSON::PP::true)) {
|
||||||
|
$reply = 'Готово.';
|
||||||
|
} elsif (defined ($result->{error}) && $result->{error}) {
|
||||||
|
if ($action eq 'mute') {
|
||||||
|
$log->error (
|
||||||
|
'[ERROR] Unable to call muteChatMember BotAPI method: ' .
|
||||||
|
Dumper ($result)
|
||||||
|
);
|
||||||
$reply = 'Что-то пошло не так, не получается замьютить.';
|
$reply = 'Что-то пошло не так, не получается замьютить.';
|
||||||
} else {
|
} else {
|
||||||
$reply = 'Готово.';
|
$log->error (
|
||||||
|
'[ERROR] Unable to call banChatMember BotAPI method: ' .
|
||||||
|
Dumper ($result)
|
||||||
|
);
|
||||||
|
$reply = 'Что-то пошло не так, не получается забанить.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$log->error (
|
||||||
|
'[ERROR] Unable to call banChatMember/muteChatMember BotAPI method: ' .
|
||||||
|
Dumper ($result)
|
||||||
|
);
|
||||||
|
$reply = 'Что-то пошло совсем не так.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,22 +385,14 @@ MYADMIN
|
|||||||
$reply = 'Я так пока не умею, я здесь не админ.'
|
$reply = 'Я так пока не умею, я здесь не админ.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} elsif ($cmd =~ /^admin\s+(censor|ценз)\s*$/gu) {
|
||||||
|
$reply = ListForbidden ($chatid);
|
||||||
|
} elsif ($cmd =~ /^admin\s+(censor|ценз)\s+(type|тип)\s+(.+)$/gu) {
|
||||||
|
my $arg;
|
||||||
|
$arg = trim $3 if (defined $3);
|
||||||
|
|
||||||
# Это должно показываться только админам чата
|
if (defined $arg && $arg ne '') {
|
||||||
} elsif (($member->status eq 'administrator') || ($member->status eq 'creator')) {
|
my ($msgType, $toggle) = split /\s/, $arg, 2;
|
||||||
# Вынем субкоманду, это первый аргумент команды admin
|
|
||||||
$cmd =~ /^(admin|админ)\s+(.+)$/u;
|
|
||||||
my $command = trim ($2); ## no critic (RegularExpressions::ProhibitCaptureWithoutTest)
|
|
||||||
my ($subcmd, $args) = split /\s+/, $command, 2;
|
|
||||||
|
|
||||||
# Субкоманды не нашлось, ну и какбэ досвидонья
|
|
||||||
if ($subcmd eq '') {
|
|
||||||
return;
|
|
||||||
# Субкоманда censor...
|
|
||||||
} elsif ($subcmd eq 'censor' || $subcmd eq 'ценз') {
|
|
||||||
# Censor с аргументами
|
|
||||||
if (defined ($args) && ($args ne '')) {
|
|
||||||
my ($msgType, $toggle) = split /\s/, $args, 2;
|
|
||||||
|
|
||||||
if (defined $toggle) {
|
if (defined $toggle) {
|
||||||
foreach (@ForbiddenMessageTypes) {
|
foreach (@ForbiddenMessageTypes) {
|
||||||
@@ -327,70 +407,80 @@ MYADMIN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# Censor без аргументов, выдаёт список типов сообщений и будут ли они автоматически удаляться
|
|
||||||
} else {
|
|
||||||
$reply = ListForbidden ($chatid);
|
|
||||||
}
|
}
|
||||||
# Хотим ли мы показывать фортунку с утра
|
} elsif ($cmd =~ /^admin\s+(fortune|фортунка)(\s*|\s+0|\s+1)$/gu) {
|
||||||
} elsif ($subcmd eq 'fortune' || $subcmd eq 'фортунка') {
|
my $arg;
|
||||||
if (defined $args) {
|
$arg = trim $2 if (defined $2);
|
||||||
if ($args == 1) {
|
|
||||||
|
if (defined $arg && $arg !~ /^\s*$/) {
|
||||||
|
if ($arg == 1) {
|
||||||
$reply = FortuneToggle ($chatid, 1);
|
$reply = FortuneToggle ($chatid, 1);
|
||||||
} elsif ($args == 0) {
|
} elsif ($arg == 0) {
|
||||||
$reply = FortuneToggle ($chatid, 0);
|
$reply = FortuneToggle ($chatid, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$reply = FortuneStatus ($chatid);
|
$reply = FortuneStatus ($chatid);
|
||||||
}
|
}
|
||||||
# Хотим ли мы удалять "сообщения от каналов"
|
} elsif ($cmd =~ /^admin\s+chan_msg(\s*|\s+0|\s+1)$/gu) {
|
||||||
} elsif ($subcmd eq 'chan_msg') {
|
my $arg = $1;
|
||||||
if (defined $args) {
|
$arg = trim $1 if (defined $1);
|
||||||
if ($args == 1) {
|
|
||||||
|
if (defined ($arg) && $arg !~ /^\s*$/) {
|
||||||
|
if ($arg == 1) {
|
||||||
$reply = ChanMsgToggle ($chatid, 1);
|
$reply = ChanMsgToggle ($chatid, 1);
|
||||||
} elsif ($args == 0) {
|
} elsif ($arg == 0) {
|
||||||
$reply = ChanMsgToggle ($chatid, 0);
|
$reply = ChanMsgToggle ($chatid, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$reply = ChanMsgStatus ($chatid);
|
$reply = ChanMsgStatus ($chatid);
|
||||||
}
|
}
|
||||||
# Приветствуем ли мы новых участников чата
|
} elsif ($cmd =~ /^admin\s+(greet|приветствие)(\s*|\s+0|\s+1)$/gu) {
|
||||||
} elsif ($subcmd eq 'greet' || $subcmd eq 'приветствие') {
|
my $arg = $2;
|
||||||
if (defined $args) {
|
$arg = trim $2 if (defined $2);
|
||||||
if ($args == 1) {
|
|
||||||
|
if (defined ($arg) && $arg !~ /^\s*$/) {
|
||||||
|
if ($arg == 1) {
|
||||||
$reply = GreetMsgToggle ($chatid, 1);
|
$reply = GreetMsgToggle ($chatid, 1);
|
||||||
} elsif ($args == 0) {
|
} elsif ($arg == 0) {
|
||||||
$reply = GreetMsgToggle ($chatid, 0);
|
$reply = GreetMsgToggle ($chatid, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$reply = GreetMsgStatus ($chatid);
|
$reply = GreetMsgStatus ($chatid);
|
||||||
}
|
}
|
||||||
} elsif ($subcmd eq 'goodbye' || $subcmd eq 'прощание') {
|
} elsif ($cmd =~ /^admin\s+(goodbye|прощание)(\s*|\s+0|\s+1)$/gu) {
|
||||||
if (defined $args) {
|
my $arg = $2;
|
||||||
if ($args == 1) {
|
$arg = trim $2 if (defined $2);
|
||||||
|
|
||||||
|
if (defined ($arg) && $arg !~ /^\s*$/) {
|
||||||
|
if ($arg == 1) {
|
||||||
$reply = GoodbyeMsgToggle ($chatid, 1);
|
$reply = GoodbyeMsgToggle ($chatid, 1);
|
||||||
} elsif ($args == 0) {
|
} elsif ($arg == 0) {
|
||||||
$reply = GoodbyeMsgToggle ($chatid, 0);
|
$reply = GoodbyeMsgToggle ($chatid, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$reply = GoodbyeMsgStatus ($chatid);
|
$reply = GoodbyeMsgStatus ($chatid);
|
||||||
}
|
}
|
||||||
# Работает ли плагин oboobs в чатике
|
} elsif ($cmd =~ /^admin\s+oboobs(\s*|\s+0|\s+1)$/gu) {
|
||||||
} elsif ($subcmd eq 'oboobs') {
|
my $arg = $1;
|
||||||
if (defined $args) {
|
$arg = trim $1 if (defined $1);
|
||||||
if ($args == 1) {
|
|
||||||
|
if (defined ($arg) && $arg !~ /^\s*$/) {
|
||||||
|
if ($arg == 1) {
|
||||||
$reply = PluginToggle ($chatid, 'oboobs', 1);
|
$reply = PluginToggle ($chatid, 'oboobs', 1);
|
||||||
} elsif ($args == 0) {
|
} elsif ($arg == 0) {
|
||||||
$reply = PluginToggle ($chatid, 'oboobs', 0);
|
$reply = PluginToggle ($chatid, 'oboobs', 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$reply = PluginStatus ($chatid, 'oboobs');
|
$reply = PluginStatus ($chatid, 'oboobs');
|
||||||
}
|
}
|
||||||
# Работает ли плагин obutts в чатике
|
} elsif ($cmd =~ /^admin\s+obutts(\s*|\s+0|\s+1)$/gu) {
|
||||||
} elsif ($subcmd eq 'obutts') {
|
my $arg = $1;
|
||||||
if (defined $args) {
|
$arg = trim $1 if (defined $1);
|
||||||
if ($args == 1) {
|
|
||||||
|
if (defined ($arg) && $arg !~ /^\s*$/) {
|
||||||
|
if ($arg == 1) {
|
||||||
$reply = PluginToggle ($chatid, 'obutts', 1);
|
$reply = PluginToggle ($chatid, 'obutts', 1);
|
||||||
} elsif ($args == 0) {
|
} elsif ($arg == 0) {
|
||||||
$reply = PluginToggle ($chatid, 'obutts', 0);
|
$reply = PluginToggle ($chatid, 'obutts', 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -398,90 +488,10 @@ MYADMIN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $reply;
|
return $reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Highlight {
|
|
||||||
my $msg = shift;
|
|
||||||
|
|
||||||
my $fullname;
|
|
||||||
my $highlight;
|
|
||||||
my $username;
|
|
||||||
my $visavi = '';
|
|
||||||
my $userid = $msg->from->id;
|
|
||||||
|
|
||||||
if ($msg->from->can ('username') && defined $msg->from->username ) {
|
|
||||||
$username = $msg->from->username;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($msg->from->can ('first_name') && defined $msg->from->first_name) {
|
|
||||||
$fullname = $msg->from->first_name;
|
|
||||||
|
|
||||||
if ($msg->from->can ('last_name') && defined $msg->from->last_name) {
|
|
||||||
$fullname .= ' ' . $msg->from->last_name;
|
|
||||||
}
|
|
||||||
} elsif ($msg->from->can ('last_name') && defined $msg->from->last_name) {
|
|
||||||
$fullname .= $msg->from->last_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defined $username) {
|
|
||||||
$visavi .= '@' . $username;
|
|
||||||
|
|
||||||
if (defined $fullname) {
|
|
||||||
$highlight = "[$fullname](tg://user?id=$userid)";
|
|
||||||
$visavi .= ', ' . $fullname;
|
|
||||||
} else {
|
|
||||||
$highlight = "[$username](tg://user?id=$userid)";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$highlight = "[$fullname](tg://user?id=$userid)";
|
|
||||||
$visavi .= $fullname;
|
|
||||||
}
|
|
||||||
|
|
||||||
$visavi .= " ($userid)";
|
|
||||||
|
|
||||||
return ($userid, $username, $fullname, $highlight, $visavi);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub BotSleep {
|
|
||||||
# TODO: Parametrise this with fuzzy sleep time in seconds
|
|
||||||
my $msg = shift;
|
|
||||||
# let's emulate real human and delay answer
|
|
||||||
sleep (irand (2) + 1);
|
|
||||||
|
|
||||||
for (0..(4 + irand (3))) {
|
|
||||||
$msg->typing ();
|
|
||||||
sleep 3;
|
|
||||||
sleep 3 unless ($_);
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep ( 3 + irand (2));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub IsCensored {
|
|
||||||
my $msg = shift;
|
|
||||||
|
|
||||||
my $forbidden = GetForbiddenTypes ($msg->chat->id);
|
|
||||||
|
|
||||||
# voice messages are special
|
|
||||||
if (defined ($msg->voice) && defined ($msg->voice->duration) && ($msg->voice->duration > 0)) {
|
|
||||||
if ($forbidden->{'voice'}) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (keys %{$forbidden}) {
|
|
||||||
if ($forbidden->{$_} && (defined $msg->{$_})) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
||||||
|
|||||||
@@ -15,10 +15,19 @@ use version; our $VERSION = qw (1.1);
|
|||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
# to export array we need @ISA here
|
# to export array we need @ISA here
|
||||||
our @ISA = qw / Exporter /; ## no critic (ClassHierarchies::ProhibitExplicitISA)
|
our @ISA = qw / Exporter /; ## no critic (ClassHierarchies::ProhibitExplicitISA)
|
||||||
our @EXPORT_OK = qw (@ForbiddenMessageTypes @PluginList GetForbiddenTypes AddForbiddenType DelForbiddenType
|
our @EXPORT_OK = qw (@ForbiddenMessageTypes @PluginList
|
||||||
ListForbidden FortuneToggle FortuneToggleList FortuneStatus PluginToggle PluginStatus
|
GetForbiddenTypes AddForbiddenType DelForbiddenType ListForbidden EnabledForbidden
|
||||||
PluginEnabled ChanMsgToggle ChanMsgStatus ChanMsgEnabled GreetMsgToggle GreetMsgStatus
|
FortuneToggle FortuneStatus FortuneEnabled FortuneToggleList
|
||||||
GreetMsgEnabled GoodbyeMsgToggle GoodbyeMsgStatus GoodbyeMsgEnabled);
|
ChanMsgToggle ChanMsgStatus ChanMsgEnabled ChanMsgToggleList
|
||||||
|
GreetMsgToggle GreetMsgStatus GreetMsgEnabled GreetMsgToggleList
|
||||||
|
GoodbyeMsgToggle GoodbyeMsgStatus GoodbyeMsgEnabled GoodbyeMsgToggleList
|
||||||
|
PluginToggle PluginStatus PluginEnabled
|
||||||
|
MuteByAdminToggle MuteByAdminStatus MuteByAdminEnabled MuteByAdminToggleList
|
||||||
|
MigrateSettingsToNewChatID
|
||||||
|
IsCensored
|
||||||
|
GetSlackGreetRememberId
|
||||||
|
SetSlackGreetRememberId
|
||||||
|
);
|
||||||
|
|
||||||
my $c = LoadConf ();
|
my $c = LoadConf ();
|
||||||
my $cachedir = $c->{cachedir};
|
my $cachedir = $c->{cachedir};
|
||||||
@@ -108,6 +117,29 @@ sub ListForbidden {
|
|||||||
return join "\n", @list;
|
return join "\n", @list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub EnabledForbidden {
|
||||||
|
my $chatid = shift;
|
||||||
|
my $ftype = shift;
|
||||||
|
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'censor' . '_' . utf2sha1 ($chatid),
|
||||||
|
);
|
||||||
|
|
||||||
|
my $type = $cache->get ($ftype);
|
||||||
|
|
||||||
|
if ($type) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
unless (defined $type) {
|
||||||
|
$cache->set ($ftype, 0, 'never');
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub FortuneToggle (@) {
|
sub FortuneToggle (@) {
|
||||||
my $chatid = shift;
|
my $chatid = shift;
|
||||||
my $action = shift // undef;
|
my $action = shift // undef;
|
||||||
@@ -166,6 +198,24 @@ sub FortuneStatus ($) {
|
|||||||
return $phrase;
|
return $phrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub FortuneEnabled ($) {
|
||||||
|
my $chatid = shift;
|
||||||
|
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'fortune',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $state = $cache->get ($chatid);
|
||||||
|
|
||||||
|
if (defined $state && $state) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub FortuneToggleList () {
|
sub FortuneToggleList () {
|
||||||
my $cache = CHI->new (
|
my $cache = CHI->new (
|
||||||
driver => 'BerkeleyDB',
|
driver => 'BerkeleyDB',
|
||||||
@@ -288,33 +338,28 @@ sub GreetMsgToggle (@) {
|
|||||||
namespace => __PACKAGE__ . '_' . 'greet_msg',
|
namespace => __PACKAGE__ . '_' . 'greet_msg',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (defined $action) {
|
||||||
|
if ($action == 0) {
|
||||||
|
$cache->set ($chatid, 0, 'never');
|
||||||
|
$phrase .= 'выключены.';
|
||||||
|
} else {
|
||||||
|
$cache->set ($chatid, 1, 'never');
|
||||||
|
$phrase .= 'включены.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
my $state = $cache->get ($chatid);
|
my $state = $cache->get ($chatid);
|
||||||
|
|
||||||
if (defined $action) {
|
|
||||||
if ($action) {
|
|
||||||
$cache->set ($chatid, 1, 'never');
|
|
||||||
$phrase .= 'включено.';
|
|
||||||
} else {
|
|
||||||
if (defined $state && $state) {
|
|
||||||
$cache->set ($chatid, 0, 'never');
|
|
||||||
$phrase .= 'выключено.';
|
|
||||||
} else {
|
|
||||||
$cache->set ($chatid, 1, 'never');
|
|
||||||
$phrase .= 'включено.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (defined $state) {
|
if (defined $state) {
|
||||||
if ($state) {
|
if ($state != 0) {
|
||||||
$cache->set ($chatid, 0, 'never');
|
$cache->set ($chatid, 0, 'never');
|
||||||
$phrase .= 'выключено.';
|
$phrase .= 'выключены.';
|
||||||
} else {
|
} else {
|
||||||
$cache->set ($chatid, 1, 'never');
|
$cache->set ($chatid, 1, 'never');
|
||||||
$phrase .= 'включено.';
|
$phrase .= 'включены.';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$cache->set ($chatid, 0, 'never');
|
$cache->set ($chatid, 0, 'never');
|
||||||
$phrase .= 'выключено.';
|
$phrase .= 'выключены.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +413,16 @@ sub GreetMsgEnabled ($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub GreetMsgToggleList () {
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'greet_msg',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $cache->get_keys ();
|
||||||
|
}
|
||||||
|
|
||||||
sub GoodbyeMsgToggle (@) {
|
sub GoodbyeMsgToggle (@) {
|
||||||
my $chatid = shift;
|
my $chatid = shift;
|
||||||
my $action = shift // undef;
|
my $action = shift // undef;
|
||||||
@@ -454,6 +509,16 @@ sub GoodbyeMsgEnabled ($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub GoodbyeMsgToggleList () {
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'goodbye_msg',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $cache->get_keys ();
|
||||||
|
}
|
||||||
|
|
||||||
sub PluginStatus (@) {
|
sub PluginStatus (@) {
|
||||||
my $chatid = shift;
|
my $chatid = shift;
|
||||||
my $plugin = shift;
|
my $plugin = shift;
|
||||||
@@ -539,6 +604,209 @@ sub PluginToggle (@) {
|
|||||||
return $phrase;
|
return $phrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub MuteByAdminToggle (@) {
|
||||||
|
my $chatid = shift;
|
||||||
|
my $action = shift // undef;
|
||||||
|
my $phrase = 'Мьют участников чата админами ';
|
||||||
|
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'admin_mute',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $state = $cache->get ($chatid);
|
||||||
|
|
||||||
|
if (defined $action) {
|
||||||
|
if ($action) {
|
||||||
|
$cache->set ($chatid, 1, 'never');
|
||||||
|
$phrase .= 'разрешён.';
|
||||||
|
} else {
|
||||||
|
$cache->set ($chatid, 0, 'never');
|
||||||
|
$phrase .= 'запрещён.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (defined $state){
|
||||||
|
if ($state) {
|
||||||
|
$cache->set ($chatid, 0, 'never');
|
||||||
|
$phrase .= 'запрещён.';
|
||||||
|
} else {
|
||||||
|
$cache->set ($chatid, 1, 'never');
|
||||||
|
$phrase .= 'разрешён.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$cache->set ($chatid, 1, 'never');
|
||||||
|
$phrase .= 'разрешён.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $phrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub MuteByAdminStatus ($) {
|
||||||
|
my $chatid = shift;
|
||||||
|
my $phrase = 'Мьют админами участников чата ';
|
||||||
|
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'admin_mute',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $state = $cache->get ($chatid);
|
||||||
|
|
||||||
|
if (defined $state) {
|
||||||
|
if ($state) {
|
||||||
|
$phrase .= 'разрешён.';
|
||||||
|
} else {
|
||||||
|
$phrase .= 'запрещён.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$phrase .= 'запрещён.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $phrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub MuteByAdminEnabled ($) {
|
||||||
|
my $chatid = shift;
|
||||||
|
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'admin_mute',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $state = $cache->get ($chatid);
|
||||||
|
|
||||||
|
if (defined $state) {
|
||||||
|
if ($state) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub MuteByAdminToggleList () {
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'admin_mute',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $cache->get_keys ();
|
||||||
|
}
|
||||||
|
|
||||||
|
sub MigrateSettingsToNewChatID {
|
||||||
|
my $old_id = shift;
|
||||||
|
my $new_id = shift;
|
||||||
|
# TODO: Catch errors, if error==1, than noop
|
||||||
|
|
||||||
|
if (FortuneEnabled ($old_id)) {
|
||||||
|
FortuneToggle ($new_id, 1);
|
||||||
|
FortuneToggle ($old_id, 0);
|
||||||
|
} else {
|
||||||
|
FortuneToggle ($new_id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ChanMsgEnabled ($old_id)) {
|
||||||
|
ChanMsgToggle ($new_id, 1);
|
||||||
|
} else {
|
||||||
|
ChanMsgToggle ($new_id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GreetMsgEnabled ($old_id)) {
|
||||||
|
GreetMsgToggle ($new_id, 1);
|
||||||
|
} else {
|
||||||
|
GreetMsgToggle ($new_id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GoodbyeMsgEnabled ($old_id)) {
|
||||||
|
GoodbyeMsgToggle ($new_id, 1);
|
||||||
|
} else {
|
||||||
|
GoodbyeMsgToggle ($new_id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $plugin (@PluginList) {
|
||||||
|
if (PluginEnabled ($old_id, $plugin)) {
|
||||||
|
PluginToggle ($new_id, $plugin, 1);
|
||||||
|
} else {
|
||||||
|
PluginToggle ($new_id, $plugin, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $ftype (@ForbiddenMessageTypes) {
|
||||||
|
if (EnabledForbidden($old_id, $ftype)) {
|
||||||
|
AddForbiddenType($new_id, $ftype);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Looks like we don't need to add forbidden type for allowed types... right?
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub IsCensored {
|
||||||
|
my $msg = shift;
|
||||||
|
|
||||||
|
my $forbidden = GetForbiddenTypes ($msg->chat->id);
|
||||||
|
|
||||||
|
# voice messages are special
|
||||||
|
if (defined ($msg->voice) && defined ($msg->voice->duration) && ($msg->voice->duration > 0)) {
|
||||||
|
if ($forbidden->{'voice'}) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (keys %{$forbidden}) {
|
||||||
|
if ($forbidden->{$_} && (defined $msg->{$_})) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub GetSlackGreetRememberId ($) {
|
||||||
|
my $userid = shift;
|
||||||
|
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'slack_greet_remember_id',
|
||||||
|
);
|
||||||
|
|
||||||
|
my $state = $cache->get ($userid);
|
||||||
|
|
||||||
|
if (defined $state) {
|
||||||
|
if ($state) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub SetSlackGreetRememberId ($) {
|
||||||
|
my $userid = shift;
|
||||||
|
|
||||||
|
my $cache = CHI->new (
|
||||||
|
driver => 'BerkeleyDB',
|
||||||
|
root_dir => $cachedir,
|
||||||
|
namespace => __PACKAGE__ . '_' . 'slack_greet_remember_id',
|
||||||
|
);
|
||||||
|
|
||||||
|
$cache->set ($userid, 1, 'never');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use Exporter qw (import);
|
|||||||
our @EXPORT_OK = qw (LoadConf);
|
our @EXPORT_OK = qw (LoadConf);
|
||||||
|
|
||||||
sub LoadConf {
|
sub LoadConf {
|
||||||
my $c = 'data/config.json';
|
my $c = shift // 'data/config.json';
|
||||||
my $CH;
|
my $CH;
|
||||||
|
|
||||||
unless (open $CH, '<', $c) {
|
unless (open $CH, '<', $c) {
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ use open qw (:std :utf8);
|
|||||||
use English qw ( -no_match_vars );
|
use English qw ( -no_match_vars );
|
||||||
use Digest::SHA qw (sha1_base64);
|
use Digest::SHA qw (sha1_base64);
|
||||||
use Encode qw (encode_utf8);
|
use Encode qw (encode_utf8);
|
||||||
|
use Math::Random::Secure qw (irand);
|
||||||
use MIME::Base64 qw (encode_base64);
|
use MIME::Base64 qw (encode_base64);
|
||||||
use Text::Fuzzy qw (distance_edits);
|
use Text::Fuzzy qw (distance_edits);
|
||||||
use URI::URL qw (url);
|
use URI::URL qw (url);
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.0);
|
use version; our $VERSION = qw (1.0);
|
||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
our @EXPORT_OK = qw (trim urlencode fmatch utf2b64 utf2sha1);
|
our @EXPORT_OK = qw (trim urlencode fmatch utf2b64 utf2sha1 BotSleep Highlight RandomCommonPhrase);
|
||||||
|
|
||||||
sub trim {
|
sub trim {
|
||||||
my $str = shift;
|
my $str = shift;
|
||||||
@@ -72,6 +73,110 @@ sub utf2sha1 {
|
|||||||
return sha1_base64 $bytes;
|
return sha1_base64 $bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub Highlight {
|
||||||
|
my $msg = shift;
|
||||||
|
|
||||||
|
my $fullname;
|
||||||
|
my $highlight;
|
||||||
|
my $username;
|
||||||
|
my $visavi = '';
|
||||||
|
|
||||||
|
my $userid;
|
||||||
|
|
||||||
|
# In channel message $msg->from->id is omitted
|
||||||
|
# In channel context Highlight is pointless
|
||||||
|
if ($msg->chat->type eq 'channel') {
|
||||||
|
return ($userid, $username, $fullname, $highlight, undef);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($msg->can ('from')) {
|
||||||
|
$userid = $msg->from->id;
|
||||||
|
|
||||||
|
if ($msg->from->can ('username') && defined $msg->from->username ) {
|
||||||
|
$username = $msg->from->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($msg->from->can ('first_name') && defined $msg->from->first_name) {
|
||||||
|
$fullname = $msg->from->first_name;
|
||||||
|
|
||||||
|
if ($msg->from->can ('last_name') && defined $msg->from->last_name) {
|
||||||
|
$fullname .= ' ' . $msg->from->last_name;
|
||||||
|
}
|
||||||
|
} elsif ($msg->from->can ('last_name') && defined $msg->from->last_name) {
|
||||||
|
$fullname .= $msg->from->last_name;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# Reacions case.
|
||||||
|
$userid = $msg->user->id;
|
||||||
|
|
||||||
|
if ($msg->user->can ('username') && defined $msg->user->username ) {
|
||||||
|
$username = $msg->user->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($msg->user->can ('first_name') && defined $msg->user->first_name) {
|
||||||
|
$fullname = $msg->user->first_name;
|
||||||
|
|
||||||
|
if ($msg->user->can ('last_name') && defined $msg->user->last_name) {
|
||||||
|
$fullname .= ' ' . $msg->user->last_name;
|
||||||
|
}
|
||||||
|
} elsif ($msg->user->can ('last_name') && defined $msg->user->last_name) {
|
||||||
|
$fullname .= $msg->user->last_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined $username) {
|
||||||
|
$visavi .= '@' . $username;
|
||||||
|
|
||||||
|
if (defined $fullname) {
|
||||||
|
$highlight = "[$fullname](tg://user?id=$userid)";
|
||||||
|
$visavi .= ', ' . $fullname;
|
||||||
|
} else {
|
||||||
|
$highlight = "[$username](tg://user?id=$userid)";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$highlight = "[$fullname](tg://user?id=$userid)";
|
||||||
|
$visavi .= $fullname;
|
||||||
|
}
|
||||||
|
|
||||||
|
$visavi .= " ($userid)";
|
||||||
|
|
||||||
|
return ($userid, $username, $fullname, $highlight, $visavi);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub RandomCommonPhrase {
|
||||||
|
my @myphrase = (
|
||||||
|
'Так, блядь...',
|
||||||
|
'*Закатывает рукава* И ради этого ты меня позвал?',
|
||||||
|
'Ну чего ты начинаешь, нормально же общались',
|
||||||
|
'Повтори свой вопрос, не поняла',
|
||||||
|
'Выйди и зайди нормально',
|
||||||
|
'Я подумаю',
|
||||||
|
'Даже не знаю, что на это ответить',
|
||||||
|
'Ты упал такие вопросы девочке задавать?',
|
||||||
|
'Можно и так, но не уверена',
|
||||||
|
'А как ты думаешь?',
|
||||||
|
'А ви, таки, почему интересуетесь?',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $myphrase[irand ($#myphrase + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub BotSleep {
|
||||||
|
# TODO: Parametrise this with fuzzy sleep time in seconds
|
||||||
|
my $msg = shift;
|
||||||
|
# let's emulate real human and delay answer
|
||||||
|
sleep (irand (2) + 1);
|
||||||
|
|
||||||
|
for (0..(4 + irand (3))) {
|
||||||
|
$msg->typing ();
|
||||||
|
sleep 3;
|
||||||
|
sleep 3 unless ($_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep ( 3 + irand (2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
||||||
|
|||||||
@@ -4,15 +4,17 @@ use 5.018; ## no critic (ProhibitImplicitImport)
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use utf8;
|
use utf8;
|
||||||
|
use English qw ( -no_match_vars );
|
||||||
use open qw (:std :utf8);
|
use open qw (:std :utf8);
|
||||||
|
|
||||||
use Data::Dumper qw (Dumper);
|
use Data::Dumper qw (Dumper);
|
||||||
|
use JSON::XS qw (decode_json);
|
||||||
use Log::Any qw ($log);
|
use Log::Any qw ($log);
|
||||||
use Mojo::Redis ();
|
use Mojo::Redis ();
|
||||||
use Mojo::Redis::Connection ();
|
use Mojo::Redis::Connection ();
|
||||||
|
|
||||||
|
use BotLib::Admin qw (MigrateSettingsToNewChatID FortuneToggle);
|
||||||
use BotLib::Conf qw (LoadConf);
|
use BotLib::Conf qw (LoadConf);
|
||||||
use Teapot::Bot::Object::ChatPermissions ();
|
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.0);
|
use version; our $VERSION = qw (1.0);
|
||||||
use Exporter qw (import);
|
use Exporter qw (import);
|
||||||
@@ -41,25 +43,76 @@ sub redis_parse_message {
|
|||||||
$message->{chat_id} = eval { 0 + $m->{chatid}; };
|
$message->{chat_id} = eval { 0 + $m->{chatid}; };
|
||||||
|
|
||||||
unless (defined $message->{chat_id}) {
|
unless (defined $message->{chat_id}) {
|
||||||
$log->error ('Incoming redis message is incorrect: chat id must be numeric value!');
|
$log->error ('[ERROR] Incoming redis message is incorrect: chat id must be numeric value!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($message->{chat_id} == 0) {
|
if ($message->{chat_id} == 0) {
|
||||||
$log->error ('Incoming redis message is incorrect: chat id must not be equal 0!');
|
$log->error ('[ERROR] Incoming redis message is incorrect: chat id must not be equal 0!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$message->{text} = "$m->{message}";
|
$message->{text} = "$m->{message}";
|
||||||
|
|
||||||
my $can_talk = Teapot::Bot::Object::ChatPermissions->canTalk ($main::TGM, 0 + $m->{chatid});
|
if (defined ($m->{threadid}) && $m->{threadid} ne '') {
|
||||||
|
$message->{message_thread_id} = 0 + $m->{threadid};
|
||||||
|
}
|
||||||
|
|
||||||
if ($can_talk) {
|
# we cannot use $self->_brain->can_talk here because of $self pointing to redis object, not telegram
|
||||||
# Результат этого действия нас не сильно волнует, т.к. если будет ошибка, то в лог попадёт трейс
|
my $can_talk = $main::TGM->can_talk ({ chat_id => 0 + $m->{chatid}});
|
||||||
|
|
||||||
|
if ($can_talk->{error}) {
|
||||||
|
$log->error ('[ERROR] Unable to guess if i can talk in this chat: ' . Dumper ($can_talk));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($can_talk->{can_talk}) {
|
||||||
my $r = $main::TGM->sendMessage ($message);
|
my $r = $main::TGM->sendMessage ($message);
|
||||||
|
|
||||||
if ($r->{error}) {
|
if ($r->{error}) {
|
||||||
$log->error ("An error occured while sending message to chat $m->{chatid}");
|
# TODO: handle 50x errors? They occur when api servers being updated.
|
||||||
|
my $resp = eval { $r->{debug}->json };
|
||||||
|
|
||||||
|
if (defined $resp) {
|
||||||
|
if (defined ($resp->{error_code}) && $resp->{error_code} == 400) {
|
||||||
|
if (defined $resp->{description}) {
|
||||||
|
if ($resp->{description} eq 'Bad Request: not enough rights to send text messages to the chat') {
|
||||||
|
$log->notice ("[NOTICE] Have no rights to send message to $m->{chatid}");
|
||||||
|
# TODO: disable fortune if message is good morning fortune
|
||||||
|
} elsif ($resp->{description} eq 'Bad Request: chat not found') {
|
||||||
|
$log->notice (
|
||||||
|
"[NOTICE] Chat not found toggling good morning fortune off for $m->{chatid}"
|
||||||
|
);
|
||||||
|
|
||||||
|
FortuneToggle($m->{chatid}, 0);
|
||||||
|
return;
|
||||||
|
} elsif ($resp->description eq 'Bad Request: group chat was upgraded to a supergroup chat') {
|
||||||
|
if (defined ($resp->{parameters}) &&
|
||||||
|
defined ($resp->{parameters}->{migrate_to_chat_id})) {
|
||||||
|
my $tpl = '[NOTICE] group upgraded to supergroup, chat_id changed, ';
|
||||||
|
$tpl .= 'migrating settings from %s to %s';
|
||||||
|
|
||||||
|
$log->notice (
|
||||||
|
sprintf($tpl, $m->{chatid}, $resp->{parameters}->{migrate_to_chat_id})
|
||||||
|
);
|
||||||
|
|
||||||
|
MigrateSettingsToNewChatID (
|
||||||
|
$m->{chatid},
|
||||||
|
$resp->{parameters}->{migrate_to_chat_id}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$log->error ('[ERROR] Unable to call sendMessage() BotAPI method: ' . Dumper ($r));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$log->error ('[ERROR] BotAPI returns parsable error: ' . Dumper ($resp));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$log->error ('[ERROR] Unable to handle BotAPI error: ' . Dumper ($resp));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$log->error ('[ERROR] Unable to call sendMessage() BotAPI method: ' . Dumper ($r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use 5.018; ## no critic (ProhibitImplicitImport)
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
use utf8;
|
use utf8;
|
||||||
$Teapot::Bot::VERSION = '0.023';
|
$Teapot::Bot::VERSION = '0.026';
|
||||||
# ABSTRACT: A base class to make your very own Telegram bot
|
# ABSTRACT: A base class to make your very own Telegram bot
|
||||||
|
|
||||||
1;
|
1;
|
||||||
@@ -25,7 +25,7 @@ A base class to make your very own Telegram bot
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,14 +9,14 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::PhotoSize ();
|
use Teapot::Bot::Object::PhotoSize ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Animation::VERSION = '0.023';
|
$Teapot::Bot::Object::Animation::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
has 'width';
|
has 'width';
|
||||||
has 'height';
|
has 'height';
|
||||||
has 'duration';
|
has 'duration';
|
||||||
has 'thumb'; #PhotoSize
|
has 'thumbnail'; #PhotoSize
|
||||||
has 'file_name';
|
has 'file_name';
|
||||||
has 'mime_type';
|
has 'mime_type';
|
||||||
has 'file_size';
|
has 'file_size';
|
||||||
@@ -24,7 +24,7 @@ has 'file_size';
|
|||||||
sub fields {
|
sub fields {
|
||||||
return { scalar => [qw/file_id file_unique_id width height duration file_name mime_type
|
return { scalar => [qw/file_id file_unique_id width height duration file_name mime_type
|
||||||
file_size/],
|
file_size/],
|
||||||
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/],
|
'Teapot::Bot::Object::PhotoSize' => [qw/thumbnail/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ Teapot::Bot::Object::Animation - The base class for Telegram message 'Animation'
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'Animation' type.
|
The base class for Telegram message 'Animation' type.
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use 5.018; ## no critic (ProhibitImplicitImport)
|
|||||||
use utf8;
|
use utf8;
|
||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
use Teapot::Bot::Object::PhotoSize ();
|
||||||
$Teapot::Bot::Object::Audio::VERSION = '0.023';
|
$Teapot::Bot::Object::Audio::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
@@ -18,12 +18,12 @@ has 'title'; # Optional. Title of the audio as defined by sender or by audio
|
|||||||
has 'file_name'; # Optional. Original filename as defined by sender
|
has 'file_name'; # Optional. Original filename as defined by sender
|
||||||
has 'mime_type'; # Optional. MIME type of the file as defined by sender
|
has 'mime_type'; # Optional. MIME type of the file as defined by sender
|
||||||
has 'file_size'; # Optional. File size
|
has 'file_size'; # Optional. File size
|
||||||
has 'thumb'; # Optional. Thumbnail of the album cover to which the music file belongs
|
has 'thumbnail'; # Optional. Thumbnail of the album cover to which the music file belongs
|
||||||
|
|
||||||
sub fields {
|
sub fields {
|
||||||
return { scalar => [qw/file_id file_unique_id duration performer title file_name mime_type
|
return { scalar => [qw/file_id file_unique_id duration performer title file_name mime_type
|
||||||
file_size/],
|
file_size/],
|
||||||
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/],
|
'Teapot::Bot::Object::PhotoSize' => [qw/thumbnail/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ Teapot::Bot::Object::Audio - The base class for Telegram 'Audio' type objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Audio' type objects.
|
The base class for Telegram 'Audio' type objects.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use List::Util qw/any/;
|
|||||||
|
|
||||||
use Mojo::Base -base;
|
use Mojo::Base -base;
|
||||||
|
|
||||||
$Teapot::Bot::Object::Base::VERSION = '0.023';
|
$Teapot::Bot::Object::Base::VERSION = '0.026';
|
||||||
|
|
||||||
has '_brain'; # a reference to our brain
|
has '_brain'; # a reference to our brain
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ Teapot::Bot::Object::Base - The base class for all Telegram::Bot::Object objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use 5.018; ## no critic (ProhibitImplicitImport)
|
|||||||
use utf8;
|
use utf8;
|
||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
$Teapot::Bot::Object::CallbackGame::VERSION = '0.023';
|
$Teapot::Bot::Object::CallbackGame::VERSION = '0.026';
|
||||||
|
|
||||||
# https://core.telegram.org/bots/api#callbackgame
|
# https://core.telegram.org/bots/api#callbackgame
|
||||||
# "A placeholder, currently holds no information. Use BotFather to set up your game"
|
# "A placeholder, currently holds no information. Use BotFather to set up your game"
|
||||||
@@ -30,7 +30,7 @@ Teapot::Bot::Object::CallbackGame - The base class for Telegram message 'Callbac
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'CallbackGame' type.
|
The base class for Telegram message 'CallbackGame' type.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use Teapot::Bot::Object::Message ();
|
|||||||
use Teapot::Bot::Object::ChatPermissions ();
|
use Teapot::Bot::Object::ChatPermissions ();
|
||||||
use Teapot::Bot::Object::ChatLocation ();
|
use Teapot::Bot::Object::ChatLocation ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Chat::VERSION = '0.023';
|
$Teapot::Bot::Object::Chat::VERSION = '0.026';
|
||||||
|
|
||||||
has 'id';
|
has 'id';
|
||||||
has 'type';
|
has 'type';
|
||||||
@@ -20,11 +20,23 @@ has 'title'; # Optional.
|
|||||||
has 'username'; # Optional.
|
has 'username'; # Optional.
|
||||||
has 'first_name'; # Optional.
|
has 'first_name'; # Optional.
|
||||||
has 'last_name'; # Optional.
|
has 'last_name'; # Optional.
|
||||||
|
has 'is_forum'; # Optional. True, if the supergroup chat is a forum (has topics enabled)
|
||||||
has 'photo'; # Teapot::Bot::Object::ChatPhoto. Optional. Returned only in getChat.
|
has 'photo'; # Teapot::Bot::Object::ChatPhoto. Optional. Returned only in getChat.
|
||||||
|
has 'active_usernames'; # Optional. If non-empty, the list of all active chat usernames; for private chats,
|
||||||
|
# supergroups and channels. Returned only in getChat.
|
||||||
|
has 'emoji_status_custom_emoji_id'; # Optional. Custom emoji identifier of emoji status of the other party in a private
|
||||||
|
# chat. Returned only in getChat.
|
||||||
has 'bio'; # Optional. Bio of the other party in a private chat. Returned only in getChat.
|
has 'bio'; # Optional. Bio of the other party in a private chat. Returned only in getChat.
|
||||||
has 'has_private_forwards'; # Optional. True, if privacy settings of the other party in the private chat allows to
|
has 'has_private_forwards'; # Optional. True, if privacy settings of the other party in the private chat allows to
|
||||||
# use tg://user?id=<user_id> links only in chats with the user.
|
# use tg://user?id=<user_id> links only in chats with the user.
|
||||||
# Returned only in getChat.
|
# Returned only in getChat.
|
||||||
|
has 'has_restricted_voice_and_video_messages'; # Optional. True, if the privacy settings of the other party restrict
|
||||||
|
# sending voice and video note messages in the private chat.
|
||||||
|
# Returned only in getChat.
|
||||||
|
has 'join_to_send_messages'; # Optional. True, if users need to join the supergroup before they can send messages.
|
||||||
|
# Returned only in getChat.
|
||||||
|
has 'join_by_request'; # Optional. True, if all users directly joining the supergroup need to be approved by
|
||||||
|
# supergroup administrators. Returned only in getChat.
|
||||||
has 'description'; # Optional. Returned only in getChat.
|
has 'description'; # Optional. Returned only in getChat.
|
||||||
has 'invite_link'; # Optional. Returned only in getChat.
|
has 'invite_link'; # Optional. Returned only in getChat.
|
||||||
has 'pinned_message'; # Teapot::Bot::Object::Message
|
has 'pinned_message'; # Teapot::Bot::Object::Message
|
||||||
@@ -33,6 +45,10 @@ has 'permissions'; # Teapot::Bot::Object::ChatPermissions. Optional
|
|||||||
has 'slow_mode_delay'; # Optional. Returned only in getChat.
|
has 'slow_mode_delay'; # Optional. Returned only in getChat.
|
||||||
has 'message_auto_delete_time'; # Optional. The time after which all messages sent to the chat will be automatically
|
has 'message_auto_delete_time'; # Optional. The time after which all messages sent to the chat will be automatically
|
||||||
# deleted; in seconds. Returned only in getChat.
|
# deleted; in seconds. Returned only in getChat.
|
||||||
|
has 'has_aggressive_anti_spam_enabled'; # Optional. True, if aggressive anti-spam checks are enabled in the supergroup.
|
||||||
|
# The field is only available to chat administrators. Returned only in getChat.
|
||||||
|
has 'has_hidden_members'; # Optional. True, if non-administrators can only get the list of bots and administrators
|
||||||
|
# in the chat. Returned only in getChat.
|
||||||
has 'has_protected_content'; # Optional. True, if messages from the chat can't be forwarded to other chats.
|
has 'has_protected_content'; # Optional. True, if messages from the chat can't be forwarded to other chats.
|
||||||
# Returned only in getChat.
|
# Returned only in getChat.
|
||||||
has 'sticker_set_name'; # Optional. Returned only in getChat.
|
has 'sticker_set_name'; # Optional. Returned only in getChat.
|
||||||
@@ -42,10 +58,14 @@ has 'location'; # Optional. Returned only in getChat.
|
|||||||
|
|
||||||
sub fields {
|
sub fields {
|
||||||
return {
|
return {
|
||||||
'scalar' => [qw/id type title username first_name last_name bio
|
'scalar' => [qw/id type title username first_name last_name is_forum
|
||||||
has_private_forwards description invite_link slow_mode_delay
|
emoji_status_custom_emoji_id bio
|
||||||
message_auto_delete_time has_protected_content
|
has_private_forwards has_restricted_voice_and_video_messages
|
||||||
sticker_set_name can_set_sticker_set linked_chat_id/],
|
join_to_send_messages join_by_request description invite_link
|
||||||
|
slow_mode_delay message_auto_delete_time
|
||||||
|
has_aggressive_anti_spam_enabled has_hidden_members
|
||||||
|
has_protected_content sticker_set_name can_set_sticker_set
|
||||||
|
linked_chat_id/],
|
||||||
'Teapot::Bot::Object::ChatPhoto' => [qw/photo/],
|
'Teapot::Bot::Object::ChatPhoto' => [qw/photo/],
|
||||||
'Teapot::Bot::Object::Message' => [qw/pinned_message/],
|
'Teapot::Bot::Object::Message' => [qw/pinned_message/],
|
||||||
'Teapot::Bot::Object::ChatPermissions' => [qw/permissions/],
|
'Teapot::Bot::Object::ChatPermissions' => [qw/permissions/],
|
||||||
@@ -53,6 +73,9 @@ sub fields {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub arrays {
|
||||||
|
return qw/active_usernames/;
|
||||||
|
}
|
||||||
|
|
||||||
sub is_user {
|
sub is_user {
|
||||||
return shift->id > 0;
|
return shift->id > 0;
|
||||||
@@ -77,7 +100,7 @@ Teapot::Bot::Object::Chat - The base class for Telegram 'Chat' type objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Chat' type objects.
|
The base class for Telegram 'Chat' type objects.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::User ();
|
use Teapot::Bot::Object::User ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::ChatInviteLink::VERSION = '0.023';
|
$Teapot::Bot::Object::ChatInviteLink::VERSION = '0.026';
|
||||||
|
|
||||||
has 'invite_link';
|
has 'invite_link';
|
||||||
has 'creator';
|
has 'creator';
|
||||||
@@ -44,7 +44,7 @@ Teapot::Bot::Object::ChatInviteLink - The base class for Telegram message 'ChatI
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'ChatInviteLink' type.
|
The base class for Telegram message 'ChatInviteLink' type.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::ChatLocation::VERSION = '0.023';
|
$Teapot::Bot::Object::ChatLocation::VERSION = '0.026';
|
||||||
|
|
||||||
has 'location';
|
has 'location';
|
||||||
has 'address';
|
has 'address';
|
||||||
@@ -34,7 +34,7 @@ Teapot::Bot::Object::ChatLocation - The base class for Telegram message 'ChatLoc
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'ChatLocation' type.
|
The base class for Telegram message 'ChatLocation' type.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use Mojo::Base 'Teapot::Bot::Object::Base';
|
|||||||
use Teapot::Bot::Object::User ();
|
use Teapot::Bot::Object::User ();
|
||||||
|
|
||||||
|
|
||||||
$Teapot::Bot::Object::ChatMember::VERSION = '0.023';
|
$Teapot::Bot::Object::ChatMember::VERSION = '0.026';
|
||||||
|
|
||||||
# ChatMemberOwner
|
# ChatMemberOwner
|
||||||
has 'user';
|
has 'user';
|
||||||
@@ -39,7 +39,8 @@ has 'can_promote_members'; # optional. Administrators only.
|
|||||||
has 'can_change_info'; # optional. Administrators and restricted only.
|
has 'can_change_info'; # optional. Administrators and restricted only.
|
||||||
has 'can_invite_users'; # optional. Administrators and restricted only.
|
has 'can_invite_users'; # optional. Administrators and restricted only.
|
||||||
has 'can_pin_messages'; # optional. Administrators and restricted only.
|
has 'can_pin_messages'; # optional. Administrators and restricted only.
|
||||||
|
has 'can_manage_topics'; # Optional. True, if the user is allowed to create, rename, close, and reopen forum
|
||||||
|
# topics; supergroups only
|
||||||
# ChatMemberMember
|
# ChatMemberMember
|
||||||
# has 'status';
|
# has 'status';
|
||||||
# has 'user';
|
# has 'user';
|
||||||
@@ -52,11 +53,17 @@ has 'is_member'; # optional. Restricted only.
|
|||||||
# has 'can_invite_users'; # optional. Administrators and restricted only.
|
# has 'can_invite_users'; # optional. Administrators and restricted only.
|
||||||
# has 'can_pin_messages'; # optional. Administrators and restricted only.
|
# has 'can_pin_messages'; # optional. Administrators and restricted only.
|
||||||
has 'can_send_messages'; # optional. Restricted only.
|
has 'can_send_messages'; # optional. Restricted only.
|
||||||
has 'can_send_media_messages'; # optional. Restricted only.
|
has 'can_send_audios';
|
||||||
|
has 'can_send_documents';
|
||||||
|
has 'can_send_photos';
|
||||||
|
has 'can_send_videos';
|
||||||
|
has 'can_send_video_notes';
|
||||||
|
has 'can_send_voice_notes';
|
||||||
has 'can_send_polls'; # optional. Restricted only.
|
has 'can_send_polls'; # optional. Restricted only.
|
||||||
has 'can_send_other_messages'; # optional. Restricted only.
|
has 'can_send_other_messages'; # optional. Restricted only.
|
||||||
has 'can_add_web_page_previews'; # optional. Restricted only.
|
has 'can_add_web_page_previews'; # optional. Restricted only.
|
||||||
has 'until_date'; # optional. Restricted and kicked only.
|
has 'until_date'; # optional. Restricted and kicked only.
|
||||||
|
# has 'can_manage_topics';
|
||||||
|
|
||||||
# ChatMemberLeft
|
# ChatMemberLeft
|
||||||
# has 'status';
|
# has 'status';
|
||||||
@@ -69,11 +76,14 @@ has 'until_date'; # optional. Restricted and kicked only.
|
|||||||
|
|
||||||
sub fields {
|
sub fields {
|
||||||
return {
|
return {
|
||||||
'scalar' => [qw/status custom_title is_anonymous can_be_edited can_manage_chat can_post_messages
|
'scalar' => [qw/status custom_title is_anonymous can_be_edited can_manage_chat
|
||||||
can_edit_messages can_delete_messages can_manage_voice_chats can_restrict_members
|
can_post_messages can_edit_messages can_delete_messages
|
||||||
can_promote_members can_change_info can_invite_users can_pin_messages is_member
|
can_manage_voice_chats can_restrict_members can_promote_members
|
||||||
can_send_messages can_send_media_messages can_send_polls can_send_other_messages
|
can_change_info can_invite_users can_pin_messages is_member
|
||||||
can_add_web_page_previews until_date/],
|
can_send_messages can_send_audios can_send_documents can_send_photos
|
||||||
|
can_send_videos can_send_video_notes can_send_voice_notes can_send_polls
|
||||||
|
can_send_other_messagescan_add_web_page_previews until_date
|
||||||
|
can_manage_topics/],
|
||||||
'Teapot::Bot::Object::User' => [qw/user/],
|
'Teapot::Bot::Object::User' => [qw/user/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -145,7 +155,7 @@ Teapot::Bot::Object::ChatMember - The base class for Telegram 'ChatMember' type
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'ChatMember' type objects.
|
The base class for Telegram 'ChatMember' type objects.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use Teapot::Bot::Object::ChatMember ();
|
|||||||
use Teapot::Bot::Object::ChatInviteLink ();
|
use Teapot::Bot::Object::ChatInviteLink ();
|
||||||
use Teapot::Bot::Object::Voice ();
|
use Teapot::Bot::Object::Voice ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::ChatMemberUpdated::VERSION = '0.023';
|
$Teapot::Bot::Object::ChatMemberUpdated::VERSION = '0.026';
|
||||||
|
|
||||||
has 'chat';
|
has 'chat';
|
||||||
has 'from';
|
has 'from';
|
||||||
@@ -50,7 +50,7 @@ Teapot::Bot::Object::ChatMemberUpdated - The base class for Telegram 'ChatMember
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'ChatMemberUpdated' type objects.
|
The base class for Telegram 'ChatMemberUpdated' type objects.
|
||||||
|
|||||||
@@ -10,13 +10,17 @@ use Carp qw(carp);
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Brain ();
|
use Teapot::Bot::Brain ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::ChatPermissions::VERSION = '0.023';
|
$Teapot::Bot::Object::ChatPermissions::VERSION = '0.026';
|
||||||
|
|
||||||
# all fields are optional
|
# all fields are optional
|
||||||
# N.B. Some of the fields "overlaps" other, so in order to guess valid set of permissions you should check all of them
|
# N.B. Some of the fields "overlaps" other, so in order to guess valid set of permissions you should check all of them
|
||||||
has 'can_send_messages'; # True, if the user is allowed to send text messages, contacts, locations and venues
|
has 'can_send_messages'; # True, if the user is allowed to send text messages, contacts, locations and venues
|
||||||
has 'can_send_media_messages'; # True, if the user is allowed to send audios, documents, photos, videos, video notes
|
has 'can_send_audios'; # True, if the user is allowed to send audios
|
||||||
# and voice notes, implies can_send_messages
|
has 'can_send_documents'; # True, if the user is allowed to send documents
|
||||||
|
has 'can_send_photos'; # True, if the user is allowed to send photos
|
||||||
|
has 'can_send_videos'; # True, if the user is allowed to send videos
|
||||||
|
has 'can_send_video_notes'; # True, if the user is allowed to send video_notes
|
||||||
|
has 'can_send_voice_notes'; # True, if the user is allowed to send voice_notes
|
||||||
has 'can_send_polls'; # True, if the user is allowed to send polls, implies can_send_messages
|
has 'can_send_polls'; # True, if the user is allowed to send polls, implies can_send_messages
|
||||||
has 'can_send_other_messages'; # True, if the user is allowed to send animations, games, stickers and use inline bots,
|
has 'can_send_other_messages'; # True, if the user is allowed to send animations, games, stickers and use inline bots,
|
||||||
# implies can_send_media_messages
|
# implies can_send_media_messages
|
||||||
@@ -26,21 +30,52 @@ has 'can_change_info'; # True, if the user is allowed to change the ch
|
|||||||
# Ignored in public supergroups
|
# Ignored in public supergroups
|
||||||
has 'can_invite_users'; # True, if the user is allowed to invite new users to the chat
|
has 'can_invite_users'; # True, if the user is allowed to invite new users to the chat
|
||||||
has 'can_pin_messages'; # True, if the user is allowed to pin messages. Ignored in public supergroups
|
has 'can_pin_messages'; # True, if the user is allowed to pin messages. Ignored in public supergroups
|
||||||
|
has 'can_manage_topics'; # Optional. True, if the user is allowed to create forum topics. If omitted defaults to
|
||||||
|
# the value of can_pin_messages
|
||||||
|
|
||||||
sub fields {
|
sub fields {
|
||||||
return {
|
return {
|
||||||
'scalar' => [qw/can_send_messages can_send_media_messages can_send_polls
|
'scalar' => [qw/can_send_messages can_send_audios can_send_documents
|
||||||
can_send_other_messages can_add_web_page_previews can_change_info
|
can_send_photos can_send_videos can_send_video_notes
|
||||||
can_invite_users can_pin_messages/],
|
can_send_voice_notes can_send_polls can_send_other_messages
|
||||||
|
can_add_web_page_previews can_change_info can_invite_users
|
||||||
|
can_pin_messages can_manage_topics/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub canTalk {
|
sub canTalk {
|
||||||
my $self = shift;
|
my $self;
|
||||||
|
my $args = {};
|
||||||
|
|
||||||
|
# There is some magic happen if we call function as object, as we usually do here
|
||||||
|
# But if we access function from usual-style wrapper that calls it directly from namespace it supply noy $self object
|
||||||
|
# but string with its name, which is a bummer.
|
||||||
|
while (my $o = shift @_) {
|
||||||
|
if (ref ($o) ne '') {
|
||||||
|
$self = $o;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $chatid = shift;
|
my $chatid = shift;
|
||||||
|
|
||||||
my $args->{chat_id} = $chatid;
|
$args->{chat_id} = $chatid;
|
||||||
my $can_talk = 0;
|
my $can_talk = 0;
|
||||||
|
my $ret;
|
||||||
|
|
||||||
|
if (! defined($self->token) || $self->token eq '') {
|
||||||
|
$ret->{error} = 1;
|
||||||
|
$ret->{message} = 'No token supplied to canTalk()';
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
unless ($args->{chat_id}) {
|
||||||
|
$ret->{error} = 1;
|
||||||
|
$ret->{message} = 'No chat_id supplied to canTalk()';
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
if ($chatid < 0) {
|
if ($chatid < 0) {
|
||||||
# group chat
|
# group chat
|
||||||
@@ -48,16 +83,23 @@ sub canTalk {
|
|||||||
|
|
||||||
# on api error, keep silence
|
# on api error, keep silence
|
||||||
if ($chatobj == 0 || $chatobj->{error}) {
|
if ($chatobj == 0 || $chatobj->{error}) {
|
||||||
carp "Unable to get chat info for $chatid from telegram API";
|
my $emesg = "Unable to get chat info for $chatid from telegram API";
|
||||||
return $can_talk;
|
$ret->{message} = $emesg;
|
||||||
|
$ret->{error} = 1;
|
||||||
|
$ret->{can_talk} = 0;
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $myObj = Teapot::Bot::Brain->getMe ($self);
|
my $myObj = Teapot::Bot::Brain->getMe ($self);
|
||||||
|
|
||||||
# on api error, keep silence
|
# on api error, keep silence
|
||||||
if ($myObj == 0 || $myObj->{error}) {
|
if ($myObj == 0 || $myObj->{error}) {
|
||||||
carp "Unable to get chat info for $chatid from telegram API";
|
my $emesg = "Unable to get chat info for $chatid from telegram API";
|
||||||
return $can_talk;
|
$ret->{message} = $emesg;
|
||||||
|
$ret->{error} = 1;
|
||||||
|
$ret->{can_talk} = 0;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $myid = $myObj->id;
|
my $myid = $myObj->id;
|
||||||
@@ -66,8 +108,12 @@ sub canTalk {
|
|||||||
|
|
||||||
# on api error, keep silence
|
# on api error, keep silence
|
||||||
if ($me == 0 || $me->{error}) {
|
if ($me == 0 || $me->{error}) {
|
||||||
carp 'Unable to get chat info for bot itself from telegram API';
|
my $emesg = 'Unable to get chat info for bot itself from telegram API';
|
||||||
return $can_talk;
|
$ret->{message} = $emesg;
|
||||||
|
$ret->{error} = 1;
|
||||||
|
$ret->{can_talk} = 0;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($me->{'status'} eq 'administrator') {
|
if ($me->{'status'} eq 'administrator') {
|
||||||
@@ -81,9 +127,13 @@ sub canTalk {
|
|||||||
$can_talk = 1;
|
$can_talk = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $can_talk;
|
$ret->{error} = 0;
|
||||||
|
$ret->{can_talk} = $can_talk;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
@@ -98,7 +148,7 @@ Teapot::Bot::Object::ChatPermissions - The base class for Telegram 'ChatPermissi
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'ChatPermissions' type objects.
|
The base class for Telegram 'ChatPermissions' type objects.
|
||||||
@@ -112,7 +162,9 @@ attributes available for C<Teapot::Bot::Object::ChatPermissions> objects.
|
|||||||
|
|
||||||
A convenience method to check if bot can talk in given conversation.
|
A convenience method to check if bot can talk in given conversation.
|
||||||
|
|
||||||
Returns true if the bot can talk in given conversation, otherwise false.
|
Returns hash reference with can_talk true if the bot can talk in given conversation, otherwise false.
|
||||||
|
Also set field error 1 if an error occurs during api interaction.
|
||||||
|
And if error set to true message field also set plus can_talk set to false.
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::ChatPhoto::VERSION = '0.023';
|
$Teapot::Bot::Object::ChatPhoto::VERSION = '0.026';
|
||||||
|
|
||||||
has 'small_file_id';
|
has 'small_file_id';
|
||||||
has 'small_file_unique_id';
|
has 'small_file_unique_id';
|
||||||
@@ -35,7 +35,7 @@ Teapot::Bot::Object::ChatPhoto - The base class for Telegram 'ChatPhoto' type ob
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'ChatPhoto' type objects.
|
The base class for Telegram 'ChatPhoto' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::Contact::VERSION = '0.023';
|
$Teapot::Bot::Object::Contact::VERSION = '0.026';
|
||||||
|
|
||||||
has 'phone_number';
|
has 'phone_number';
|
||||||
has 'first_name';
|
has 'first_name';
|
||||||
@@ -36,7 +36,7 @@ Teapot::Bot::Object::Contact - The base class for Telegram 'Contact' objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Contact' objects.
|
The base class for Telegram 'Contact' objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::Dice::VERSION = '0.023';
|
$Teapot::Bot::Object::Dice::VERSION = '0.026';
|
||||||
|
|
||||||
has 'emoji';
|
has 'emoji';
|
||||||
has 'value';
|
has 'value';
|
||||||
@@ -31,7 +31,7 @@ Teapot::Bot::Object::Dice - The base class for Telegram message 'Dice' type
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'Dice' type.
|
The base class for Telegram message 'Dice' type.
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::PhotoSize ();
|
use Teapot::Bot::Object::PhotoSize ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Document::VERSION = '0.023';
|
$Teapot::Bot::Object::Document::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
has 'thumb'; #PhotoSize
|
has 'thumbnail'; #PhotoSize
|
||||||
has 'file_name';
|
has 'file_name';
|
||||||
has 'mime_type';
|
has 'mime_type';
|
||||||
has 'file_size';
|
has 'file_size';
|
||||||
@@ -21,7 +21,7 @@ has 'file_size';
|
|||||||
sub fields {
|
sub fields {
|
||||||
return {
|
return {
|
||||||
scalar => [qw/file_id file_unique_id file_name mime_type file_size/],
|
scalar => [qw/file_id file_unique_id file_name mime_type file_size/],
|
||||||
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/],
|
'Teapot::Bot::Object::PhotoSize' => [qw/thumbnail/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ Teapot::Bot::Object::Document - The base class for Telegram 'Document' objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Document' objects.
|
The base class for Telegram 'Document' objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::EncryptedCredentials::VERSION = '0.023';
|
$Teapot::Bot::Object::EncryptedCredentials::VERSION = '0.026';
|
||||||
|
|
||||||
has 'data';
|
has 'data';
|
||||||
has 'hash';
|
has 'hash';
|
||||||
@@ -32,7 +32,7 @@ Teapot::Bot::Object::EncryptedCredentials - The base class for Telegram 'Encrypt
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'EncryptedCredentials' type objects.
|
The base class for Telegram 'EncryptedCredentials' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::EncryptedPassportElement::VERSION = '0.023';
|
$Teapot::Bot::Object::EncryptedPassportElement::VERSION = '0.026';
|
||||||
|
|
||||||
# XXX Implement rest of this
|
# XXX Implement rest of this
|
||||||
# https://core.telegram.org/bots/api#encryptedpassportelement
|
# https://core.telegram.org/bots/api#encryptedpassportelement
|
||||||
@@ -38,7 +38,7 @@ Teapot::Bot::Object::EncryptedPassportElement - The base class for Telegram 'Enc
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'EncryptedPassportElement' type objects.
|
The base class for Telegram 'EncryptedPassportElement' type objects.
|
||||||
|
|||||||
51
lib/Teapot/Bot/Object/ForumTopicClosed.pm
Normal file
51
lib/Teapot/Bot/Object/ForumTopicClosed.pm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package Teapot::Bot::Object::ForumTopicClosed;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'ForumTopicClosed' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::ForumTopicClosed::VERSION = '0.026';
|
||||||
|
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::ForumTopicClosed - The base class for Telegram message 'ForumTopicClosed' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'ForumTopicClosed' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#forumtopicclosed> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::ForumTopicClosed> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2022 by Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
54
lib/Teapot/Bot/Object/ForumTopicCreated.pm
Normal file
54
lib/Teapot/Bot/Object/ForumTopicCreated.pm
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package Teapot::Bot::Object::ForumTopicCreated;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'ForumTopicCreated' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::ForumTopicCreated::VERSION = '0.026';
|
||||||
|
|
||||||
|
has 'name';
|
||||||
|
has 'icon_color';
|
||||||
|
has 'icon_custom_emoji_id';
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return { scalar => [qw/name icon_color icon_custom_emoji_id/] };
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::ForumTopicCreated - The base class for Telegram message 'ForumTopicCreated' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'ForumTopicCreated' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#forumtopiccreated> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::ForumTopicCreated> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2022 by Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
55
lib/Teapot/Bot/Object/ForumTopicEdited.pm
Normal file
55
lib/Teapot/Bot/Object/ForumTopicEdited.pm
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package Teapot::Bot::Object::ForumTopicEdited;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'ForumTopicEdited' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::ForumTopicEdited::VERSION = '0.026';
|
||||||
|
|
||||||
|
has 'name';
|
||||||
|
has 'icon_custom_emoji_id';
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return {
|
||||||
|
'scalar' => [qw/name icon_custom_emoji_id/],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::ForumTopicEdited - The base class for Telegram message 'ForumTopicEdited' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'ForumTopicEdited' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#forumtopicedited> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::ForumTopicEdited> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2023 by Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
51
lib/Teapot/Bot/Object/ForumTopicReopened.pm
Normal file
51
lib/Teapot/Bot/Object/ForumTopicReopened.pm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package Teapot::Bot::Object::ForumTopicReopened;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'ForumTopicReopened' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::ForumTopicReopened::VERSION = '0.026';
|
||||||
|
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::ForumTopicReopened - The base class for Telegram message 'ForumTopicReopened' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'ForumTopicReopened' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#forumtopicreopened> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::ForumTopicReopened> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2022 by Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
@@ -11,7 +11,7 @@ use Teapot::Bot::Object::PhotoSize ();
|
|||||||
use Teapot::Bot::Object::Animation ();
|
use Teapot::Bot::Object::Animation ();
|
||||||
use Teapot::Bot::Object::MessageEntity ();
|
use Teapot::Bot::Object::MessageEntity ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Game::VERSION = '0.023';
|
$Teapot::Bot::Object::Game::VERSION = '0.026';
|
||||||
|
|
||||||
has 'title';
|
has 'title';
|
||||||
has 'description';
|
has 'description';
|
||||||
@@ -45,7 +45,7 @@ Teapot::Bot::Object::Game - The base class for Telegram message 'Game' type
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'Game' type.
|
The base class for Telegram message 'Game' type.
|
||||||
|
|||||||
51
lib/Teapot/Bot/Object/GeneralForumTopicHidden.pm
Normal file
51
lib/Teapot/Bot/Object/GeneralForumTopicHidden.pm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package Teapot::Bot::Object::GeneralForumTopicHidden;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'GeneralForumTopicHidden' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::GeneralForumTopicHidden::VERSION = '0.026';
|
||||||
|
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::GeneralForumTopicHidden - The base class for Telegram message 'GeneralForumTopicHidden' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'GeneralForumTopicHidden' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#generalforumtopichidden> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::GeneralForumTopicHidden> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2023 by Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
51
lib/Teapot/Bot/Object/GeneralForumTopicUnhidden.pm
Normal file
51
lib/Teapot/Bot/Object/GeneralForumTopicUnhidden.pm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package Teapot::Bot::Object::GeneralForumTopicUnhidden;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'GeneralForumTopicUnhidden' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::GeneralForumTopicUnhidden::VERSION = '0.026';
|
||||||
|
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::GeneralForumTopicUnhidden - The base class for Telegram message 'GeneralForumTopicUnhidden' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'GeneralForumTopicUnhidden' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#generalforumtopicunhidden> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::GeneralForumTopicUnhidden> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2023 by Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
@@ -10,7 +10,7 @@ use Mojo::Base 'Teapot::Bot::Object::Base';
|
|||||||
use Teapot::Bot::Object::LoginUrl ();
|
use Teapot::Bot::Object::LoginUrl ();
|
||||||
use Teapot::Bot::Object::CallbackGame ();
|
use Teapot::Bot::Object::CallbackGame ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::InlineKeyboardButton::VERSION = '0.023';
|
$Teapot::Bot::Object::InlineKeyboardButton::VERSION = '0.026';
|
||||||
|
|
||||||
has 'text';
|
has 'text';
|
||||||
has 'url';
|
has 'url';
|
||||||
@@ -43,7 +43,7 @@ Teapot::Bot::Object::InlineKeyboardButton - The base class for Telegram 'InlineK
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'InlineKeyboardButton' type objects.
|
The base class for Telegram 'InlineKeyboardButton' type objects.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::InlineKeyboardButton ();
|
use Teapot::Bot::Object::InlineKeyboardButton ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::InlineKeyboardMarkup::VERSION = '0.023';
|
$Teapot::Bot::Object::InlineKeyboardMarkup::VERSION = '0.026';
|
||||||
|
|
||||||
has 'inline_keyboard';
|
has 'inline_keyboard';
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ Teapot::Bot::Object::InlineKeyboardMarkup - The base class for Telegram 'InlineK
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'InlineKeyboardMarkup' type objects.
|
The base class for Telegram 'InlineKeyboardMarkup' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::Invoice::VERSION = '0.023';
|
$Teapot::Bot::Object::Invoice::VERSION = '0.026';
|
||||||
|
|
||||||
has 'title';
|
has 'title';
|
||||||
has 'description';
|
has 'description';
|
||||||
@@ -34,7 +34,7 @@ Teapot::Bot::Object::Invoice - The base class for Telegram 'Invoice' type object
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Invoice' type objects.
|
The base class for Telegram 'Invoice' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::Location::VERSION = '0.023';
|
$Teapot::Bot::Object::Location::VERSION = '0.026';
|
||||||
|
|
||||||
has 'longitude';
|
has 'longitude';
|
||||||
has 'latitude';
|
has 'latitude';
|
||||||
@@ -35,7 +35,7 @@ Teapot::Bot::Object::Location - The base class for Telegram message 'Location' t
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'Location' type.
|
The base class for Telegram message 'Location' type.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::LoginUrl::VERSION = '0.023';
|
$Teapot::Bot::Object::LoginUrl::VERSION = '0.026';
|
||||||
|
|
||||||
has 'url';
|
has 'url';
|
||||||
has 'forward_text';
|
has 'forward_text';
|
||||||
@@ -33,7 +33,7 @@ Teapot::Bot::Object::LoginUrl - The base class for Telegram 'LoginUrl' type obje
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'LoginUrl' type objects.
|
The base class for Telegram 'LoginUrl' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::MaskPosition::VERSION = '0.023';
|
$Teapot::Bot::Object::MaskPosition::VERSION = '0.026';
|
||||||
|
|
||||||
has 'point';
|
has 'point';
|
||||||
has 'x_shift';
|
has 'x_shift';
|
||||||
@@ -33,7 +33,7 @@ Teapot::Bot::Object::MaskPosition - The base class for Telegram 'MaskPosition' t
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'MaskPosition' type objects.
|
The base class for Telegram 'MaskPosition' type objects.
|
||||||
|
|||||||
@@ -30,7 +30,14 @@ use Teapot::Bot::Object::PhotoSize ();
|
|||||||
use Teapot::Bot::Object::Invoice ();
|
use Teapot::Bot::Object::Invoice ();
|
||||||
use Teapot::Bot::Object::Venue ();
|
use Teapot::Bot::Object::Venue ();
|
||||||
use Teapot::Bot::Object::SuccessfulPayment ();
|
use Teapot::Bot::Object::SuccessfulPayment ();
|
||||||
|
use Teapot::Bot::Object::WriteAccessAllowed ();
|
||||||
use Teapot::Bot::Object::PassportData ();
|
use Teapot::Bot::Object::PassportData ();
|
||||||
|
use Teapot::Bot::Object::ForumTopicCreated ();
|
||||||
|
use Teapot::Bot::Object::ForumTopicEdited ();
|
||||||
|
use Teapot::Bot::Object::ForumTopicClosed ();
|
||||||
|
use Teapot::Bot::Object::ForumTopicReopened ();
|
||||||
|
use Teapot::Bot::Object::GeneralForumTopicHidden ();
|
||||||
|
use Teapot::Bot::Object::GeneralForumTopicUnhidden ();
|
||||||
use Teapot::Bot::Object::InlineKeyboardMarkup ();
|
use Teapot::Bot::Object::InlineKeyboardMarkup ();
|
||||||
use Teapot::Bot::Object::ProximityAlertTriggered ();
|
use Teapot::Bot::Object::ProximityAlertTriggered ();
|
||||||
use Teapot::Bot::Object::Dice ();
|
use Teapot::Bot::Object::Dice ();
|
||||||
@@ -40,10 +47,12 @@ use Teapot::Bot::Object::VideoChatStarted ();
|
|||||||
use Teapot::Bot::Object::VideoChatEnded ();
|
use Teapot::Bot::Object::VideoChatEnded ();
|
||||||
use Teapot::Bot::Object::VideoChatParticipantsInvited ();
|
use Teapot::Bot::Object::VideoChatParticipantsInvited ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Message::VERSION = '0.023';
|
$Teapot::Bot::Object::Message::VERSION = '0.026';
|
||||||
|
|
||||||
# basic message stuff
|
# basic message stuff
|
||||||
has 'message_id';
|
has 'message_id';
|
||||||
|
has 'message_thread_id'; # Optional. Unique identifier of a message thread to which the message belongs;
|
||||||
|
# for supergroups only
|
||||||
has 'from'; # User
|
has 'from'; # User
|
||||||
has 'sender_chat'; # Chat
|
has 'sender_chat'; # Chat
|
||||||
has 'date';
|
has 'date';
|
||||||
@@ -54,6 +63,7 @@ has 'forward_from_message_id';
|
|||||||
has 'forward_signature';
|
has 'forward_signature';
|
||||||
has 'forward_sender_name';
|
has 'forward_sender_name';
|
||||||
has 'forward_date';
|
has 'forward_date';
|
||||||
|
has 'is_topic_message'; # Optional. True, if the message is sent to a forum topic
|
||||||
has 'is_automatic_forward';
|
has 'is_automatic_forward';
|
||||||
has 'reply_to_message'; # Message
|
has 'reply_to_message'; # Message
|
||||||
has 'via_bot'; # User
|
has 'via_bot'; # User
|
||||||
@@ -73,6 +83,7 @@ has 'video_note'; # VideoNote
|
|||||||
has 'voice'; # Voice
|
has 'voice'; # Voice
|
||||||
has 'caption';
|
has 'caption';
|
||||||
has 'caption_entities'; # Array of MessageEntity
|
has 'caption_entities'; # Array of MessageEntity
|
||||||
|
has 'has_media_spoiler';
|
||||||
has 'contact'; # Contact
|
has 'contact'; # Contact
|
||||||
has 'dice';
|
has 'dice';
|
||||||
has 'game';
|
has 'game';
|
||||||
@@ -94,8 +105,15 @@ has 'pinned_message'; # Message
|
|||||||
has 'invoice'; # Invoice
|
has 'invoice'; # Invoice
|
||||||
has 'successful_payment'; # SuccessfulPayment
|
has 'successful_payment'; # SuccessfulPayment
|
||||||
has 'connected_website';
|
has 'connected_website';
|
||||||
|
has 'write_access_allowed'; # WriteAccessAllowed
|
||||||
has 'passport_data'; # PassportData
|
has 'passport_data'; # PassportData
|
||||||
has 'proximity_alert_triggered';
|
has 'proximity_alert_triggered';
|
||||||
|
has 'forum_topic_created'; # ForumTopicCreated
|
||||||
|
has 'forum_topic_edited'; # ForumTopicEdited
|
||||||
|
has 'forum_topic_closed'; # ForumTopicClosed
|
||||||
|
has 'forum_topic_reopened'; # ForumTopicReopened
|
||||||
|
has 'general_forum_topic_hidden'; # GeneralForumTopicHidden
|
||||||
|
has 'general_forum_topic_unhidden'; # GeneralForumTopicUnhidden
|
||||||
has 'video_chat_scheduled';
|
has 'video_chat_scheduled';
|
||||||
has 'video_chat_started';
|
has 'video_chat_started';
|
||||||
has 'video_chat_ended';
|
has 'video_chat_ended';
|
||||||
@@ -105,11 +123,11 @@ has 'reply_markup'; # Array of InlineKeyboardMarkup
|
|||||||
|
|
||||||
sub fields {
|
sub fields {
|
||||||
return {
|
return {
|
||||||
'scalar' => [qw/message_id date forward_from_message_id
|
'scalar' => [qw/message_id message_thread_id date forward_from_message_id
|
||||||
forward_signature forward_sender_name
|
forward_signature forward_sender_name forward_date
|
||||||
forward_date is_automatic_forward edit_date has_protected_content
|
is_topic_message is_automatic_forward edit_date
|
||||||
media_group_id author_signature text caption
|
has_protected_content media_group_id author_signature text
|
||||||
new_chat_title delete_chat_photo
|
caption has_media_spoiler new_chat_title delete_chat_photo
|
||||||
group_chat_created supergroup_chat_created
|
group_chat_created supergroup_chat_created
|
||||||
channel_chat_created migrate_to_chat_id
|
channel_chat_created migrate_to_chat_id
|
||||||
migrate_from_chat_id connected_website/],
|
migrate_from_chat_id connected_website/],
|
||||||
@@ -137,15 +155,22 @@ sub fields {
|
|||||||
|
|
||||||
'Teapot::Bot::Object::Invoice' => [qw/invoice/],
|
'Teapot::Bot::Object::Invoice' => [qw/invoice/],
|
||||||
'Teapot::Bot::Object::SuccessfulPayment' => [qw/successful_payment/],
|
'Teapot::Bot::Object::SuccessfulPayment' => [qw/successful_payment/],
|
||||||
|
'Teapot::Bot::Object::WriteAccessAllowed' => [qw/write_access_allowed/],
|
||||||
'Teapot::Bot::Object::PassportData' => [qw/passport_data/],
|
'Teapot::Bot::Object::PassportData' => [qw/passport_data/],
|
||||||
|
'Teapot::Bot::Object::ForumTopicCreated' => [qw/forum_topic_created/],
|
||||||
|
'Teapot::Bot::Object::ForumTopicEdited' => [qw/forum_topic_edited/],
|
||||||
|
'Teapot::Bot::Object::ForumTopicClosed' => [qw/forum_topic_closed/],
|
||||||
|
'Teapot::Bot::Object::ForumTopicReopened' => [qw/forum_topic_reopened/],
|
||||||
|
'Teapot::Bot::Object::GeneralForumTopicHidden' => [qw/general_forum_topic_unhidden/],
|
||||||
|
'Teapot::Bot::Object::GeneralForumTopicUnhidden' => [qw/general_forum_topic_unhidden/],
|
||||||
'Teapot::Bot::Object::InlineKeyboardMarkup' => [qw/reply_markup/],
|
'Teapot::Bot::Object::InlineKeyboardMarkup' => [qw/reply_markup/],
|
||||||
'Teapot::Bot::Object::ProximityAlertTriggered' => [qw/proximity_alert_triggered/],
|
'Teapot::Bot::Object::ProximityAlertTriggered' => [qw/proximity_alert_triggered/],
|
||||||
'Teapot::Bot::Object::Dice' => [qw/dice/],
|
'Teapot::Bot::Object::Dice' => [qw/dice/],
|
||||||
'Teapot::Bot::Object::MessageAutoDeleteTimerChanged' => [qw/message_auto_delete_timer_changed/],
|
'Teapot::Bot::Object::MessageAutoDeleteTimerChanged' => [qw/message_auto_delete_timer_changed/],
|
||||||
'Teapot::Bot::Object::VideoChatScheduled' => [qw/voice_chat_scheduled/],
|
'Teapot::Bot::Object::VideoChatScheduled' => [qw/video_chat_scheduled/],
|
||||||
'Teapot::Bot::Object::VideoChatStarted' => [qw/voice_chat_started/],
|
'Teapot::Bot::Object::VideoChatStarted' => [qw/video_chat_started/],
|
||||||
'Teapot::Bot::Object::VideoChatEnded' => [qw/voice_chat_ended/],
|
'Teapot::Bot::Object::VideoChatEnded' => [qw/video_chat_ended/],
|
||||||
'Teapot::Bot::Object::VideoChatParticipantsInvited' => [qw/voice_chat_participants_invited/],
|
'Teapot::Bot::Object::VideoChatParticipantsInvited' => [qw/video_chat_participants_invited/],
|
||||||
'Teapot::Bot::Object::WebAppData' => [qw/web_app_data/],
|
'Teapot::Bot::Object::WebAppData' => [qw/web_app_data/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -154,48 +179,76 @@ sub arrays {
|
|||||||
return qw/photo entities caption_entities new_chat_members new_chat_photo/;
|
return qw/photo entities caption_entities new_chat_members new_chat_photo/;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub reply {
|
sub reply {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $text = shift;
|
my $text = shift;
|
||||||
|
|
||||||
my $chatid = $self->chat->id;
|
my $ret = '';
|
||||||
|
|
||||||
if (Teapot::Bot::Object::ChatPermissions->canTalk($self, $chatid)) {
|
my $send_args->{chat_id} = $self->chat->id;
|
||||||
return $self->_brain->sendMessage({chat_id => $chatid, text => $text});
|
my $message_thread_id = eval {$self->message_thread_id};
|
||||||
|
|
||||||
|
my $can_talk = $self->_brain->can_talk($send_args);
|
||||||
|
|
||||||
|
if ($can_talk->{error}) {
|
||||||
|
$ret = $can_talk;
|
||||||
|
} else {
|
||||||
|
if ($can_talk->{can_talk}) {
|
||||||
|
$send_args->{text} = $text;
|
||||||
|
|
||||||
|
if (defined $message_thread_id && $message_thread_id ne '') {
|
||||||
|
$send_args->{$message_thread_id} = $message_thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {'error' => 1};
|
$ret = $self->_brain->sendMessage($send_args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub replyMd {
|
sub replyMd {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $text = shift;
|
my $text = shift;
|
||||||
|
|
||||||
my $chatid = $self->chat->id;
|
my $ret = '';
|
||||||
|
|
||||||
if (Teapot::Bot::Object::ChatPermissions->canTalk ($self, $chatid)) {
|
my $send_args->{chat_id} = $self->chat->id;
|
||||||
my $send_args;
|
my $message_thread_id = eval {$self->message_thread_id};
|
||||||
|
|
||||||
|
my $can_talk = $self->_brain->can_talk($send_args);
|
||||||
|
|
||||||
|
if ($can_talk->{error}) {
|
||||||
|
$ret = $can_talk;
|
||||||
|
} else {
|
||||||
|
if ($can_talk->{can_talk}) {
|
||||||
$send_args->{text} = $text;
|
$send_args->{text} = $text;
|
||||||
$send_args->{parse_mode} = 'Markdown';
|
$send_args->{parse_mode} = 'Markdown';
|
||||||
$send_args->{chat_id} = $chatid;
|
$send_args->{message_thread_id} = $message_thread_id if (defined $message_thread_id);
|
||||||
|
|
||||||
return $self->_brain->sendMessage($send_args);
|
$ret = $self->_brain->sendMessage($send_args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {'error' => 1};
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub typing {
|
sub typing {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
my $chatid = $self->chat->id;
|
my $ret = '';
|
||||||
|
my $send_args->{chat_id} = $self->chat->id;
|
||||||
|
my $can_talk = $self->_brain->can_talk($send_args);
|
||||||
|
|
||||||
if (Teapot::Bot::Object::ChatPermissions->canTalk ($self, $chatid)) {
|
if ($can_talk->{error}) {
|
||||||
return $self->_brain->sendChatAction({chat_id => $chatid});
|
$ret = $can_talk;
|
||||||
|
} else {
|
||||||
|
if ($can_talk->{can_talk}) {
|
||||||
|
$ret = $self->_brain->sendChatAction($send_args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {'error' => 1};
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
@@ -212,7 +265,7 @@ Teapot::Bot::Object::Message - The base class for the Telegram type "Message"
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for the Telegram type "Message".
|
The base class for the Telegram type "Message".
|
||||||
@@ -228,6 +281,9 @@ A convenience method to reply to a message with text.
|
|||||||
|
|
||||||
Will return the C<Teapot::Bot::Object::Message> object representing the message
|
Will return the C<Teapot::Bot::Object::Message> object representing the message
|
||||||
sent.
|
sent.
|
||||||
|
On error returns hash reference with error field set to 1, also set fields
|
||||||
|
param, url and debug (which is result of Mojo::UserAgent->post->result->json)
|
||||||
|
|
||||||
|
|
||||||
=head2 replyMd
|
=head2 replyMd
|
||||||
|
|
||||||
@@ -235,12 +291,15 @@ A convenience method to reply to a message with markdown formatted text.
|
|||||||
|
|
||||||
Will return the C<Teapot::Bot::Object::Message> object representing the message
|
Will return the C<Teapot::Bot::Object::Message> object representing the message
|
||||||
sent.
|
sent.
|
||||||
|
On error returns hash reference with error field set to 1, also set fields
|
||||||
|
param, url and debug (which is result of Mojo::UserAgent->post->result->json)
|
||||||
|
|
||||||
=head2 typing
|
=head2 typing
|
||||||
|
|
||||||
Sends notification to chat that bot is "typing" something.
|
Sends notification to chat that bot is "typing" something.
|
||||||
|
|
||||||
Returns nothing that should be checked.
|
On error returns hash reference with error field set to 1, also set fields
|
||||||
|
param, url and debug (which is result of Mojo::UserAgent->post->result->json)
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::MessageAutoDeleteTimerChanged::VERSION = '0.023';
|
$Teapot::Bot::Object::MessageAutoDeleteTimerChanged::VERSION = '0.026';
|
||||||
|
|
||||||
has 'message_auto_delete_time';
|
has 'message_auto_delete_time';
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ Teapot::Bot::Object::MessageAutoDeleteTimerChanged - The base class for Telegram
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'MessageAutoDeleteTimerChanged' type objects.
|
The base class for Telegram 'MessageAutoDeleteTimerChanged' type objects.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::User ();
|
use Teapot::Bot::Object::User ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::MessageEntity::VERSION = '0.023';
|
$Teapot::Bot::Object::MessageEntity::VERSION = '0.026';
|
||||||
|
|
||||||
has 'type';
|
has 'type';
|
||||||
has 'offset';
|
has 'offset';
|
||||||
@@ -39,7 +39,7 @@ Teapot::Bot::Object::MessageEntity - The base class for Telegram 'MessageEntity'
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'MessageEntity' type objects.
|
The base class for Telegram 'MessageEntity' type objects.
|
||||||
|
|||||||
60
lib/Teapot/Bot/Object/MessageReaction.pm
Normal file
60
lib/Teapot/Bot/Object/MessageReaction.pm
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package Teapot::Bot::Object::MessageReaction;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'Reaction' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::MessageReaction::VERSION = '0.026';
|
||||||
|
|
||||||
|
has 'type'; # Type of the reaction, always “emoji”
|
||||||
|
has 'emoji'; # Reaction emoji. Currently, it can be one of "👍", "👎", "❤", "🔥", "🥰", "👏", "😁", "🤔",
|
||||||
|
# "🤯", "😱", "🤬", "😢", "🎉", "🤩", "🤮", "💩", "🙏", "👌", "🕊", "🤡", "🥱", "🥴", "😍", "🐳", "❤🔥", "🌚", "🌭",
|
||||||
|
# "💯", "🤣", "⚡", "🍌", "🏆", "💔", "🤨", "😐", "🍓", "🍾", "💋", "🖕", "😈", "😴", "😭", "🤓", "👻", "👨💻", "👀",
|
||||||
|
# "🎃", "🙈", "😇", "😨", "🤝", "✍", "🤗", "🫡", "🎅", "🎄", "☃", "💅", "🤪", "🗿", "🆒", "💘", "🙉", "🦄", "😘",
|
||||||
|
# "💊", "🙊", "😎", "👾", "🤷♂", "🤷", "🤷♀", "😡"
|
||||||
|
has 'custom_emoji_id'; # Only for ReactionTypeCustomEmoji. Custom emoji identifier.
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return {
|
||||||
|
'scalar' => [qw/type emoji custom_emoji_id total_count/],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::MessageReaction - The base class for Telegram message 'Reaction' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'Reaction' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#reactiontype> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::MessageReaction> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2025 Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
58
lib/Teapot/Bot/Object/MessageReactionCount.pm
Normal file
58
lib/Teapot/Bot/Object/MessageReactionCount.pm
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package Teapot::Bot::Object::MessageReactionCount;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'Reaction' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
use Teapot::Bot::Object::MessageReaction ();
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::MessageReactionCount::VERSION = '0.026';
|
||||||
|
|
||||||
|
has 'type'; # Type of the reaction
|
||||||
|
has 'total_count'; # Number of times the reaction was added
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return {
|
||||||
|
'Teapot::Bot::Object::MessageReaction' => [qw/type/],
|
||||||
|
'scalar' => [qw/total_count/],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::MessageReactionCount - The base class for Telegram message 'Reaction' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'Reaction' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#reactiontype> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::MessageReactionCount> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2025 Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
61
lib/Teapot/Bot/Object/MessageReactionCountUpdated.pm
Normal file
61
lib/Teapot/Bot/Object/MessageReactionCountUpdated.pm
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package Teapot::Bot::Object::MessageReactionCountUpdated;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'Reaction' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
use Teapot::Bot::Object::MessageReactionCount ();
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::MessageReactionCountUpdated::VERSION = '0.026';
|
||||||
|
|
||||||
|
has 'chat';
|
||||||
|
has 'message_id';
|
||||||
|
has 'date';
|
||||||
|
has 'reactions';
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return {
|
||||||
|
'Teapot::Bot::Object::Chat' => [qw/chat actor_chat/],
|
||||||
|
'Teapot::Bot::Object::MessageReactionCount' => [qw/reactions/],
|
||||||
|
'scalar' => [qw/message_id date/],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::MessageReactionCountUpdated - The base class for Telegram message 'Reaction' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'Reaction' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#reactiontype> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::MessageReactionCountUpdated> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2025 Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
67
lib/Teapot/Bot/Object/MessageReactionUpdated.pm
Normal file
67
lib/Teapot/Bot/Object/MessageReactionUpdated.pm
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package Teapot::Bot::Object::MessageReactionUpdated;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'ReactionUpdated' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
use Teapot::Bot::Object::Chat ();
|
||||||
|
use Teapot::Bot::Object::Chat ();
|
||||||
|
use Teapot::Bot::Object::MessageReaction ();
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::MessageReactionUpdated::VERSION = '0.026';
|
||||||
|
|
||||||
|
has 'chat'; # The chat containing the message the user reacted to
|
||||||
|
has 'message_id'; # Unique identifier of the message inside the chat
|
||||||
|
has 'user'; # Optional. The user that changed the reaction, if the user isn't anonymous
|
||||||
|
has 'actor_chat'; # Optional. The chat on behalf of which the reaction was changed, if the user is anonymous
|
||||||
|
has 'date'; # Date of the change in Unix time
|
||||||
|
has 'old_reaction'; # Previous list of reaction types that were set by the user
|
||||||
|
has 'new_reaction'; # New list of reaction types that have been set by the user
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return {
|
||||||
|
'Teapot::Bot::Object::Chat' => [qw/chat actor_chat/],
|
||||||
|
'Teapot::Bot::Object::User' => [qw/user/],
|
||||||
|
'Teapot::Bot::Object::MessageReaction' => [qw/old_reaction new_reaction/],
|
||||||
|
'scalar' => [qw/message_id date/],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::MessageReaction - The base class for Telegram message 'ReactionUpdated' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'ReactionUpdated' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#messagereactionupdated> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::MessageReactionUpdated> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2025 Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
@@ -10,7 +10,7 @@ use Mojo::Base 'Teapot::Bot::Object::Base';
|
|||||||
use Teapot::Bot::Object::EncryptedPassportElement ();
|
use Teapot::Bot::Object::EncryptedPassportElement ();
|
||||||
use Teapot::Bot::Object::EncryptedCredentials ();
|
use Teapot::Bot::Object::EncryptedCredentials ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::PassportData::VERSION = '0.023';
|
$Teapot::Bot::Object::PassportData::VERSION = '0.026';
|
||||||
|
|
||||||
has 'data'; # Array of EncryptedPassportElement
|
has 'data'; # Array of EncryptedPassportElement
|
||||||
has 'credentials'; # EncryptedCredentials
|
has 'credentials'; # EncryptedCredentials
|
||||||
@@ -40,7 +40,7 @@ Teapot::Bot::Object::PassportData - The base class for Telegram 'PassportData' t
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'PassportData' type objects.
|
The base class for Telegram 'PassportData' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::PhotoSize::VERSION = '0.023';
|
$Teapot::Bot::Object::PhotoSize::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
@@ -34,7 +34,7 @@ Teapot::Bot::Object::PhotoSize - The base class for Telegram message 'PhotoSize'
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'PhotoSize' type.
|
The base class for Telegram message 'PhotoSize' type.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::PollOption ();
|
use Teapot::Bot::Object::PollOption ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Poll::VERSION = '0.023';
|
$Teapot::Bot::Object::Poll::VERSION = '0.026';
|
||||||
|
|
||||||
has 'id';
|
has 'id';
|
||||||
has 'question';
|
has 'question';
|
||||||
@@ -52,7 +52,7 @@ Teapot::Bot::Object::Poll - The base class for Telegram 'Poll' type objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Poll' type objects
|
The base class for Telegram 'Poll' type objects
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::PollAnswer::VERSION = '0.023';
|
$Teapot::Bot::Object::PollAnswer::VERSION = '0.026';
|
||||||
|
|
||||||
has 'poll_id';
|
has 'poll_id';
|
||||||
has 'user';
|
has 'user';
|
||||||
@@ -39,7 +39,7 @@ Teapot::Bot::Object::PollAnswer - The base class for Telegram 'PollAnswer' type
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'PollAnswer' type objects.
|
The base class for Telegram 'PollAnswer' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::PollOption::VERSION = '0.023';
|
$Teapot::Bot::Object::PollOption::VERSION = '0.026';
|
||||||
|
|
||||||
has 'text';
|
has 'text';
|
||||||
has 'voter_count';
|
has 'voter_count';
|
||||||
@@ -31,7 +31,7 @@ Teapot::Bot::Object::PollOption - The base class for Telegram 'PollOption' type
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'PollOption' type objects.
|
The base class for Telegram 'PollOption' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::ProximityAlertTriggered::VERSION = '0.023';
|
$Teapot::Bot::Object::ProximityAlertTriggered::VERSION = '0.026';
|
||||||
|
|
||||||
has 'traveler'; # User
|
has 'traveler'; # User
|
||||||
has 'watcher'; # User
|
has 'watcher'; # User
|
||||||
@@ -35,7 +35,7 @@ Teapot::Bot::Object::ProximityAlertTriggered - The base class for Telegram messa
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'ProximityAlertTriggered' type.
|
The base class for Telegram message 'ProximityAlertTriggered' type.
|
||||||
|
|||||||
@@ -10,24 +10,30 @@ use Mojo::Base 'Teapot::Bot::Object::Base';
|
|||||||
use Teapot::Bot::Object::PhotoSize ();
|
use Teapot::Bot::Object::PhotoSize ();
|
||||||
use Teapot::Bot::Object::MaskPosition ();
|
use Teapot::Bot::Object::MaskPosition ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Sticker::VERSION = '0.023';
|
$Teapot::Bot::Object::Sticker::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
|
has 'type';
|
||||||
has 'width';
|
has 'width';
|
||||||
has 'height';
|
has 'height';
|
||||||
has 'is_animated';
|
has 'is_animated';
|
||||||
has 'is_video';
|
has 'is_video';
|
||||||
has 'thumb'; # PhotoSize
|
has 'thumbnail'; # PhotoSize
|
||||||
has 'emoji';
|
has 'emoji';
|
||||||
has 'set_name';
|
has 'set_name';
|
||||||
|
has 'premium_animation';
|
||||||
has 'mask_position';
|
has 'mask_position';
|
||||||
|
has 'custom_emoji_id';
|
||||||
|
has 'needs_repainting';
|
||||||
has 'file_size';
|
has 'file_size';
|
||||||
|
|
||||||
sub fields {
|
sub fields {
|
||||||
return {
|
return {
|
||||||
scalar => [ qw/file_id file_unique_id width height is_animated is_video emoji set_name file_size/ ],
|
scalar => [ qw/file_id file_unique_id type width height is_animated is_video emoji
|
||||||
'Teapot::Bot::Object::PhotoSize' => [ qw/thumb/ ],
|
set_name premium_animation custom_emoji_id needs_repainting
|
||||||
|
file_size/ ],
|
||||||
|
'Teapot::Bot::Object::PhotoSize' => [ qw/thumbnail/ ],
|
||||||
'Teapot::Bot::Object::MaskPosition' => [qw/mask_position/],
|
'Teapot::Bot::Object::MaskPosition' => [qw/mask_position/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -46,7 +52,7 @@ Teapot::Bot::Object::Sticker - The base class for Telegram message 'Sticker' typ
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'Sticker' type.
|
The base class for Telegram message 'Sticker' type.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
# use Teapot::Bot::Object::OrderInfo;
|
# use Teapot::Bot::Object::OrderInfo;
|
||||||
|
|
||||||
$Teapot::Bot::Object::SuccessfulPayment::VERSION = '0.023';
|
$Teapot::Bot::Object::SuccessfulPayment::VERSION = '0.026';
|
||||||
|
|
||||||
has 'currency';
|
has 'currency';
|
||||||
has 'total_amount';
|
has 'total_amount';
|
||||||
@@ -41,7 +41,7 @@ Teapot::Bot::Object::SuccessfulPayment - The base class for Telegram 'Successful
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'SuccessfulPayment' type objects.
|
The base class for Telegram 'SuccessfulPayment' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::User::VERSION = '0.023';
|
$Teapot::Bot::Object::User::VERSION = '0.026';
|
||||||
|
|
||||||
has 'id';
|
has 'id';
|
||||||
has 'is_bot';
|
has 'is_bot';
|
||||||
@@ -41,7 +41,7 @@ Teapot::Bot::Object::User - The base class for Telegram message 'User' type
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'User' type.
|
The base class for Telegram message 'User' type.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::Location ();
|
use Teapot::Bot::Object::Location ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Venue::VERSION = '0.023';
|
$Teapot::Bot::Object::Venue::VERSION = '0.026';
|
||||||
|
|
||||||
has 'location'; #Location
|
has 'location'; #Location
|
||||||
has 'title';
|
has 'title';
|
||||||
@@ -41,7 +41,7 @@ Teapot::Bot::Object::Venue - The base class for Telegram 'LoginUrl' type objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'LoginUrl' type objects.
|
The base class for Telegram 'LoginUrl' type objects.
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::PhotoSize ();
|
use Teapot::Bot::Object::PhotoSize ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::Video::VERSION = '0.023';
|
$Teapot::Bot::Object::Video::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
has 'width';
|
has 'width';
|
||||||
has 'height';
|
has 'height';
|
||||||
has 'duration';
|
has 'duration';
|
||||||
has 'thumb'; # Optional. Video thumbnail
|
has 'thumbnail'; # Optional. Video thumbnail
|
||||||
has 'file_name'; # Optional. Original filename as defined by sender
|
has 'file_name'; # Optional. Original filename as defined by sender
|
||||||
has 'mime_type'; # Optional. Mime type of a file as defined by sender
|
has 'mime_type'; # Optional. Mime type of a file as defined by sender
|
||||||
has 'file_size'; # Optional. File size
|
has 'file_size'; # Optional. File size
|
||||||
@@ -25,7 +25,7 @@ sub fields {
|
|||||||
return {
|
return {
|
||||||
scalar => [qw/file_id file_unique_id width height duration file_name mime_type
|
scalar => [qw/file_id file_unique_id width height duration file_name mime_type
|
||||||
file_size/],
|
file_size/],
|
||||||
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/],
|
'Teapot::Bot::Object::PhotoSize' => [qw/thumbnail/],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ Teapot::Bot::Object::Video - The base class for Telegram 'Video' object
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Video' object.
|
The base class for Telegram 'Video' object.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::VideoChatEnded::VERSION = '0.023';
|
$Teapot::Bot::Object::VideoChatEnded::VERSION = '0.026';
|
||||||
|
|
||||||
# This object represents a service message about a Video chat started in the chat. Currently holds no information.
|
# This object represents a service message about a Video chat started in the chat. Currently holds no information.
|
||||||
has 'duration';
|
has 'duration';
|
||||||
@@ -31,7 +31,7 @@ Teapot::Bot::Object::VideoChatEnded - The base class for Telegram message 'Video
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'VideoChatEnded' type.
|
The base class for Telegram message 'VideoChatEnded' type.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::User ();
|
use Teapot::Bot::Object::User ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::VideoChatParticipantsInvited::VERSION = '0.023';
|
$Teapot::Bot::Object::VideoChatParticipantsInvited::VERSION = '0.026';
|
||||||
|
|
||||||
# This object represents a service message about a Video chat started in the chat. Currently holds no information.
|
# This object represents a service message about a Video chat started in the chat. Currently holds no information.
|
||||||
has 'users';
|
has 'users';
|
||||||
@@ -36,7 +36,7 @@ Teapot::Bot::Object::VideoChatParticipantsInvited - The base class for Telegram
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'VideoChatParticipantsInvited' type.
|
The base class for Telegram message 'VideoChatParticipantsInvited' type.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::VideoChatScheduled::VERSION = '0.023';
|
$Teapot::Bot::Object::VideoChatScheduled::VERSION = '0.026';
|
||||||
|
|
||||||
# This object represents a service message about a video chat started in the chat. Currently holds no information.
|
# This object represents a service message about a video chat started in the chat. Currently holds no information.
|
||||||
has 'start_date';
|
has 'start_date';
|
||||||
@@ -31,7 +31,7 @@ Teapot::Bot::Object::VideoChatScheduled - The base class for Telegram message 'V
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'VideoChatScheduled' type.
|
The base class for Telegram message 'VideoChatScheduled' type.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::VideoChatStarted::VERSION = '0.023';
|
$Teapot::Bot::Object::VideoChatStarted::VERSION = '0.026';
|
||||||
|
|
||||||
# This object represents a service message about a Video chat started in the chat. Currently holds no information.
|
# This object represents a service message about a Video chat started in the chat. Currently holds no information.
|
||||||
has 'stub';
|
has 'stub';
|
||||||
@@ -31,7 +31,7 @@ Teapot::Bot::Object::VideoChatStarted - The base class for Telegram message 'Vid
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram message 'VideoChatStarted' type.
|
The base class for Telegram message 'VideoChatStarted' type.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use utf8;
|
|||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
use Teapot::Bot::Object::PhotoSize ();
|
use Teapot::Bot::Object::PhotoSize ();
|
||||||
|
|
||||||
$Teapot::Bot::Object::VideoNote::VERSION = '0.023';
|
$Teapot::Bot::Object::VideoNote::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
@@ -40,7 +40,7 @@ Teapot::Bot::Object::VideoNote - The base class for Telegram 'VideoNote' type ob
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'VideoNote' type object.
|
The base class for Telegram 'VideoNote' type object.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::Voice::VERSION = '0.023';
|
$Teapot::Bot::Object::Voice::VERSION = '0.026';
|
||||||
|
|
||||||
has 'file_id';
|
has 'file_id';
|
||||||
has 'file_unique_id';
|
has 'file_unique_id';
|
||||||
@@ -34,7 +34,7 @@ Teapot::Bot::Object::Voice - The base class for Telegram 'Voice' type objects
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'Voice' type objects.
|
The base class for Telegram 'Voice' type objects.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use utf8;
|
|||||||
|
|
||||||
use Mojo::Base 'Teapot::Bot::Object::Base';
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
$Teapot::Bot::Object::WebAppData::VERSION = '0.023';
|
$Teapot::Bot::Object::WebAppData::VERSION = '0.026';
|
||||||
|
|
||||||
has 'data';
|
has 'data';
|
||||||
has 'button_text';
|
has 'button_text';
|
||||||
@@ -31,7 +31,7 @@ Teapot::Bot::Object::WebAppData - The base class for Telegram 'WebAppData' type
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
version 0.023
|
version 0.026
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
The base class for Telegram 'WebAppData' type objects.
|
The base class for Telegram 'WebAppData' type objects.
|
||||||
|
|||||||
51
lib/Teapot/Bot/Object/WriteAccessAllowed.pm
Normal file
51
lib/Teapot/Bot/Object/WriteAccessAllowed.pm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package Teapot::Bot::Object::WriteAccessAllowed;
|
||||||
|
# ABSTRACT: The base class for Telegram message 'WriteAccessAllowed' type.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use Mojo::Base 'Teapot::Bot::Object::Base';
|
||||||
|
|
||||||
|
$Teapot::Bot::Object::WriteAccessAllowed::VERSION = '0.026';
|
||||||
|
|
||||||
|
|
||||||
|
sub fields {
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Teapot::Bot::Object::WriteAccessAllowed - The base class for Telegram message 'WriteAccessAllowed' type
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
version 0.026
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
The base class for Telegram message 'WriteAccessAllowed' type.
|
||||||
|
|
||||||
|
See L<https://core.telegram.org/bots/api#writeaccessallowed> for details of the
|
||||||
|
attributes available for C<Teapot::Bot::Object::WriteAccessAllowed> objects.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Sergei Fedosov <eleksir@gmail.com>
|
||||||
|
|
||||||
|
=head1 LICENSE AND COPYRIGHT
|
||||||
|
|
||||||
|
This software is copyright (c) 2023 by Sergei Fedosov <eleksir@gmail.com>.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under
|
||||||
|
the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
@@ -14,10 +14,11 @@ 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';
|
||||||
|
|
||||||
use BotLib::Admin qw (FortuneToggleList ChanMsgEnabled GreetMsgEnabled GoodbyeMsgEnabled);
|
use BotLib::Admin qw (FortuneToggleList ChanMsgEnabled GreetMsgEnabled GoodbyeMsgEnabled
|
||||||
use BotLib qw (Command Highlight BotSleep IsCensored);
|
MigrateSettingsToNewChatID IsCensored GetSlackGreetRememberId SetSlackGreetRememberId);
|
||||||
|
use BotLib qw (Command);
|
||||||
use BotLib::Conf qw (LoadConf);
|
use BotLib::Conf qw (LoadConf);
|
||||||
use BotLib::Util qw (trim fmatch);
|
use BotLib::Util qw (trim fmatch Highlight RandomCommonPhrase);
|
||||||
use RedisLib qw (redis_events_listener);
|
use RedisLib qw (redis_events_listener);
|
||||||
|
|
||||||
use version; our $VERSION = qw (1.0);
|
use version; our $VERSION = qw (1.0);
|
||||||
@@ -42,6 +43,7 @@ my @introduce_greet = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
my $redismsg->{from} = 'telegram';
|
my $redismsg->{from} = 'telegram';
|
||||||
|
$redismsg->{threadid} = '';
|
||||||
$redismsg->{plugin} = 'telegram';
|
$redismsg->{plugin} = 'telegram';
|
||||||
$redismsg->{misc}->{answer} = 1;
|
$redismsg->{misc}->{answer} = 1;
|
||||||
$redismsg->{misc}->{csign} = "$c->{telegrambot}->{csign}";
|
$redismsg->{misc}->{csign} = "$c->{telegrambot}->{csign}";
|
||||||
@@ -85,6 +87,9 @@ sub __cron {
|
|||||||
$pubsub->json ($c->{'redis_router_channel'})->notify (
|
$pubsub->json ($c->{'redis_router_channel'})->notify (
|
||||||
$c->{'redis_router_channel'} => $rmsg,
|
$c->{'redis_router_channel'} => $rmsg,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Ratelimit this, just in case
|
||||||
|
sleep (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +100,15 @@ sub __on_msg {
|
|||||||
my ($self, $msg) = @_;
|
my ($self, $msg) = @_;
|
||||||
# chat info
|
# chat info
|
||||||
my $chatid;
|
my $chatid;
|
||||||
|
|
||||||
|
# Ловим сообщения о миграции.
|
||||||
|
if ($msg->can ('migrate_to_chat_id') && $msg->can ('migrate_from_chat_id')) {
|
||||||
|
if (defined ($msg->migrate_from_chat_id) && defined ($msg->migrate_from_chat_id)) {
|
||||||
|
MigrateSettingsToNewChatID ($msg->migrate_from_chat_id, $msg->migrate_to_chat_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $chatname = 'Noname chat';
|
my $chatname = 'Noname chat';
|
||||||
# user sending message info
|
# user sending message info
|
||||||
my ($userid, $username, $fullname, $highlight, $vis_a_vi) = Highlight ($msg);
|
my ($userid, $username, $fullname, $highlight, $vis_a_vi) = Highlight ($msg);
|
||||||
@@ -104,6 +118,7 @@ sub __on_msg {
|
|||||||
my $myObj = $self->getMe ();
|
my $myObj = $self->getMe ();
|
||||||
|
|
||||||
if ($myObj->{error}) {
|
if ($myObj->{error}) {
|
||||||
|
$log->error ("[ERROR] Unable to call getMe BotAPI method: " . Dumper ($myObj));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,6 +188,10 @@ sub __on_msg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Remember user id, to check it later, in next event.
|
||||||
|
SetSlackGreetRememberId ($member->id);
|
||||||
|
$log->info (sprintf ("[INFO] New chat member %s (%s)", $member_str, $member->id));
|
||||||
|
|
||||||
push @members, sprintf '[%s](tg://user?id=%s)', $member_str, $member->id;
|
push @members, sprintf '[%s](tg://user?id=%s)', $member_str, $member->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +211,55 @@ sub __on_msg {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
BotSleep $msg;
|
sleep 2;
|
||||||
$msg->replyMd ($phrase);
|
my $m->{text} = $phrase;
|
||||||
|
$m->{chat_id} = $chatid;
|
||||||
|
$m->{disable_notification} = 1;
|
||||||
|
$m->{parse_mode} = 'Markdown';
|
||||||
|
|
||||||
|
my $res = $main::TGM->sendMessage ($m);
|
||||||
|
|
||||||
|
if ($res->{error}) {
|
||||||
|
$log->error ("[ERROR] Unable to call sendMessage BotAPI method: " . Dumper ($res));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bots have non-0% tendency to appear with this kind of updates.
|
||||||
|
if ($msg->can ('new_chat_member') && defined ($msg->new_chat_member)) {
|
||||||
|
return;
|
||||||
|
# slackware_ru
|
||||||
|
unless ($chatid == -1001332512695) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep 2;
|
||||||
|
|
||||||
|
# Can be racy, but hope for best.
|
||||||
|
unless (GetSlackGreetRememberId($msg->new_chat_member->user->id)) {
|
||||||
|
$log->info ("[INFO] $vis_a_vi entered to chat without prior notice event");
|
||||||
|
|
||||||
|
# if earlier we did not get new chat member event, it looks like we have spammer here. Ban it.
|
||||||
|
my $send_args = undef;
|
||||||
|
$send_args->{chat_id} = 0 + $chatid;
|
||||||
|
$send_args->{user_id} = 0 + $msg->new_chat_member->user->id;
|
||||||
|
|
||||||
|
# According to docs if user banned for <30 seonds || >366 days it banned forever.
|
||||||
|
# Some bots have annoying behavior to constantly try to join chat.
|
||||||
|
$send_args->{until_date} = 10 + time ();
|
||||||
|
$send_args->{until_date} = 10 + time ();
|
||||||
|
|
||||||
|
my $result = $self->banChatMember ($send_args);
|
||||||
|
|
||||||
|
if ((ref ($result) eq 'JSON::PP::Boolean') && ($result == JSON::PP::true)) {
|
||||||
|
$log->info ("[INFO] $vis_a_vi banned");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$log->error ("[ERROR] Unable to ban user: " . Dumper ($result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +302,17 @@ sub __on_msg {
|
|||||||
|
|
||||||
my $leftuser = sprintf '[%s](tg://user?id=%s)', $member_str, $member->id;
|
my $leftuser = sprintf '[%s](tg://user?id=%s)', $member_str, $member->id;
|
||||||
$phrase = sprintf $goodbye[irand ($#goodbye + 1)], $leftuser;
|
$phrase = sprintf $goodbye[irand ($#goodbye + 1)], $leftuser;
|
||||||
$msg->replyMd ($phrase);
|
my $res = $msg->replyMd ($phrase);
|
||||||
|
|
||||||
|
if ($res->{error}) {
|
||||||
|
$log->error ("[ERROR] Unable to call sendMessage BotAPI method: " . Dumper ($res));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($msg->can ('old_reaction') || $msg->can ('new_reaction')) {
|
||||||
|
$log->debug (sprintf ('[DEBUG] user %s in %s posts reaction to message', $vis_a_vi, $chatname));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +372,11 @@ sub __on_msg {
|
|||||||
# И вот тут как раз такая проверка и происходит
|
# И вот тут как раз такая проверка и происходит
|
||||||
if (IsCensored $msg) {
|
if (IsCensored $msg) {
|
||||||
$log->info (sprintf '[INFO] In public chat %s (%s) message from %s was censored', $chatname, $chatid, $vis_a_vi);
|
$log->info (sprintf '[INFO] In public chat %s (%s) message from %s was censored', $chatname, $chatid, $vis_a_vi);
|
||||||
$self->deleteMessage ({chat_id => $chatid, message_id => $msg->{message_id}});
|
my $res = $self->deleteMessage ({chat_id => $chatid, message_id => $msg->{message_id}});
|
||||||
|
|
||||||
|
if ($res->{error}) {
|
||||||
|
$log->error ("[ERROR] Unable to call sendMessage BotAPI method: " . Dumper ($res));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Некоторые рекламные товарищи пытаются срать своими каналами в чятик это тоже можно зацензурить ботом и это
|
# Некоторые рекламные товарищи пытаются срать своими каналами в чятик это тоже можно зацензурить ботом и это
|
||||||
@@ -308,7 +388,11 @@ sub __on_msg {
|
|||||||
|
|
||||||
if (defined $sender_chat) {
|
if (defined $sender_chat) {
|
||||||
unless (ChanMsgEnabled ($chatid)) {
|
unless (ChanMsgEnabled ($chatid)) {
|
||||||
$self->deleteMessage ({chat_id => $chatid, message_id => $msg->{message_id}});
|
my $res = $self->deleteMessage ({chat_id => $chatid, message_id => $msg->{message_id}});
|
||||||
|
|
||||||
|
if ($res->{error}) {
|
||||||
|
$log->error ("[ERROR] Unable to call sendMessage BotAPI method: " . Dumper ($res));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,6 +443,15 @@ sub __on_msg {
|
|||||||
$rmsg->{chatid} = "$chatid";
|
$rmsg->{chatid} = "$chatid";
|
||||||
$rmsg->{misc}->{answer} = 1;
|
$rmsg->{misc}->{answer} = 1;
|
||||||
|
|
||||||
|
# Если тип группы supergroup, в ней могут быть треды, попробуем найти message_thread_id, если таковой есть
|
||||||
|
if ($msg->chat->type eq 'supergroup') {
|
||||||
|
if ($msg->can ('is_topic_message') && $msg->is_topic_message) {
|
||||||
|
if ($msg->can ('message_thread_id') && $msg->message_thread_id ne '') {
|
||||||
|
$rmsg->{threadid} = "$msg->message_thread_id";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
my $ready = eval { $main::RCONN->is_connected; };
|
my $ready = eval { $main::RCONN->is_connected; };
|
||||||
@@ -399,6 +492,15 @@ sub __on_msg {
|
|||||||
$rmsg->{chatid} = "$chatid";
|
$rmsg->{chatid} = "$chatid";
|
||||||
$rmsg->{misc}->{answer} = 1;
|
$rmsg->{misc}->{answer} = 1;
|
||||||
|
|
||||||
|
# Если тип группы supergroup, в ней могут быть треды, попробуем найти message_thread_id, если таковой есть
|
||||||
|
if ($msg->chat->type eq 'supergroup') {
|
||||||
|
if ($msg->can ('is_topic_message') && $msg->is_topic_message) {
|
||||||
|
if ($msg->can ('message_thread_id') && $msg->message_thread_id ne '') {
|
||||||
|
$rmsg->{threadid} = "$msg->message_thread_id";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Сообщение обращено к боту
|
# Сообщение обращено к боту
|
||||||
if ((lc ($text) =~ /^${qname}[\,|\:]? (.+)/) or (lc ($text) =~ /^${qtname}[\,|\:]? (.+)/)){
|
if ((lc ($text) =~ /^${qname}[\,|\:]? (.+)/) or (lc ($text) =~ /^${qtname}[\,|\:]? (.+)/)){
|
||||||
$phrase = $1;
|
$phrase = $1;
|
||||||
@@ -451,10 +553,25 @@ sub __on_msg {
|
|||||||
|
|
||||||
$msg->typing ();
|
$msg->typing ();
|
||||||
sleep (irand 2);
|
sleep (irand 2);
|
||||||
$log->debug (sprintf ('[DEBUG] In public chat %s (%s) bot reply to %s: %s', $chatname, $chatid, $vis_a_vi, $reply));
|
$log->debug (
|
||||||
$msg->reply ($reply);
|
sprintf (
|
||||||
|
'[DEBUG] In public chat %s (%s) bot reply to %s: %s',
|
||||||
|
$chatname, $chatid, $vis_a_vi, $reply,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
my $res = $msg->reply ($reply);
|
||||||
|
|
||||||
|
if ($res->{error}) {
|
||||||
|
$log->error ("[ERROR] Unable to call sendMessage BotAPI method: " . Dumper ($res));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$log->debug (sprintf ('[DEBUG] In public chat %s (%s) bot is not required to reply to %s', $chatname, $chatid, $vis_a_vi));
|
$log->debug (
|
||||||
|
sprintf (
|
||||||
|
'[DEBUG] In public chat %s (%s) bot is not required to reply to %s',
|
||||||
|
$chatname, $chatid, $vis_a_vi,
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# should be channel, so we can't talk
|
# should be channel, so we can't talk
|
||||||
@@ -465,23 +582,6 @@ sub __on_msg {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub RandomCommonPhrase {
|
|
||||||
my @myphrase = (
|
|
||||||
'Так, блядь...',
|
|
||||||
'*Закатывает рукава* И ради этого ты меня позвал?',
|
|
||||||
'Ну чего ты начинаешь, нормально же общались',
|
|
||||||
'Повтори свой вопрос, не поняла',
|
|
||||||
'Выйди и зайди нормально',
|
|
||||||
'Я подумаю',
|
|
||||||
'Даже не знаю, что на это ответить',
|
|
||||||
'Ты упал такие вопросы девочке задавать?',
|
|
||||||
'Можно и так, но не уверена',
|
|
||||||
'А как ты думаешь?',
|
|
||||||
'А ви, таки, почему интересуетесь?',
|
|
||||||
);
|
|
||||||
|
|
||||||
return $myphrase[irand ($#myphrase + 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
# setup our bot
|
# setup our bot
|
||||||
sub init {
|
sub init {
|
||||||
@@ -501,6 +601,8 @@ sub RunTelegramBot {
|
|||||||
eval { ## no critic (ErrorHandling::RequireCheckingReturnValueOfEval)
|
eval { ## no critic (ErrorHandling::RequireCheckingReturnValueOfEval)
|
||||||
TelegramBot->new->think;
|
TelegramBot->new->think;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$log->error ("[ERROR] $EVAL_ERROR");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
101
util/get_chat_users_by_id.pl
Normal file
101
util/get_chat_users_by_id.pl
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
# По соглашению, рабочим каталогом является каталог с приложением, то есть запускать этот скрипт надо как
|
||||||
|
# util/get_chat_users_by_id.pl
|
||||||
|
|
||||||
|
# Для запуска этого скрипта нам понадобится список id пользователей и id чата, для которого мы дампим информацию о
|
||||||
|
# пользователях. Входные данные мы складываем в файл get_chat_users_by_id.json.
|
||||||
|
|
||||||
|
# На выходе в каталоге c->{cachedir} мы получим каталог get_chat_users_by_id/chat_id с кучей json-чиков, по одному на
|
||||||
|
# каждого пользователя.
|
||||||
|
|
||||||
|
use 5.018; ## no critic (ProhibitImplicitImport)
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use utf8;
|
||||||
|
use open qw (:std :utf8);
|
||||||
|
use English qw ( -no_match_vars );
|
||||||
|
|
||||||
|
use version; our $VERSION = qw (1.0);
|
||||||
|
|
||||||
|
my $workdir;
|
||||||
|
|
||||||
|
# before we run, change working dir
|
||||||
|
BEGIN {
|
||||||
|
use Cwd qw (chdir abs_path);
|
||||||
|
my @CWD = split /\//xms, abs_path ($PROGRAM_NAME);
|
||||||
|
|
||||||
|
if ($#CWD > 1) {
|
||||||
|
$#CWD = $#CWD - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
$workdir = join '/', @CWD;
|
||||||
|
chdir $workdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
use lib ("$workdir/lib", "$workdir/vendor_perl", "$workdir/vendor_perl/lib/perl5");
|
||||||
|
no Cwd;
|
||||||
|
use Cwd::utf8 qw (chdir abs_path);
|
||||||
|
use Data::Dumper qw (Dumper);
|
||||||
|
use File::Path qw(make_path);
|
||||||
|
use JSON::XS qw (decode_json);
|
||||||
|
# Грех не воспользоваться, если у нас оно есть под рукой, хотя по мне тут достаточно Http::Tiny
|
||||||
|
use Mojo::UserAgent ();
|
||||||
|
|
||||||
|
use BotLib::Conf qw (LoadConf);
|
||||||
|
|
||||||
|
# Поехали!
|
||||||
|
my $c = LoadConf ();
|
||||||
|
|
||||||
|
# Пример содержимого файлика: {"chatid": -номер, "users": ["id1", "id2"]}
|
||||||
|
my $data = LoadConf ("$workdir/get_chat_users_by_id.json");
|
||||||
|
|
||||||
|
unless (defined $c->{cachedir}) {
|
||||||
|
die "Please define cachedir in data/config.jason\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
unless (defined $data->{chatid}) {
|
||||||
|
die "Please define chatid in get_chat_users_by_id.json\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $targetDir = sprintf ("%s/get_chat_users_by_id/%s", $c->{cachedir}, $data->{chatid});
|
||||||
|
|
||||||
|
make_path ($targetDir) or die "Unable to create $targetDir: $OS_ERROR\n";
|
||||||
|
|
||||||
|
my $url = sprintf (
|
||||||
|
"https://api.telegram.org/bot%s/getChatMember",
|
||||||
|
$c->{telegrambot}->{token},
|
||||||
|
);
|
||||||
|
|
||||||
|
while (my $userid = pop @{$data->{users}}) {
|
||||||
|
my $ua = Mojo::UserAgent->new->connect_timeout (3);
|
||||||
|
my $r = $ua->post ($url => form => {chat_id => $data->{chatid}, user_id => $userid} )->result;
|
||||||
|
|
||||||
|
# Do not flood api with requests!
|
||||||
|
sleep 1;
|
||||||
|
|
||||||
|
unless ($r->is_success) {
|
||||||
|
warn sprintf ("Unable to get info about user: http status %s\n%s\n", $r->{code}, $r->body);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $j = eval { decode_json ($r->body) };
|
||||||
|
|
||||||
|
if (defined $j) {
|
||||||
|
my $jobj = JSON::XS->new ();
|
||||||
|
$jobj = $jobj->pretty (1);
|
||||||
|
$jobj = $jobj->canonical (1);
|
||||||
|
my $json = $jobj->encode ($j);
|
||||||
|
|
||||||
|
my $file = sprintf "%s/%s.json", $targetDir, $userid;
|
||||||
|
|
||||||
|
open (my $FH, '>', $file) or do {
|
||||||
|
warn "Unable to write to $file: $OS_ERROR\n";
|
||||||
|
next;
|
||||||
|
};
|
||||||
|
|
||||||
|
print $FH $json . "\n";
|
||||||
|
close $FH;
|
||||||
|
} else {
|
||||||
|
warn sprintf ("Telegram bot api returns corrupted json: %s,\n%s\n", $r->body, $@);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user