New logging, handle bot quote in groups, newcommer greets reworked

+ More sane and verbose logging
* Newcommer greet now should now mention newcommer
+ If someone in group quote bot's phrase, bot should answer
* Move some subs related to framework to telegramlib.pm
* Handle (log only for now) sent media - documents, stickers, photos in public chats (voice, audio, video still unhandled)
This commit is contained in:
eleksir
2020-09-26 21:22:39 +03:00
parent 376cbdfbe5
commit 1567fbe0db
3 changed files with 320 additions and 167 deletions

View File

@@ -23,15 +23,15 @@ $VERSION = "1.0";
my $c = loadConf(); my $c = loadConf();
sub weather($) { sub weather ($) {
my $city = shift; my $city = shift;
$city = trim($city); $city = trim ($city);
return "Мне нужно ИМЯ города." if ($city eq ''); return "Мне нужно ИМЯ города." if ($city eq '');
return "Длинновато для названия города." if (length($city) > 80); return "Длинновато для названия города." if (length($city) > 80);
$city = ucfirst($city); $city = ucfirst ($city);
my $w = __weather($city); my $w = __weather ($city);
my $reply; my $reply;
if ($w) { if ($w) {
@@ -39,7 +39,7 @@ sub weather($) {
$reply = sprintf ("Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.ст", $reply = sprintf ("Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.ст",
$w->{name}, $w->{name},
$w->{country}, $w->{country},
ucfirst($w->{description}), ucfirst ($w->{description}),
$w->{wind_direction}, $w->{wind_direction},
$w->{wind_speed}, $w->{wind_speed},
$w->{temperature_min}, $w->{temperature_min},
@@ -51,7 +51,7 @@ sub weather($) {
$reply = sprintf ("Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s-%s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.ст", $reply = sprintf ("Погода в городе %s, %s:\n%s, ветер %s %s м/c, температура %s-%s°C, ощущается как %s°C, относительная влажность %s%%, давление %s мм.рт.ст",
$w->{name}, $w->{name},
$w->{country}, $w->{country},
ucfirst($w->{description}), ucfirst ($w->{description}),
$w->{wind_direction}, $w->{wind_direction},
$w->{wind_speed}, $w->{wind_speed},
$w->{temperature_min}, $w->{temperature_min},
@@ -68,16 +68,16 @@ sub weather($) {
return $reply; return $reply;
} }
sub __weather($) { sub __weather ($) {
my $city = shift; my $city = shift;
$city = __urlencode($city); $city = __urlencode ($city);
my $id = md5_base64($city); my $id = md5_base64 ($city);
my $appid = $c->{openweathermap}->{appid}; my $appid = $c->{openweathermap}->{appid};
my $now = time(); my $now = time ();
my $fc; my $fc;
my $w; my $w;
# attach to cache data # attach to cache data
tie my %cachetime, 'DB_File', $c->{openweathermap}->{cachetime} or do { tie my %cachetime, 'DB_File', $c->{openweathermap}->{cachetime} or do {
warn "Something nasty happen when cachetime ties to its data: $!"; warn "Something nasty happen when cachetime ties to its data: $!";
return undef; return undef;
@@ -88,23 +88,23 @@ sub __weather($) {
return undef; return undef;
}; };
# lookup cache # lookup cache
if (defined ($cachetime{$id}) && ($now - $cachetime{$id}) < 10800) { if (defined ($cachetime{$id}) && ($now - $cachetime{$id}) < 10800) {
$fc = decode_json($cachedata{$id}); $fc = decode_json ($cachedata{$id});
} else { } else {
my $r; my $r;
# try 3 times and giveup # try 3 times and giveup
for (my $counter = 0; $counter < 3; $counter++) { for (my $counter = 0; $counter < 3; $counter++) {
next if ($r->{success}); next if ($r->{success});
my $http = HTTP::Tiny->new(timeout => 3); my $http = HTTP::Tiny->new (timeout => 3);
$r = $http->get(sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&lang=ru&APPID=%s", $city, $appid)); $r = $http->get (sprintf ("http://api.openweathermap.org/data/2.5/weather?q=%s&lang=ru&APPID=%s", $city, $appid));
sleep 2; sleep 2;
} }
# all 3 times can give error, so check it here # all 3 times can give error, so check it here
if ($r->{success}) { if ($r->{success}) {
$fc = eval { decode_json($r->{content}) }; $fc = eval { decode_json ($r->{content}) };
if ($@) { if ($@) {
warn "[WARN] openweathermap returns corrupted json: $@"; warn "[WARN] openweathermap returns corrupted json: $@";
@@ -114,7 +114,7 @@ sub __weather($) {
}; };
$cachetime{$id} = $now; $cachetime{$id} = $now;
$cachedata{$id} = encode_json($fc); $cachedata{$id} = encode_json ($fc);
} else { } else {
untie %cachetime; untie %cachetime;
untie %cachedata; untie %cachedata;
@@ -125,21 +125,21 @@ sub __weather($) {
untie %cachetime; untie %cachetime;
untie %cachedata; untie %cachedata;
# TODO: check all of this for existance # TODO: check all of this for existance
$w->{'name'} = $fc->{name}; $w->{'name'} = $fc->{name};
$w->{'state'} = $fc->{state}; $w->{'state'} = $fc->{state};
$w->{'country'} = $fc->{sys}->{country}; $w->{'country'} = $fc->{sys}->{country};
$w->{'longitude'} = $fc->{coord}->{lon}; $w->{'longitude'} = $fc->{coord}->{lon};
$w->{'latitude'} = $fc->{coord}->{lat}; $w->{'latitude'} = $fc->{coord}->{lat};
$w->{'temperature_min'} = int($fc->{main}->{temp_min} - 273.15); $w->{'temperature_min'} = int ($fc->{main}->{temp_min} - 273.15);
$w->{'temperature_max'} = int($fc->{main}->{temp_max} - 273.15); $w->{'temperature_max'} = int ($fc->{main}->{temp_max} - 273.15);
$w->{'temperature_feelslike'} = int($fc->{main}->{feels_like} - 273.15); $w->{'temperature_feelslike'} = int ($fc->{main}->{feels_like} - 273.15);
$w->{'humidity'} = $fc->{main}->{humidity}; $w->{'humidity'} = $fc->{main}->{humidity};
$w->{'pressure'} = int($fc->{main}->{pressure} * 0.75006375541921); $w->{'pressure'} = int ($fc->{main}->{pressure} * 0.75006375541921);
$w->{'description'} = $fc->{weather}->[0]->{description}; $w->{'description'} = $fc->{weather}->[0]->{description};
$w->{'wind_speed'} = $fc->{wind}->{speed}; $w->{'wind_speed'} = $fc->{wind}->{speed};
$w->{'wind_direction'} = 'разный'; $w->{'wind_direction'} = 'разный';
my $dir = int($fc->{wind}->{deg} + 0); my $dir = int ($fc->{wind}->{deg} + 0);
if ($dir == 0) { if ($dir == 0) {
$w->{'wind_direction'} = 'северный'; $w->{'wind_direction'} = 'северный';
@@ -180,7 +180,7 @@ sub __weather($) {
return $w; return $w;
} }
sub __urlencode($) { sub __urlencode ($) {
my $str = shift; my $str = shift;
my $urlobj = url $str; my $urlobj = url $str;
$str = $urlobj->as_string; $str = $urlobj->as_string;
@@ -206,11 +206,11 @@ sub logger {
} }
} }
sub trim($) { sub trim ($) {
my $str = shift; my $str = shift;
while (substr ($str, 0, 1) =~ /^\s$/) { while (substr ($str, 0, 1) =~ /^\s$/) {
$str = substr($str, 1); $str = substr ($str, 1);
} }
while (substr ($str, -1, 1) =~ /^\s$/) { while (substr ($str, -1, 1) =~ /^\s$/) {
@@ -220,7 +220,7 @@ sub trim($) {
return $str; return $str;
} }
sub randomCommonPhrase() { sub randomCommonPhrase () {
my @myphrase = ( my @myphrase = (
"Так, блядь...", "Так, блядь...",
"*Закатывает рукава* И ради этого ты меня позвал?", "*Закатывает рукава* И ради этого ты меня позвал?",
@@ -234,7 +234,7 @@ sub randomCommonPhrase() {
"А как ты думаешь?" "А как ты думаешь?"
); );
return ($myphrase[rand($#myphrase -1)]); return ($myphrase[rand ($#myphrase -1)]);
} }
1; 1;

View File

@@ -14,6 +14,7 @@ use Mojo::Base 'Telegram::Bot::Brain';
use conf; use conf;
use botlib; use botlib;
use telegramlib;
use Exporter qw(import); use Exporter qw(import);
our @EXPORT = qw(run_telegrambot); our @EXPORT = qw(run_telegrambot);
@@ -23,6 +24,10 @@ $VERSION = "1.0";
my $c = loadConf(); my $c = loadConf();
my $hailo; my $hailo;
my $myid; my $myid;
my $myusername;
my $myfirst_name;
my $mylast_name;
my $myfullname;
# guess it later # guess it later
my $can_talk = 0; my $can_talk = 0;
@@ -36,139 +41,254 @@ sub __cron {
sub __on_msg { sub __on_msg {
my ($self, $msg) = @_; my ($self, $msg) = @_;
# chat info
my $chatid; my $chatid;
my $chatname = 'Noname chat';
# user sending message info
my $userid;
my $username;
my $fullname;
my $vis_a_vi = 'unknown';
$can_talk = 0; $can_talk = 0;
unless ($myid) { unless ($myid) {
my $myObj = Telegram::Bot::Brain::getMe($self); my $myObj = Telegram::Bot::Brain::getMe ($self);
$myid = $myObj->id; $myid = $myObj->id;
# TODO: use these values instead of pre-defined in config!
$myusername = $myObj->username;
$myfirst_name = $myObj->first_name;
$mylast_name = $myObj->last_name;
if (defined ($myfirst_name) && ($myfirst_name ne '') && defined ($mylast_name) && ($mylast_name ne '')) {
$myfullname = $myfirst_name . ' ' . $mylast_name;
} elsif (defined ($myfirst_name) && ($myfirst_name ne '')) {
$myfullname = $myfirst_name;
} elsif (defined ($mylast_name) && ($mylast_name ne '')) {
$myfullname = $mylast_name;
} else {
$myfullname = $myusername;
}
} }
if ($msg->{'chat'}->can('id')) { if ($msg->chat->can ('id') && defined ($msg->chat->id)) {
$chatid = $msg->{'chat'}->id; $chatid = $msg->chat->id;
my $group_talk = 0; my $group_talk = 0;
my $chatname = 'Noname chat'; if ($msg->chat->can ('username') && defined ($msg->chat->username)) {
$chatname = $msg->{'chat'}->username if ($msg->{'chat'}->can('username')); $chatname = $msg->chat->username ;
} else {
if ($msg->chat->can ('title') && defined ($msg->chat->title)) {
$chatname = $msg->chat->title;
} else {
$chatname = 'Noname chat';
}
}
# because of bot api restriction there is no events about changing permissions in chat sent to bot # because of bot api restriction there is no events about changing permissions
# so before sending any answer, we should check if we can do so # in chat sent to bot so before sending any answer, we should check if we can do so
# N.B. there is situation when we do not recieve any messages from chat: if we are in exception list, even if it allows any kind of events for bot # N.B. there is situation when we do not recieve any messages from chat: if we
# are in exception list, even if it allows any kind of events for bot
# If we are just member of chat, it looks like we obey general chat restrictions, so we need only to query getChat in this case # If we are just member of chat, it looks like we obey general chat restrictions,
# so we need only to query getChat in this case
# If we admin, we can get|send messages even if group by itself disallows it. # If we admin, we can get|send messages even if group by itself disallows it.
# works only for public chats, so id shoud be < 0. # works only for public chats, so id shoud be < 0.
if ($chatid < 0) { if ($chatid < 0) {
my $chatobj = getChat ($self, $chatid); my $chatobj = getChat ($self, $chatid);
# actually evaluates to 1 for true and to 0 for false # actually evaluates to 1 for true and to 0 for false
$group_talk = int ($chatobj->{permissions}->{can_send_messages}); $group_talk = int ($chatobj->{permissions}->{can_send_messages});
}
my $chatObj = getChatMember ($self, $chatid, $myid); my $chatObj = getChatMember ($self, $chatid, $myid);
if ($chatObj->{'status'} eq 'administrator') { if ($chatObj->{'status'} eq 'administrator') {
logger "can talk in $chatname"; logger "I can talk in group chat $chatname ($chatid)";
$can_talk = 1; $can_talk = 1;
} else { } else {
logger "can talk in $chatname" if ($group_talk); logger "I can talk in group chat $chatname ($chatid)" if ($group_talk);
logger "can not talk in $chatname" unless ($group_talk); logger "I can not talk in group chat $chatname ($chatid)" unless ($group_talk);
$can_talk = $group_talk; $can_talk = $group_talk;
} }
} else { } else {
logger "mute in $chatid"; # private chat, so definely can talk
logger "I can talk in private chat $chatname ($chatid)";
$can_talk = 1;
} }
my $phrase;
if (($msg->{'new_chat_members'}) && $can_talk) {
# we have newcommers here
my $newcommer;
if ($msg->{'new_chat_members'}->can('first_name')) {
$newcommer .= $msg->{'new_chat_members'}->first_name;
if ($msg->{'new_chat_members'}->can('last_name')) {
$newcommer .= ' ' . $msg->{'new_chat_members'}->last_name;
}
} elsif ($msg->{'new_chat_members'}->can('last_name')) {
$newcommer .= $msg->{'new_chat_members'}->last_name;
} elsif ($msg->{'new_chat_members'}->can('username')) {
$newcommer .= $msg->{'new_chat_members'}->username;
}
if ($newcommer) {
$msg->reply("Дратути, $newcommer. Представьтес, пожалуйста, и расскажите, что вас сюда привело.");
logger "newcommer $newcommer in $chatid";
} else { } else {
logger "newcommer in $chatid"; logger "Unable to get chatid";
$msg->reply("Дратути. Представьтес, пожалуйста, и расскажите, что вас сюда привело.");
} }
# according api user must have username and/or first_name and/or last_name at least one of these fields
if ($msg->can ('from') && defined ($msg->from)) {
$userid = $msg->from->id; # it must be filled, so do not check it
$username = $msg->from->username if ($msg->from->can ('username') && defined($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;
}
$vis_a_vi = visavi ($userid, $username, $fullname);
}
my $phrase = '';
# Newcommer event, greet our new member and suggest to introduce themself.
if ($msg->can ('new_chat_members') && defined ($msg->new_chat_members)) {
my $send_args;
$send_args->{parse_mode} = 'Markdown';
$send_args->{chat_id} = $chatid;
if (defined ($username)) {
if (defined ($fullname)) {
logger "Newcommer in $chatname ($chatid): \@$username, $fullname";
$send_args->{text} = "Дратути, [$fullname](mention:\@$username). Представьтес, пожалуйста, и расскажите, что вас сюда привело.";
} else {
logger "Newcommer in $chatname ($chatid): \@$username";
$send_args->{text} = "Дратути, [$username](mention:\@$username). Представьтес, пожалуйста, и расскажите, что вас сюда привело.";
}
} else {
logger "Newcommer in $chatname ($chatid): $fullname";
$send_args->{text} = "Дратути, [$fullname](mention:$fullname). Представьтес, пожалуйста, и расскажите, что вас сюда привело.";
}
Telegram::Bot::Brain::sendMessage ($self, $send_args);
return; return;
} }
# lazy init chat-bot brains # lazy init chat-bot brains
unless (defined($hailo->{$chatid})) { unless (defined ($hailo->{$chatid})) {
$hailo->{$chatid} = Hailo->new( my $brainname = sprintf ("%s/%s.brain.sqlite", $c->{telegrambot}->{braindir}, $chatid);
$hailo->{$chatid} = Hailo->new (
# we'll got file like this: data/telegrambot-brains/-1001332512695.brain.sqlite # we'll got file like this: data/telegrambot-brains/-1001332512695.brain.sqlite
brain => sprintf("%s/%s.brain.sqlite", $c->{telegrambot}->{braindir}, $chatid), brain => $brainname,
order => 3 order => 3
); );
if ($chatid < 0) {
logger "Initialized brain for public chat $chatname ($chatid): $brainname";
} else {
logger "Initialized for private chat $chatname ($chatid): $brainname";
}
} }
# is this a 1-on-1 ? # is this a 1-on-1 ?
if ($msg->chat->type eq 'private') { if ($msg->chat->type eq 'private') {
return unless(defined($msg->text)); # TODO: what about stickers, photos, documents, audio, video, etc... We should log em at least.
my $text = $msg->text; return unless ($msg->can ('text') && defined ($msg->text));
my $csign = quotemeta($c->{telegrambot}->{csign});
my $reply;
if (substr($text, 0, 1) eq $c->{telegrambot}->{csign}) { my $text = $msg->text;
if (substr($text, 1) eq "ping") { logger sprintf ("Private chat %s say to bot: %s", $vis_a_vi, $text);
my $csign = quotemeta ($c->{telegrambot}->{csign});
my $reply = "Давайте ещё пообщаемся, а то я ещё не научилась от вас плохому.";
# TODO: Process commands in separate sub, they are same for public and private chats.
if (substr ($text, 0, 1) eq $c->{telegrambot}->{csign}) {
if (substr ($text, 1) eq "ping") {
$reply = "Pong."; $reply = "Pong.";
} elsif (substr($text, 1) eq "пинг") { } elsif (substr ($text, 1) eq "пинг") {
$reply = "Понг."; $reply = "Понг.";
} elsif (substr($text, 1, 1) eq 'w' || substr($text, 1, 1) eq 'п') { } elsif (substr ($text, 1, 2) eq 'w ' || substr ($text, 1, 2) eq 'п ') {
my $city = substr($text, 2); my $city = substr ($text, 2);
$reply = weather($city); $reply = weather ($city);
} else { } else {
$reply = "Чего?"; $reply = "Чего?";
} }
} else { } else {
$reply = $hailo->{$msg->chat->id}->learn_reply($text); my $str = $hailo->{$msg->chat->id}->learn_reply ($text);
if (defined ($str) && $str ne '') {
$reply = $str;
# TODO: move it to telegramlib.pm/botlib.pm!
$phrase = trim ($text);
while ($phrase =~ /[\.|\,|\?|\!]$/) {
chop $phrase;
} }
if (defined($reply) && $reply ne '') { $phrase = lc ($phrase);
$msg->reply($reply);
logger ("private chat reply: $reply"); if (lc ($reply) eq $phrase) {
} else { $reply = randomCommonPhrase();
# if we have no answer, say something default in private chat } elsif (lc ($reply) eq substr ($phrase, 0, -1)) {
$msg->reply("Давайте ещё пообщаемся, а то я ещё не научилась от вас плохому."); # in case of trailing dot
$reply = randomCommonPhrase();
} elsif (substr (lc ($reply), 0, -1) eq $phrase) {
$reply = randomCommonPhrase();
} }
}
}
logger sprintf ("Private chat bot reply to $vis_a_vi: %s", $reply);
$msg->reply ($reply);
# group chat # group chat
} elsif (($msg->chat->type eq 'supergroup') or ($msg->chat->type eq 'group')) { } elsif (($msg->chat->type eq 'supergroup') or ($msg->chat->type eq 'group')) {
my $reply; my $reply;
unless(defined($msg->text)) { # detect and log messages without text, noop here
logger "No text in message"; unless (defined ($msg->text)) {
logger Dumper($msg); logger sprintf("No text in message from %s", $vis_a_vi);
if ($msg->can ('document') && defined ($msg->document)) {
if (defined ($msg->document->{'file_name'})) {
my $docsize = 'unknown';
$docsize = $msg->document->{'file_size'} if (defined ($msg->document->{'file_size'}));
my $type = 'unknown';
$type = $msg->document->{'mime_type'} if (defined ($msg->document->{'mime_type'}));
logger sprintf ("In public chat %s (%s) %s send document type %s named %s, size %s bytes", $chatname, $chatid, $vis_a_vi, $type, $msg->document->{'file_name'}, $docsize);
} else {
logger sprintf ("In public chat %s (%s) %s send unknown document", $chatname, $chatid, $vis_a_vi);
}
} elsif ($msg->can ('sticker') && defined ($msg->sticker)) {
my $set_name = 'unknown';
$set_name = $msg->sticker->set_name if ($msg->sticker->can ('set_name') && defined ($msg->sticker->set_name));
my $emoji = 'unknown';
$emoji = $msg->sticker->emoji if ($msg->sticker->can ('emoji') && defined ($msg->sticker->emoji));
logger sprintf ("In public chat %s (%s) %s reacted with sticker %s from pack %s", $chatname, $chatid, $vis_a_vi, $emoji, $set_name);
} elsif ($msg->can ('photo') && defined ($msg->photo)) {
# actually it is an array! duh, hate arrays!
logger sprintf ("In public chat %s (%s) %s send photo", $chatname, $chatid, $vis_a_vi);
} else {
logger Dumper ($msg);
}
return; return;
} }
# we have text here! so potentially we can chit-chat
my $text = $msg->text; my $text = $msg->text;
# sometimes shit happens? logger sprintf ("In public chat %s (%s) %s say: %s", $chatname, $chatid, $vis_a_vi, $text);
return unless(defined($text)); my $qname = quotemeta ($c->{telegrambot}->{name});
my $qtname = quotemeta ($c->{telegrambot}->{tname});
my $csign = quotemeta ($c->{telegrambot}->{csign});
my $qname = quotemeta($c->{telegrambot}->{name}); # are they quote something, maybe, us?
my $qtname = quotemeta($c->{telegrambot}->{tname}); if (defined ($msg->reply_to_message) &&
my $csign = quotemeta($c->{telegrambot}->{csign}); defined ($msg->reply_to_message->from) &&
defined ($msg->reply_to_message->from->username) &&
($msg->reply_to_message->from->username eq $myusername)) {
logger sprintf ("In public chat %s (%s) %s quote us!", $chatname, $chatid, $vis_a_vi);
# remove our name from users reply, just in case
my $pat1 = quotemeta ('@' . $myusername);
my $pat2 = quotemeta ($myfullname);
$phrase = $text;
$phrase =~ s/$pat1//g;
$phrase =~ s/$pat2//g;
# simple commands # figure out reply :)
if (substr($text, 0, 1) eq $c->{telegrambot}->{csign}) { $reply = $hailo->{$msg->chat->id}->learn_reply ($phrase);
if (substr($text, 1) eq "help") { # simple commands
# TODO: Process commands in separate sub, they are same for public and private chats.
# TODO: Log commands and answers
} elsif (substr ($text, 0, 1) eq $c->{telegrambot}->{csign}) {
if (substr ($text, 1) eq "help") {
return unless ($can_talk); return unless ($can_talk);
my $send_args; my $send_args;
$send_args->{text} = '``` $send_args->{text} = '```
@@ -181,72 +301,72 @@ sub __on_msg {
'; ';
$send_args->{parse_mode} = 'Markdown'; $send_args->{parse_mode} = 'Markdown';
$send_args->{chat_id} = $chatid; $send_args->{chat_id} = $chatid;
Telegram::Bot::Brain::sendMessage($self, $send_args); Telegram::Bot::Brain::sendMessage ($self, $send_args);
return; return;
} elsif (substr($text, 1) eq "ping") { } elsif (substr ($text, 1) eq "ping") {
$reply = "Pong."; $reply = "Pong.";
} elsif (substr($text, 1) eq "пинг") { } elsif (substr ($text, 1) eq "пинг") {
$reply = "Понг."; $reply = "Понг.";
} elsif (substr($text, 1) eq "pong") { } elsif (substr ($text, 1) eq "pong") {
$reply = "Wat?"; $reply = "Wat?";
} elsif (substr($text, 1) eq "понг") { } elsif (substr ($text, 1) eq "понг") {
$reply = "Шта?"; $reply = "Шта?";
} elsif (substr($text, 1, 2) eq 'w ' || substr($text, 1, 2) eq 'п ') { } elsif (substr ($text, 1, 2) eq 'w ' || substr ($text, 1, 2) eq 'п ') {
my $city = substr($text, 3); my $city = substr ($text, 3);
$reply = weather($city); $reply = weather ($city);
} }
} elsif ( } elsif (
($text eq $qname) or ($text eq $qname) or
($text eq sprintf("%s", $qtname)) or ($text eq sprintf ("%s", $qtname)) or
($text eq sprintf("@%s_bot", $qname)) or # :( ($text eq sprintf ("@%s_bot", $qname)) or # :(
($text eq sprintf("%s ", $qtname)) ($text eq sprintf ("%s ", $qtname))
) { ) {
$reply = "Чего?"; $reply = "Чего?";
} else { } else {
# phrase directed to bot # phrase directed to bot
if ((lc($text) =~ /^${qname}[\,|\:]? (.+)/) or (lc($text) =~ /^${qtname}[\,|\:]? (.+)/)){ if ((lc ($text) =~ /^${qname}[\,|\:]? (.+)/) or (lc ($text) =~ /^${qtname}[\,|\:]? (.+)/)){
$phrase = $1; $phrase = $1;
$reply = $hailo->{$msg->chat->id}->learn_reply($phrase); $reply = $hailo->{$msg->chat->id}->learn_reply ($phrase);
# bot mention by name # bot mention by name
} elsif ((lc($text) =~ /.+ ${qname}[\,|\!|\?|\.| ]/) or (lc($text) =~ / $qname$/)) { } elsif ((lc ($text) =~ /.+ ${qname}[\,|\!|\?|\.| ]/) or (lc ($text) =~ / $qname$/)) {
$phrase = $text; $phrase = $text;
$reply = $hailo->{$msg->chat->id}->reply($phrase); $reply = $hailo->{$msg->chat->id}->reply($phrase);
# bot mention by telegram name # bot mention by telegram name
} elsif ((lc($text) =~ /.+ ${qtname}[\,|\!|\?|\.| ]/) or (lc($text) =~ / $qtname$/)) { } elsif ((lc ($text) =~ /.+ ${qtname}[\,|\!|\?|\.| ]/) or (lc ($text) =~ / $qtname$/)) {
$phrase = $text; $phrase = $text;
$reply = $hailo->{$msg->chat->id}->reply($phrase); $reply = $hailo->{$msg->chat->id}->reply ($phrase);
# just message in chat # just message in chat
} else { } else {
$hailo->{$msg->chat->id}->learn($text); $hailo->{$msg->chat->id}->learn ($text);
} }
} }
if (defined($reply) && $reply ne '' && $can_talk) { if (defined ($reply) && $reply ne '' && $can_talk) {
# work a bit more on input phrase # work a bit more on input phrase
$phrase = trim($phrase); $phrase = trim ($phrase);
while ($phrase =~ /[\.|\,|\?|\!]$/) { while ($phrase =~ /[\.|\,|\?|\!]$/) {
chop $phrase; chop $phrase;
} }
$phrase = lc($phrase); $phrase = lc ($phrase);
if (lc($reply) eq $phrase) { if (lc ($reply) eq $phrase) {
$reply = randomCommonPhrase(); $reply = randomCommonPhrase();
} elsif (lc($reply) eq substr($phrase, 0, -1)) { } elsif (lc ($reply) eq substr ($phrase, 0, -1)) {
# in case of trailing dot # in case of trailing dot
$reply = randomCommonPhrase(); $reply = randomCommonPhrase();
} elsif (substr(lc($reply), 0, -1) eq $phrase) { } elsif (substr(lc ($reply), 0, -1) eq $phrase) {
$reply = randomCommonPhrase(); $reply = randomCommonPhrase();
} }
logger ("reply with: $reply"); logger sprintf ("In public chat %s (%s) bot reply to %s: %s", $chatname, $chatid, $vis_a_vi, $reply);
$msg->reply($reply); $msg->reply ($reply);
} else { } else {
if ($can_talk) { if ($can_talk) {
logger ("no reply"); logger sprintf ("In public chat %s (%s) bot is not required to reply to %s", $chatname, $chatid, $vis_a_vi);
} else { } else {
logger ("Can't talk, but reply is: $reply"); logger sprintf ("In public chat %s (%s) bot can't talk, but reply to %s is: %s", $chatname, $chatid, $vis_a_vi, $reply);
} }
} }
@@ -265,7 +385,7 @@ sub init {
} }
my $self = shift; my $self = shift;
$self->add_listener(\&__on_msg); $self->add_listener (\&__on_msg);
# $self->add_repeating_task(900, \&__cron); # $self->add_repeating_task(900, \&__cron);
} }
@@ -277,41 +397,6 @@ sub run_telegrambot {
} }
} }
# complete framework with our getChat()
sub getChat {
my $self = shift;
my $id = shift;
my $send_args = {};
$send_args->{chat_id} = $id;
my $token = $self->token;
my $url = "https://api.telegram.org/bot${token}/getChat";
my $api_response = $self->_post_request($url, $send_args);
# we seek for permissions, when making call to this subroutine, but
# framework does just omits it, when creating object from hash, so
# pick raw json object instead
#return Telegram::Bot::Object::User->create_from_hash($api_response, $self);
return $api_response;
}
# complete framework with our getChatMember()
sub getChatMember {
my $self = shift;
my $chatid = shift;
my $userid = shift;
my $send_args = {};
$send_args->{chat_id} = $chatid;
$send_args->{user_id} = $userid;
my $token = $self->token;
my $url = "https://api.telegram.org/bot${token}/getChatMember";
my $api_response = $self->_post_request($url, $send_args);
# return Telegram::Bot::Object::User->create_from_hash($api_response, $self);
return $api_response;
}
1; 1;
# vim: ft=perl noet ai ts=4 sw=4 sts=4: # vim: ft=perl noet ai ts=4 sw=4 sts=4:

68
lib/telegramlib.pm Normal file
View File

@@ -0,0 +1,68 @@
package telegramlib;
# store here functions that are not implemented in Telegram::Bot
use 5.018;
use strict;
use warnings "all";
use utf8;
use open qw(:std :utf8);
use botlib qw(trim);
use Telegram::Bot::Brain;
# module shit
use vars qw/$VERSION/;
use Exporter qw(import);
our @EXPORT = qw(getChat getChatMember visavi);
$VERSION = "1.0";
# complete framework with our getChat()
sub getChat {
my $self = shift;
my $id = shift;
my $send_args = {};
$send_args->{chat_id} = $id;
my $token = $self->token;
my $url = "https://api.telegram.org/bot${token}/getChat";
my $api_response = $self->_post_request ($url, $send_args);
# we seek for permissions, when making call to this subroutine, but
# framework does just omits it, when creating object from hash, so
# pick raw json object instead
#return Telegram::Bot::Object::User->create_from_hash($api_response, $self);
return $api_response;
}
# complete framework with our getChatMember()
sub getChatMember {
my $self = shift;
my $chatid = shift;
my $userid = shift;
my $send_args = {};
$send_args->{chat_id} = $chatid;
$send_args->{user_id} = $userid;
my $token = $self->token;
my $url = "https://api.telegram.org/bot${token}/getChatMember";
my $api_response = $self->_post_request ($url, $send_args);
# return Telegram::Bot::Object::User->create_from_hash($api_response, $self);
return $api_response;
}
sub visavi (@) {
my ($userid, $username, $fullname) = @_;
my $name = '';
if (defined ($username)) {
$name .= '@' . $username;
$name .= ', ' . $fullname if (defined ($fullname));
} else {
$name .= $fullname;
}
$name .= " ($userid)";
return $name;
}