Compare commits
6 Commits
ea634710f1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cec2f2f875 | ||
|
|
a4d0afab5d | ||
|
|
75d0e07c6d | ||
|
|
b503fec769 | ||
|
|
c9e664b4e5 | ||
|
|
e552ecbf00 |
73
README.md
73
README.md
@@ -2,35 +2,31 @@
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This version - 3 (something) - considered stable. It means that further
|
||||
development of new features kind of frosen. Most effort will be targeted to
|
||||
future 4-th version development. If you have some ideas or fixes to this version
|
||||
This version - 3 (something) - considered stable. It means that further development of new features kind of frosen.
|
||||
Most effort will be targeted to future 4-th version development. If you have some ideas or fixes to this version
|
||||
feel free PR them, they will be merged as soon as being reviewed.
|
||||
|
||||
## About
|
||||
|
||||
It is based on Perl modules [Telegram::Bot][1] and [Hailo][2] as conversation
|
||||
generator.
|
||||
It is based on Perl modules [Telegram::Bot][1] and [Hailo][2] as conversation generator.
|
||||
|
||||
I have to fork [Telegram::Bot][1] and update it according to features appeared
|
||||
in [Telegram Bot API v5][3]. Also, I decide to rename it to avoid collision in
|
||||
the future, now it is Teapot::Bot and is bundled with bot. When lib becomes
|
||||
I have to fork [Telegram::Bot][1] and update it according to features appeared in [Telegram Bot API v5][3]. Also,
|
||||
I decide to rename it to avoid collision in the future, now it is Teapot::Bot and is bundled with bot. When lib becomes
|
||||
mature enough, maybe I release it separately.
|
||||
|
||||
Bot config located in **data/config.json**, sample config provided as
|
||||
**data/sample_config.json**.
|
||||
Bot config located in **data/config.json**, sample config provided as **data/sample_config.json**.
|
||||
|
||||
Bot can be run via **bin/aleesa-telegram-bot** and acts as daemon (double fork()
|
||||
and detaches stdio).
|
||||
Bot can be run via **bin/aleesa-telegram-bot** and acts as daemon (double fork() and detaches stdio).
|
||||
|
||||
## Installation
|
||||
|
||||
In order to run this application, you need to "bootstrap" it - download and build
|
||||
all required dependencies and libraries.
|
||||
Application have been tested on alpine linux x86_64 3.12, with perl-5.32.1 builtin.
|
||||
|
||||
You'll need perl-5.18 or newer, "Development Tools" or similar group of
|
||||
packages, perl, perl-devel, perl-local-lib, perl-app-cpanm, sqlite-devel,
|
||||
zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make.
|
||||
In order to run this application, you need to "bootstrap" it - download and build all required dependencies and
|
||||
libraries.
|
||||
|
||||
You'll need perl-5.18 or newer, "Development Tools" or similar group of packages, perl, perl-devel, perl-local-lib,
|
||||
perl-app-cpanm, sqlite-devel, zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make.
|
||||
|
||||
After installing required dependencies it is possible to run:
|
||||
|
||||
@@ -44,56 +40,49 @@ and all libraries should be downloaded, built, tested and installed.
|
||||
|
||||
## Running
|
||||
|
||||
This bot does not [ultilize][4] webhooks, so in order to run it only well
|
||||
internet connection is required, no public-available ip address is needed.
|
||||
This bot does not [ultilize][4] webhooks, so in order to run it only well internet connection is required, no
|
||||
public-available ip address is needed.
|
||||
|
||||
### Additional Settings to be performed in order to run bot as it designed
|
||||
|
||||
There are some "plugins" that requires registration on third party services
|
||||
and API keys and secrets in order to work.
|
||||
There are some "plugins" that requires registration on third party services and API keys and secrets in order to work.
|
||||
|
||||
#### OpenWeatherMap
|
||||
|
||||
You should [register][5], [login][6] and [create][7] api key. Free plan have
|
||||
all required features to run this "plugin".
|
||||
You should [register][5], [login][6] and [create][7] api key. Free plan have all required features to run this "plugin".
|
||||
|
||||
Once key is created you should put it in **config.json** under openweathermap
|
||||
section as appid. Thats it.
|
||||
Once key is created you should put it in **config.json** under openweathermap section as appid. Thats it.
|
||||
|
||||
It is still impossible to disable this plugin, but "I'm working on it".
|
||||
|
||||
#### Imgur
|
||||
|
||||
This plugin "just exists" and is actually used nowhere around the code.
|
||||
Anyway, to make use of it besides registering appropriate handler in code, you
|
||||
should sign in imgur and get access token.
|
||||
This plugin "just exists" and is actually used nowhere around the code. Anyway, to make use of it besides registering
|
||||
appropriate handler in code, you should sign in imgur and get access token.
|
||||
|
||||
Actually at this time this "plugin" can be stub-ed with default config values.
|
||||
|
||||
Anyway, to fetch access token you should [login][8] and perform [registration][9]
|
||||
of your app. Then you should authorize your app according to [this][10] manual. Or
|
||||
[this][11] one.
|
||||
Anyway, to fetch access token you should [login][8] and perform [registration][9] of your app. Then you should
|
||||
authorize your app according to [this][10] manual. Or [this][11] one.
|
||||
|
||||
#### Flickr
|
||||
|
||||
This "plugin" is really used to implement random picture link retrival plugins.
|
||||
|
||||
There is helper script in **bin/flickr_init.pl** that helps to get all required keys
|
||||
and secrets from flickr api.
|
||||
There is helper script in **bin/flickr_init.pl** that helps to get all required keys and secrets from flickr api.
|
||||
|
||||
Before using it bot must be bootstrapped via **`bootstrap.sh`**.
|
||||
|
||||
[Login][11] and create an [app][12] in your flickr account. Then *logout* flickr account.
|
||||
(It is required in order to properly get "verifier" parameter later).
|
||||
[Login][11] and create an [app][12] in your flickr account. Then *logout* flickr account. (It is required in order to
|
||||
properly get "verifier" parameter later).
|
||||
|
||||
Put your [app key and secret][13] to **config.json**. Ensure that "verifier" parameter
|
||||
in Flickr-related part of config either absent or commented out.
|
||||
Put your [app key and secret][13] to **config.json**. Ensure that "verifier" parameter in Flickr-related part of config
|
||||
either absent or commented out.
|
||||
|
||||
Run **bin/flickr_init.pl** first time and follow on screen instructions - copy and
|
||||
paste given link to browser login to flickr account and you'll be redirected to
|
||||
example.com. Check address bar in browser to get so-called "verifier", put it in
|
||||
**config.json**. Then run **bin/flickr_init.pl** again to store API access token in db
|
||||
under data/image directory (in default config). You're done.
|
||||
Run **bin/flickr_init.pl** first time and follow on screen instructions - copy and paste given link to browser login to
|
||||
flickr account and you'll be redirected to example.com. Check address bar in browser to get so-called "verifier", put
|
||||
it in **config.json**. Then run **bin/flickr_init.pl** again to store API access token in db under data/image directory
|
||||
(in default config). You're done.
|
||||
|
||||
[1]: https://metacpan.org/pod/Telegram::Bot
|
||||
[2]: https://metacpan.org/pod/Hailo
|
||||
|
||||
91
README_RU.md
91
README_RU.md
@@ -2,40 +2,35 @@
|
||||
|
||||
## Дисклеймер
|
||||
|
||||
Эта версия бота за номером 3 (с мелочью) стабильная. Сие означает, что
|
||||
дальнейшего развития функций в этой версии не предполагается. Конечно, возможны
|
||||
исключения, но основной план - переключиться на 4-ю версию, куда планируется
|
||||
Эта версия бота за номером 3 (с мелочью) стабильная. Сие означает, что дальнейшего развития функций в этой версии не
|
||||
предполагается. Конечно, возможны исключения, но основной план - переключиться на 4-ю версию, куда планируется
|
||||
перенести большинство функций 3-й версии.
|
||||
|
||||
Если у кого-то возникнут идеи относительно этой версии бота ставьте PR, я только
|
||||
рад. Т.к. несмотря на то, что развитие этой версии слегка заморожено,
|
||||
поддерживать её планируется до выхода в свет 4-й версии бота.
|
||||
Если у кого-то возникнут идеи относительно этой версии бота - ставьте PR, я только рад. Т.к. несмотря на то, что
|
||||
развитие этой версии "слегка" заморожено, поддерживать её планируется как минимум до выхода в свет 4-й версии бота.
|
||||
|
||||
## Что это такое
|
||||
|
||||
Это бот, основанный на перловых модулях [Telegram::Bot][1] для работы в
|
||||
мессенджере Telegram и [Hailo][2] для генерации "умной" беседы.
|
||||
Это бот, основанный на перловых модулях [Telegram::Bot][1] для работы в мессенджере Telegram и [Hailo][2] для генерации
|
||||
"умной" беседы.
|
||||
|
||||
Для корректной работы, пришлось форкнуть [Telegram::Bot][1], чтобы обновить
|
||||
интерфейс API до [Telegram Bot API v5][3]. Для избежания неоднозначностей, модуль
|
||||
пришлось переименовать и теперь он идёт в составе бота. Возможно, когда модуль
|
||||
отлежится и будет похож на стабильный, он стнет самостоятельным и поселится на
|
||||
metacpan.org
|
||||
Для корректной работы, пришлось форкнуть [Telegram::Bot][1], чтобы обновить интерфейс API до [Telegram Bot API v5][3].
|
||||
Для избежания неоднозначностей, модуль пришлось переименовать и теперь он идёт в составе бота. Возможно, когда модуль
|
||||
отлежится и будет похож на стабильный, он стнет самостоятельным и поселится на metacpan.org
|
||||
|
||||
Конфиг бота должен лежать в **data/config.json**. Пример конфига расположен в
|
||||
**data/sample_config.json**.
|
||||
Конфиг бота должен лежать в **data/config.json**. Пример конфига расположен в **data/sample_config.json**.
|
||||
|
||||
Бота можно запустить через **bin/aleesa-telegram-bot** и он взлетит, как юниксовый
|
||||
демон (сделает двойной fork() и отцепится от stdio).
|
||||
Бота можно запустить через **bin/aleesa-telegram-bot** и он взлетит, как юниксовый демон (сделает двойной fork() и
|
||||
отцепится от stdio).
|
||||
|
||||
## Установка
|
||||
|
||||
Чтобы запустить приложение, его надо "забурстрапить" - загрузить и собрать все
|
||||
необходимые зависимости.
|
||||
Приложение тестировалось на alpine linux x86_64 3.12, со встроенным perl-5.32.1.
|
||||
|
||||
Понадобится perl-5.18, а желательно новее, "Development Tools" или подобная
|
||||
группа пакетов , perl, perl-devel, perl-local-lib, perl-app-cpanm, sqlite-devel,
|
||||
zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make.
|
||||
Чтобы запустить приложение, его надо "забурстрапить" - загрузить и собрать все необходимые зависимости.
|
||||
|
||||
Понадобится perl-5.18, а желательно новее, "Development Tools" или подобная группа пакетов , perl, perl-devel,
|
||||
perl-local-lib, perl-app-cpanm, sqlite-devel, zlib-devel, openssl-devel, libdb4-devel (Berkeley DB devel), make.
|
||||
|
||||
После установки этих пакетов, можно будет запустить:
|
||||
|
||||
@@ -49,56 +44,50 @@ bash bootstrap.sh
|
||||
|
||||
## Запуск и работа
|
||||
|
||||
Бот не использует [вебхуки][4], поэтому ничего дополнительного, кроме хорошего
|
||||
подключения к интернету ему не нужно.
|
||||
Бот не использует [вебхуки][4], поэтому ничего дополнительного, кроме хорошего подключения к интернету ему не нужно.
|
||||
|
||||
### Дополнительные настройки
|
||||
|
||||
Некоторые "плагины" требуют регистрации в сторонних сервисах (API keys, secrets
|
||||
итд), чтобы бот не сыпал ошибками в логи (возможно, в дальнейшем возможно будет
|
||||
отключить эти плагины).
|
||||
Некоторые "плагины" требуют регистрации в сторонних сервисах (API keys, secrets итд), чтобы бот не сыпал ошибками в
|
||||
логи (возможно, в дальнейшем возможно будет отключить эти плагины).
|
||||
|
||||
#### OpenWeatherMap
|
||||
|
||||
Для работы погодного плагина, надо [заргистрироваться][5], [залогиниться][6] и
|
||||
[создать][7] api key. Free plan предлагает всё необхдимое для работы "плагина".
|
||||
Для работы погодного плагина, надо [заргистрироваться][5], [залогиниться][6] и [создать][7] api key. Free plan
|
||||
предлагает всё необхдимое для работы "плагина".
|
||||
|
||||
Когда api key будет создан, его нужно вписать в **config.json** "секцию"
|
||||
openweathermap в качестве appid. На этом всё.
|
||||
Когда api key будет создан, его нужно вписать в **config.json** "секцию" openweathermap в качестве appid. На этом всё.
|
||||
|
||||
#### Imgur
|
||||
|
||||
Этот плагин "просто есть" и его на самом деле ничто и никто не использует. И в
|
||||
этой связи все настройки плагина можно оставить "как есть" в примере конфига.
|
||||
Этот плагин "просто есть" и его на самом деле ничто и никто не использует. И в этой связи все настройки плагина можно
|
||||
оставить "как есть" в примере конфига.
|
||||
|
||||
Тем не менее, если есть большое желание, то можно [залогиниться][8] и
|
||||
[зарегистрировать][9] бота как приложение, а потом разрешить приложению
|
||||
пользоваться API-шкой, как описано в [этом][10] или [этом][11] мануале.
|
||||
Тем не менее, если есть большое желание, то можно [залогиниться][8] и [зарегистрировать][9] бота как приложение, а
|
||||
потом разрешить приложению пользоваться API-шкой, как описано в [этом][10] или [этом][11] мануале.
|
||||
|
||||
#### Flickr
|
||||
|
||||
Этот "плагин" действительно используется для добычи ссылок на картинки в разных
|
||||
"картиночных" командах бота.
|
||||
Этот "плагин" действительно используется для добычи ссылок на картинки в разных "картиночных" командах бота.
|
||||
|
||||
Есть скрипт, который поможет с регистрацией приложения в api Flickr -
|
||||
**bin/flickr_init.pl**, он достанет все нужные ключи и секреты к ним.
|
||||
Есть скрипт, который поможет с регистрацией приложения в api Flickr - **bin/flickr_init.pl**, он достанет все нужные
|
||||
ключи и секреты к ним.
|
||||
|
||||
До запуска этого скрипта, бот должен быть забутстраплен через **`bootstrap.sh`**.
|
||||
|
||||
[Залогиньтесь][11] и создайте [app][12] in своём Flicker-овском аккаунте. Далее,
|
||||
*разлогиньтесь*, это нужно, чтобы потом проще было достать параметр verifier.
|
||||
[Залогиньтесь][11] и создайте [app][12] in своём Flicker-овском аккаунте. Далее, *разлогиньтесь*, это нужно, чтобы
|
||||
потом проще было достать параметр verifier.
|
||||
|
||||
Запишите [app key и secret][13] в **config.json**. Удостоверьтесь, что параметр
|
||||
"verifier" в конфиге либо закоменчен, либо отсутствует.
|
||||
Запишите [app key и secret][13] в **config.json**. Удостоверьтесь, что параметр "verifier" в конфиге либо закоменчен,
|
||||
либо отсутствует.
|
||||
|
||||
Запустите **bin/flickr_init.pl** и следуте предлагаемым инструкциям - в итоге
|
||||
будет дана ссылка, которую надо скопипастить в браузер. По ссылке предложат
|
||||
залогиниться, далее надо будет разрешить приложению просматривать профиль и,
|
||||
через один-два редиректа, вы попадёте на example.com. Из адресной строки браузера
|
||||
надо скопировать параметр "verifier" и вписать его в **config.json**.
|
||||
Запустите **bin/flickr_init.pl** и следуте предлагаемым инструкциям - в итоге будет дана ссылка, которую надо
|
||||
скопипастить в браузер. По ссылке предложат залогиниться, далее надо будет разрешить приложению просматривать профиль
|
||||
и, через один-два редиректа, вы попадёте на example.com. Из адресной строки браузера надо скопировать параметр
|
||||
"verifier" и вписать его в **config.json**.
|
||||
|
||||
Чтобы сохранить в бд плагина API access token для нормальной работы "плагина",
|
||||
второй раз запустите **bin/flickr_init.pl**. На этом всё.
|
||||
Чтобы сохранить в бд плагина API access token для нормальной работы "плагина", второй раз запустите
|
||||
**bin/flickr_init.pl**. На этом всё.
|
||||
|
||||
[1]: https://metacpan.org/pod/Telegram::Bot
|
||||
[2]: https://metacpan.org/pod/Hailo
|
||||
|
||||
73
cpanfile
73
cpanfile
@@ -1,34 +1,39 @@
|
||||
requires 'Carp';
|
||||
requires 'CHI';
|
||||
requires 'CHI::Driver::BerkeleyDB';
|
||||
requires 'Cwd::utf8';
|
||||
requires 'DateTime';
|
||||
requires 'DB_File';
|
||||
requires 'SQLite_File';
|
||||
requires 'DBI';
|
||||
requires 'DBD::SQLite';
|
||||
requires 'Digest::HMAC_SHA1';
|
||||
requires 'Digest::MD5';
|
||||
requires 'Data::Dumper';
|
||||
requires 'Digest::SHA';
|
||||
requires 'File::Basename';
|
||||
requires 'File::Path';
|
||||
requires 'Hailo';
|
||||
requires 'HTML::TokeParser';
|
||||
requires 'IO::Socket::SSL';
|
||||
requires 'JSON';
|
||||
requires 'JSON::XS';
|
||||
requires 'List::Util';
|
||||
requires 'local::lib';
|
||||
requires 'Log::Any';
|
||||
requires 'Log::Any::Adapter';
|
||||
requires 'Log::Any::For::Std';
|
||||
requires 'Math::Random::Secure';
|
||||
requires 'Mojo::Base';
|
||||
requires 'Mojo::IOLoop';
|
||||
requires 'Mojo::UserAgent';
|
||||
requires 'Mojo::UserAgent::Cached';
|
||||
requires 'String::Random';
|
||||
requires 'Text::Fuzzy';
|
||||
requires 'URI::Encode::XS';
|
||||
requires 'URI::URL';
|
||||
## no critic (TestingAndDebugging::RequireUseStrict,Modules::RequireVersionVar)
|
||||
## no critic (TestingAndDebugging::RequireUseWarnings,Modules::RequireExplicitPackage)
|
||||
## no critic (Modules::RequireEndWithOne)
|
||||
requires 'Carp', '==1.50';
|
||||
requires 'CHI', '==0.61';
|
||||
requires 'CHI::Driver::BerkeleyDB', '==0.05';
|
||||
requires 'Cwd::utf8', '==0.011';
|
||||
requires 'DateTime', '==1.55';
|
||||
requires 'DB_File', '==1.856';
|
||||
requires 'SQLite_File', '==0.1006';
|
||||
requires 'DBI', '==1.643';
|
||||
requires 'DBD::SQLite', '==1.70';
|
||||
requires 'Digest::HMAC_SHA1', '==1.04';
|
||||
requires 'Digest::MD5', '==2.58';
|
||||
requires 'Data::Dumper', '==2.183';
|
||||
requires 'Digest::SHA', '==6.02';
|
||||
requires 'File::Basename', '==2.85';
|
||||
requires 'File::Path', '==2.18';
|
||||
requires 'Hailo', '==0.75';
|
||||
requires 'HTML::TokeParser', '==3.76';
|
||||
requires 'IO::Socket::SSL', '==2.074';
|
||||
requires 'JSON', '==4.05';
|
||||
requires 'JSON::PP', '==4.07';
|
||||
requires 'JSON::XS', '==4.03';
|
||||
requires 'List::Util', '==1.60';
|
||||
requires 'local::lib', '==2.000028';
|
||||
requires 'Log::Any', '==1.710';
|
||||
requires 'Log::Any::Adapter', '==1.710';
|
||||
requires 'Log::Any::For::Std', '==0.05';
|
||||
requires 'Math::Random::Secure', '==0.080001';
|
||||
requires 'Mojolicious', '==9.22';
|
||||
requires 'Mojo::Base', '0';
|
||||
requires 'Mojo::IOLoop', '0';
|
||||
requires 'Mojo::UserAgent', '0';
|
||||
requires 'Mojo::UserAgent::Cached', '==1.18';
|
||||
requires 'String::Random', '==0.32';
|
||||
requires 'Text::Fuzzy', '==0.29';
|
||||
requires 'URI::Encode::XS', '==0.11';
|
||||
requires 'URI::URL', '==5.10';
|
||||
|
||||
@@ -5,6 +5,7 @@ use Mojo::Base -base;
|
||||
use List::Util qw/any/;
|
||||
use Carp qw/croak cluck/;
|
||||
use Data::Dumper;
|
||||
use JSON::PP ();
|
||||
|
||||
$Teapot::Bot::Object::Base::VERSION = '0.022';
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ sub canDeleteMessage {
|
||||
my $chatobj = $self->getChat ({ 'chat_id' => $chatid });
|
||||
|
||||
# on api error, keep silence
|
||||
unless ($chatobj) {
|
||||
if ($chatobj == 0 || $chatobj->{error}) {
|
||||
cluck "Unable to get chat info for $chatid from telegram API";
|
||||
return 0;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ sub canDeleteMessage {
|
||||
my $myObj = $self->getMe ();
|
||||
|
||||
# on api error, keep silence
|
||||
unless ($chatobj) {
|
||||
if ($myObj == 0 || $myObj->{error}) {
|
||||
cluck "Unable to get chat info for $chatid from telegram API";
|
||||
return 0;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ sub canDeleteMessage {
|
||||
my $me = $self->getChatMember ({ 'chat_id' => $chatid, 'user_id' => $myid });
|
||||
|
||||
# on api error, keep silence
|
||||
unless ($me) {
|
||||
if ($me == 0 || $me->{error}) {
|
||||
cluck 'Unable to get chat info for bot itself from telegram API';
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -39,26 +39,26 @@ sub canTalk {
|
||||
my $chatobj = $self->_brain->getChat ({ 'chat_id' => $chatid });
|
||||
|
||||
# on api error, keep silence
|
||||
unless ($chatobj) {
|
||||
if ($chatobj == 0 || $chatobj->{error}) {
|
||||
carp "Unable to get chat info for $chatid from telegram API";
|
||||
return 0;
|
||||
return $can_talk;
|
||||
}
|
||||
|
||||
my $myObj = $self->_brain->getMe ();
|
||||
|
||||
# on api error, keep silence
|
||||
unless ($chatobj) {
|
||||
if ($myObj == 0 || $myObj->{error}) {
|
||||
carp "Unable to get chat info for $chatid from telegram API";
|
||||
return 0;
|
||||
return $can_talk;
|
||||
}
|
||||
|
||||
my $myid = $myObj->id;
|
||||
my $me = $self->_brain->getChatMember ({ 'chat_id' => $chatid, 'user_id' => $myid });
|
||||
|
||||
# on api error, keep silence
|
||||
unless ($me) {
|
||||
if ($me == 0 || $me->{error}) {
|
||||
carp 'Unable to get chat info for bot itself from telegram API';
|
||||
return 0;
|
||||
return $can_talk;
|
||||
}
|
||||
|
||||
if ($me->{'status'} eq 'administrator') {
|
||||
|
||||
@@ -157,7 +157,7 @@ sub reply {
|
||||
|
||||
my $chatid = $self->chat->id;
|
||||
|
||||
if (Teapot::Bot::Object::ChatPermissions::canTalk($self, $chatid)) {
|
||||
if (Teapot::Bot::Object::ChatPermissions->canTalk($self, $chatid)) {
|
||||
return $self->_brain->sendMessage({chat_id => $chatid, text => $text});
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ sub replyMd {
|
||||
|
||||
my $chatid = $self->chat->id;
|
||||
|
||||
if (Teapot::Bot::Object::ChatPermissions::canTalk ($self, $chatid)) {
|
||||
if (Teapot::Bot::Object::ChatPermissions->canTalk ($self, $chatid)) {
|
||||
my $send_args;
|
||||
$send_args->{text} = $text;
|
||||
$send_args->{parse_mode} = 'Markdown';
|
||||
@@ -187,7 +187,7 @@ sub typing {
|
||||
|
||||
my $chatid = $self->chat->id;
|
||||
|
||||
if (Teapot::Bot::Object::ChatPermissions::canTalk ($self, $chatid)) {
|
||||
if (Teapot::Bot::Object::ChatPermissions->canTalk ($self, $chatid)) {
|
||||
return $self->_brain->sendChatAction({chat_id => $chatid});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user