diff --git a/README_RU.md b/README_RU.md new file mode 100644 index 0000000..c75c0e7 --- /dev/null +++ b/README_RU.md @@ -0,0 +1,103 @@ +# Aleesa-Telegram-bot - Болтливый бот для Telegram + +## Что это такое + +Это бот основанный на перловых модулях [Telegram::Bot][1] для работы в +мессенджере Telegram и [Hailo][2] для генерации "умной" беседы. + +Для корректной работы пришлось форкнуть [Telegram::Bot][1] чтобы обновить +интерфейс API до [Telegram Bot API v5][3]. Для избежания неоднозначностей модуль +пришлось переименовать и теперь он идёт в составе бота. Возможно, когда модуль +отлежится и будет похож на стабильный, он стнет самостоятельным и поселится на +metacpan.org + +Конфиг бота должен лежать в **data/config.json**, пример конфига расположен в +**data/sample_config.json**. + +Бота можно запустить через **bin/aleesa-telegram-bot** и он взлетит как юниксовый +демон (сделает двойной fork() и отцепится от stdio). + +## Установка + +Чтобы запустить приложение, его надо "забурстрапить" - загрузить и собрать все +необходимые зависимости. + +Понадобится 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. + +После установки этих пакетов можно будет запустить: + +```bash + +bash bootstrap.sh + +``` + +и по идее всё что нужно будет выкачено, собрано и разложено куда надо. + +## Запуск и работа + +Бот не использует [вебхуки][4], поэтому ничего дополнительного, кроме хорошего +подключения к интернету ему не нужно. + +### Дополнительные настройки + +Некоторые "плагины" требуют регистрации в сторонних сервисах (API keys, secrets +итд), чтобы бот не сыпал ошибками в логи (возможно, в дальнейшем возможно будет +отключить эти плагины). + +#### OpenWeatherMap + +Для работы погодного плагина надо [заргистрироваться][5], [залогиниться][6] и +[создать][7] api key. Free plan предлагает всё необхдимое для работы "плагина". + +Когда api key будет создан, его нужно вписать в **config.json** "секцию" +openweathermap в качестве appid. На этом всё. + +#### Imgur + +Этот плагин "просто есть" и его на самом деле ничто и никто не использует. И в +этой связи все настройки плагина можно оставить "как есть" в примере конфига. + +Тем не менее, если есть большое желание, то можно [залогиниться][8] и +[зарегистрировать][9] бота как приложение, а потом разрешить приложению +пользоваться API-шкой, как описано в [этом][10] или [этом][11] мануале. + +#### Flickr + +Этот "плагин" действительно используется для добычи ссылок на картинки в разных +"картиночных" командах бота. + +Есть скрипт, который поможет с регистрацией приложения в api Flickr - +**bin/flickr_init.pl** он достанет все нужные ключи и секреты к ним. + +До запуска этого скрипта, бот должен быть забутстраплен через **`bootstrap.sh`**. + +[Залогиньтесь][11] и создайте [app][12] in своём Flicker-овском аккаунте. Далее, +*разлогиньтесь*, это нужно, чтобы потом проще было достать параметр verifier. + +Запишите [app key и secret][13] в **config.json**. Удостоверьтесь, что параметр +"verifier" в конфиге либо закоменчен либо отсутствует. + +Запустите **bin/flickr_init.pl** и следуте предлагаемым инструкциям - в итоге +будет дана ссылка, которую надо скопипастить в браузер и через один-два +редиректа вы попадёте на example.com. Из адресной строки браузера надо +скопировать параметр "verifier" и вписать его в **config.json**. + +Чтобы сохранить в бд плагина API access token для нормальной работы "плагина", +второй раз запустите **bin/flickr_init.pl**. На этом всё. + +[1]: https://metacpan.org/pod/Telegram::Bot +[2]: https://metacpan.org/pod/Hailo +[3]: https://core.telegram.org/bots/api +[4]: https://core.telegram.org/bots/api#getting-updates +[5]: https://home.openweathermap.org/users/sign_up +[6]: https://home.openweathermap.org/users/sign_in +[7]: https://home.openweathermap.org/api_keys +[8]: https://imgur.com/signin +[9]: https://api.imgur.com/oauth2/addclient +[10]: https://apidocs.imgur.com/#authorization-and-oauth +[11]: https://identity.flickr.com/login +[12]: https://www.flickr.com/services/apps/create/apply/ +[13]: https://www.flickr.com/services/api/keys/ diff --git a/lib/Teapot/Bot/Brain.pm b/lib/Teapot/Bot/Brain.pm index 9bb5750..642b8e8 100644 --- a/lib/Teapot/Bot/Brain.pm +++ b/lib/Teapot/Bot/Brain.pm @@ -132,6 +132,61 @@ sub getChatMember { } } +sub kickChatMember { + my $self = shift; + my $args = shift || {}; + + my $token = $self->token || croak 'No token supplied to kickChatMember?'; + my $send_args = {}; + + unless ($args->{chat_id}) { + cluck 'No chat_id supplied to kickChatMember()'; + return {'error' => 1}; + } + + unless ($args->{user_id}) { + cluck 'No user_id supplied to kickChatMember()'; + return {'error' => 1}; + } + + $send_args->{chat_id} = $args->{chat_id}; + $send_args->{user_id} = $args->{user_id}; + $send_args->{until_date} = $args->{until_date} if exists $args->{until_date}; + $send_args->{revoke_messages} = $args->{revoke_messages} if exists $args->{revoke_messages}; + + my $url = "https://api.telegram.org/bot${token}/kickChatMember"; + my $api_response = $self->_post_request($url, $send_args); + + return; +} + +sub unbanChatMember { + my $self = shift; + my $args = shift || {}; + + my $token = $self->token || croak 'No token supplied to unbanChatMember?'; + my $send_args = {}; + + unless ($args->{chat_id}) { + cluck 'No chat_id supplied to unbanChatMember()'; + return {'error' => 1}; + } + + unless ($args->{user_id}) { + cluck 'No user_id supplied to unbanChatMember()'; + return {'error' => 1}; + } + + $send_args->{chat_id} = $args->{chat_id}; + $send_args->{user_id} = $args->{user_id}; + $send_args->{only_if_banned} = $args->{only_if_banned} if exists $args->{only_if_banned}; + + my $url = "https://api.telegram.org/bot${token}/unbanChatMember"; + my $api_response = $self->_post_request($url, $send_args); + + return; +} + sub getChat { my $self = shift; @@ -160,6 +215,28 @@ sub getChat { } +sub leaveChat { + my $self = shift; + my $args = shift || {}; + + my $send_args = {}; + + unless ($args->{chat_id}) { + cluck 'No chat_id supplied to getChat()'; + return {'error' => 1}; + } + + $send_args->{chat_id} = $args->{chat_id}; + + my $token = $self->token || croak 'No token supplied to getChat()?'; + + my $url = "https://api.telegram.org/bot${token}/leaveChat"; + my $api_response = $self->_post_request($url, $send_args); + + return; +} + + sub sendMessage { my $self = shift; my $args = shift || {}; @@ -385,6 +462,121 @@ sub sendChatAction { return; } +sub exportChatInviteLink { + my $self = shift; + my $args = shift || {}; + my $send_args = {}; + + my $token = $self->token || croak 'No token supplied to createChatInviteLink()?'; + + unless ($args->{chat_id}) { + cluck 'No chat_id supplied in createChatInviteLink()'; + return {'error' => 1}; + } + + $send_args->{chat_id} = $args->{chat_id}; + + my $url = "https://api.telegram.org/bot${token}/exportChatInviteLink"; + my $api_response = $self->_post_request($url); + + if ($api_response) { + return $api_response; + } + else { + return {'error' => 1}; + } +} + +sub createChatInviteLink { + my $self = shift; + my $args = shift || {}; + my $send_args = {}; + + my $token = $self->token || croak 'No token supplied to createChatInviteLink()?'; + + unless ($args->{chat_id}) { + cluck 'No chat_id supplied in createChatInviteLink()'; + return {'error' => 1}; + } + + $send_args->{chat_id} = $args->{chat_id}; + $send_args->{expire_date} = $args->{expire_date} if exists $args->{expire_date}; + $send_args->{member_limit} = $args->{member_limit} if exists $args->{member_limit}; + + my $url = "https://api.telegram.org/bot${token}/createChatInviteLink"; + my $api_response = $self->_post_request($url); + + if ($api_response) { + return Teapot::Bot::Object::ChatInviteLink->create_from_hash($api_response, $self); + } + else { + return {'error' => 1}; + } +} + +sub editChatInviteLink { + my $self = shift; + my $args = shift || {}; + my $send_args = {}; + + my $token = $self->token || croak 'No token supplied to editChatInviteLink()?'; + + unless ($args->{chat_id}) { + cluck 'No chat_id supplied in editChatInviteLink()'; + return {'error' => 1}; + } + + unless ($args->{invite_link}) { + cluck 'No invite_link supplied in editChatInviteLink()'; + return {'error' => 1}; + } + + $send_args->{chat_id} = $args->{chat_id}; + $send_args->{invite_link} = $args->{invite_link}; + $send_args->{expire_date} = $args->{expire_date} if exists $args->{expire_date}; + $send_args->{member_limit} = $args->{member_limit} if exists $args->{member_limit}; + + my $url = "https://api.telegram.org/bot${token}/editChatInviteLink"; + my $api_response = $self->_post_request($url); + + if ($api_response) { + return Teapot::Bot::Object::ChatInviteLink->create_from_hash($api_response, $self); + } + else { + return {'error' => 1}; + } +} + +sub revokeChatInviteLink { + my $self = shift; + my $args = shift || {}; + my $send_args = {}; + + my $token = $self->token || croak 'No token supplied to revokeChatInviteLink()?'; + + unless ($args->{chat_id}) { + cluck 'No chat_id supplied in revokeChatInviteLink()'; + return {'error' => 1}; + } + + unless ($args->{invite_link}) { + cluck 'No invite_link supplied in revokeChatInviteLink()'; + return {'error' => 1}; + } + + $send_args->{chat_id} = $args->{chat_id}; + $send_args->{invite_link} = $args->{invite_link}; + + my $url = "https://api.telegram.org/bot${token}/revokeChatInviteLink"; + my $api_response = $self->_post_request($url); + + if ($api_response) { + return Teapot::Bot::Object::ChatInviteLink->create_from_hash($api_response, $self); + } + else { + return {'error' => 1}; + } +} sub _add_getUpdates_handler { my $self = shift; @@ -414,7 +606,7 @@ sub _add_getUpdates_handler { $self->_process_message($item); } } else { - cluck "Something nasty happen while handling updates from $updateURL : $EVAL_ERROR"; + cluck "Unable to get update from API: $EVAL_ERROR"; } $http_active = 0; @@ -433,11 +625,24 @@ sub _process_message { # There can be several types of responses. But only one response. # https://core.telegram.org/bots/api#update my $update; - $update = Teapot::Bot::Object::Message->create_from_hash($item->{message}, $self) if $item->{message}; - $update = Teapot::Bot::Object::Message->create_from_hash($item->{edited_message}, $self) if $item->{edited_message}; - $update = Teapot::Bot::Object::Message->create_from_hash($item->{channel_post}, $self) if $item->{channel_post}; - $update = Teapot::Bot::Object::Message->create_from_hash($item->{edited_channel_post}, $self) if $item->{edited_channel_post}; - $update = Teapot::Bot::Object::Message->create_from_hash($item->{poll}, $self) if $item->{poll}; + $update = Teapot::Bot::Object::Message->create_from_hash($item->{message}, $self) if $item->{message}; + $update = Teapot::Bot::Object::Message->create_from_hash($item->{edited_message}, $self) if $item->{edited_message}; + $update = Teapot::Bot::Object::Message->create_from_hash($item->{channel_post}, $self) if $item->{channel_post}; + $update = Teapot::Bot::Object::Message->create_from_hash($item->{edited_channel_post}, $self) if $item->{edited_channel_post}; + # Not yet implemented, we have no InlineQuery object yet + #$update = Teapot::Bot::Object::InlineQuery->create_from_hash($tem->{inline_query}, $self) if $item->{inline_query}; + # Not yet implemented, we have no ChosenInlineResult object yet + #$update = Teapot::Bot::Object::ChosenInlineResult->create_from_hash($tem->{chosen_inline_result}, $self) if $item->{chosen_inline_result}; + # Not yet implemented, we have no callback_query object yet, because we do not use this mechanism, s API should not gi us that shit + #$update = Teapot::Bot::Object::CallbackQuery->create_from_hash($tem->{callback_query}, $self) if $item->{callback_query}; + # Not yet implemented, we have no ShippingQuery object yet + #$update = Teapot::Bot::Object::ShippingQuery->create_from_hash($tem->{shipping_query}, $self) if $item->{shipping_query}; + # Not yet implemented, we have no PreCheckoutQuery object yet + #$update = Teapot::Bot::Object::PreCheckoutQuery->create_from_hash($tem->{pre_checkout_query}, $self) if $item->{pre_checkout_query}; + $update = Teapot::Bot::Object::Poll->create_from_hash($item->{poll}, $self) if $item->{poll}; + $update = Teapot::Bot::Object::PollAnswer->create_from_hash($item->{poll_answer}, $self) if $item->{poll_answer}; + $update = Teapot::Bot::Object::ChatMemberUpdated->create_from_hash($item->{my_chat_member}, $self) if $item->{my_chat_member}; + $update = Teapot::Bot::Object::ChatMemberUpdated->create_from_hash($item->{chat_member}, $self) if $item->{chat_member}; # if we got to this point without creating a response, it must be a type we # don't handle yet @@ -448,7 +653,15 @@ sub _process_message { foreach my $listener (@{ $self->listeners }) { # call the listener code, supplying ourself and the update - $listener->($self, $update); + my $evalRet = eval { + $listener->($self, $update); + return 1; + }; + + unless ($evalRet) { + cluck "An error occured during update processing: $EVAL_ERROR"; + return; + } } return; @@ -585,6 +798,25 @@ of Chat User. On error returns hash reference with error set to 1 +=head2 kickChatMember + +This is the wrapper around the C API method. See +L. + +Takes chat_id, and user_id as arguments. And optionally until_date and +revoke_messages. + +Returns nothing, it's send-only method (Telegram API returns true on success) + +=head2 unbanChatMember + +This is the wrapper around the C API method. See +L. + +Takes chat_id, and user_id as arguments. And optionally only_if_banned. + +Returns nothing, it's send-only method (Telegram API returns true on success) + =head2 getChat This is the wrapper around the C API method. See @@ -596,6 +828,15 @@ Returns the L that represents properties of Chat. On error returns hash reference with error set to 1 +=head2 leaveChat + +This is the wrapper around the C API method. See +L. + +Takes chat_id as argument. + +Returns nothing, it's send-only method (Telegram API returns true on success) + =head2 sendMessage See L. @@ -633,6 +874,47 @@ See L. Returns nothing, it's send-only method (Telegram API returns true on success) +=head2 exportChatInviteLink + +See L + +Takes chat_id as argument. + +Returns a raw api answer. + +On error returns hash reference with error set to 1 + +=head2 createChatInviteLink + +See L + +Takes chat_id as argument. And optionally expire_date and member_limit. + +Returns a L object. + +On error returns hash reference with error set to 1 + +=head2 editChatInviteLink + +See L + +Takes chat_id and invite_link as arguments. And optionally expire_date +and member_limit. + +Returns a L object. + +On error returns hash reference with error set to 1 + +=head2 revokeChatInviteLink + +See L + +Takes chat_id and invite_link as arguments. + +Returns a L object. + +On error returns hash reference with error set to 1 + =head1 SEE ALSO =over 4 diff --git a/lib/Teapot/Bot/Object/Audio.pm b/lib/Teapot/Bot/Object/Audio.pm index 768f772..e7ffa10 100644 --- a/lib/Teapot/Bot/Object/Audio.pm +++ b/lib/Teapot/Bot/Object/Audio.pm @@ -6,15 +6,18 @@ use Mojo::Base 'Teapot::Bot::Object::Base'; $Teapot::Bot::Object::Audio::VERSION = '0.022'; has 'file_id'; +has 'file_unique_id'; has 'duration'; -has 'performer'; -has 'title'; -has 'mime_type'; -has 'file_size'; -has 'thumb'; #PhotoSize +has 'performer'; # Optional. Performer of the audio as defined by sender or by audio tags +has 'title'; # Optional. Title of the audio as defined by sender or by audio tags +has 'file_name'; # Optional. Original filename as defined by sender +has 'mime_type'; # Optional. MIME type of the file as defined by sender +has 'file_size'; # Optional. File size +has 'thumb'; # Optional. Thumbnail of the album cover to which the music file belongs sub fields { - return { scalar => [qw/file_id duration performer title mime_type file_size/], + return { scalar => [qw/file_id file_unique_id duration performer title file_name mime_type + file_size/], 'Teapot::Bot::Object::PhotoSize' => [qw/thumb/], }; } diff --git a/lib/Teapot/Bot/Object/Base.pm b/lib/Teapot/Bot/Object/Base.pm index 240b0b7..ef789ee 100644 --- a/lib/Teapot/Bot/Object/Base.pm +++ b/lib/Teapot/Bot/Object/Base.pm @@ -42,6 +42,28 @@ sub _field_is_array_of_arrays { return; } +sub create_from_array { + my $class = shift; + my $array = shift; + my $brain = shift || croak 'No brain supplied to create_from_array()'; + my $obj = shift || $class->new(_brain => $brain); + + unless (defined $array) { + cluck 'Array is undef'; + return $obj; + } + + unless (ref ($array) eq 'ARRAY') { + cluck 'Not array ' . Dumper ($array); + return $obj; + } + + cluck "Dumping class: " . Dumper ($class); + cluck "Dumping array: " . Dumper ($array); + +# it's stub, return $obj + return $obj; +} # create an object from a hash. Needs to deal with the nested types, and # arrays @@ -57,6 +79,10 @@ sub create_from_hash { } unless (ref ($hash) eq 'HASH') { + if (ref ($hash) eq 'ARRAY') { + return create_from_array($class, $hash, $brain); + } + cluck 'Not a hash ' . Dumper ($hash); return $obj; } diff --git a/lib/Teapot/Bot/Object/ChatInviteLink.pm b/lib/Teapot/Bot/Object/ChatInviteLink.pm new file mode 100644 index 0000000..a7842bb --- /dev/null +++ b/lib/Teapot/Bot/Object/ChatInviteLink.pm @@ -0,0 +1,57 @@ +package Teapot::Bot::Object::ChatInviteLink; +# ABSTRACT: The base class for Telegram message 'ChatInviteLink' type. + +use Mojo::Base 'Teapot::Bot::Object::Base'; +use Teapot::Bot::Object::User; + +$Teapot::Bot::Object::ChatInviteLink::VERSION = '0.022'; + +has 'invite_link'; +has 'creator'; +has 'is_primary'; +has 'is_revoked'; +has 'expire_date'; # Optional. Point in time (Unix timestamp) when the link will expire or has been expired +has 'member_limit'; # Optional. Maximum number of users that can be members of the chat simultaneously after joining + # the chat via this invite link; 1-99999 + +sub fields { + return { + 'scalar' => [qw/invite_link is_primary is_revoked expire_date expire_date member_limit/], + 'Teapot::Bot::Object::User' => [qw/creator/], + }; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Teapot::Bot::Object::ChatInviteLink - The base class for Telegram message 'ChatInviteLink' type + +=head1 VERSION + +version 0.022 + +=head1 DESCRIPTION +The base class for Telegram message 'ChatInviteLink' type. + +See L for details of the +attributes available for L objects. + +=head1 AUTHOR + +Sergei Fedosov + +=head1 LICENSE AND COPYRIGHT + +This software is copyright (c) 2021 by Sergei Fedosov . + +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 diff --git a/lib/Teapot/Bot/Object/ChatMember.pm b/lib/Teapot/Bot/Object/ChatMember.pm index 5ea57e8..6399d84 100644 --- a/lib/Teapot/Bot/Object/ChatMember.pm +++ b/lib/Teapot/Bot/Object/ChatMember.pm @@ -13,9 +13,14 @@ has 'custom_title'; # optional. Owner and administrators only. has 'is_anonymous'; # Optional. Owner and administrators only. has 'can_be_edited'; # optional. Administrators only. +has 'can_manage_chat'; # Optional. Administrators only. True, if the administrator can access the chat event + # log, chat statistics, message statistics in channels, see channel members, see + # anonymous administrators in supergroups and ignore slow mode. Implied by any other + # administrator privilege has 'can_post_messages'; # optional. Administrators only. has 'can_edit_messages'; # optional. Administrators only. has 'can_delete_messages'; # optional. Administrators only. +has 'can_manage_voice_chats'; # Optional. Administrators only. True, if the administrator can manage voice chats has 'can_restrict_members'; # optional. Administrators only. has 'can_promote_members'; # optional. Administrators only. has 'can_change_info'; # optional. Administrators and restricted only. @@ -31,10 +36,11 @@ has 'until_date'; # optional. Restricted and kicked only. sub fields { return { - 'scalar' => [qw/status custom_title is_anonymous can_be_edited can_post_messages can_edit_messages - can_delete_messages can_restrict_members can_promote_members can_change_info - can_invite_users can_pin_messages is_member can_send_messages - can_send_media_messages can_send_polls can_send_other_messages can_add_web_page_previews until_date/], + 'scalar' => [qw/status custom_title is_anonymous can_be_edited can_manage_chat can_post_messages + can_edit_messages can_delete_messages can_manage_voice_chats can_restrict_members + can_promote_members can_change_info can_invite_users can_pin_messages is_member + can_send_messages can_send_media_messages can_send_polls can_send_other_messages + can_add_web_page_previews until_date/], 'Teapot::Bot::Object::User' => [qw/user/], }; } diff --git a/lib/Teapot/Bot/Object/ChatMemberUpdated.pm b/lib/Teapot/Bot/Object/ChatMemberUpdated.pm new file mode 100644 index 0000000..7335ca7 --- /dev/null +++ b/lib/Teapot/Bot/Object/ChatMemberUpdated.pm @@ -0,0 +1,63 @@ +package Teapot::Bot::Object::ChatMemberUpdated; +# ABSTRACT: The base class for Telegram 'ChatMemberUpdated' type objects + +use Mojo::Base 'Teapot::Bot::Object::Base'; +use Teapot::Bot::Object::Chat; +use Teapot::Bot::Object::User; +use Teapot::Bot::Object::ChatMember; +use Teapot::Bot::Object::ChatInviteLink; + +$Teapot::Bot::Object::ChatMemberUpdated::VERSION = '0.022'; + +has 'chat'; +has 'from'; +has 'date'; +has 'old_chat_member'; +has 'new_chat_member'; +has 'invite_link'; # Optional. Chat invite link, which was used by the user to join the chat; for joining by + # invite link events only. + +sub fields { + return { + 'Teapot::Bot::Object::Chat' => [qw/chat/], + 'Teapot::Bot::Object::User' => [qw/from/], + 'scalar' => [qw/date/], + 'Teapot::Bot::Object::ChatMember' => [qw/old_chat_member new_chat_member/], + 'Teapot::Bot::Object::ChatInviteLink' => [qw/invite_link/] + }; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Teapot::Bot::Object::ChatMemberUpdated - The base class for Telegram 'ChatMemberUpdated' type objects + +=head1 VERSION + +version 0.022 + +=head1 DESCRIPTION +The base class for Telegram 'ChatMemberUpdated' type objects. + +See L for details of the +attributes available for L objects. + +=head1 AUTHOR + +Sergei Fedosov + +=head1 LICENSE AND COPYRIGHT + +This software is copyright (c) 2021 by Sergei Fedosov + +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 diff --git a/lib/Teapot/Bot/Object/Message.pm b/lib/Teapot/Bot/Object/Message.pm index f579421..0cba34a 100644 --- a/lib/Teapot/Bot/Object/Message.pm +++ b/lib/Teapot/Bot/Object/Message.pm @@ -29,6 +29,10 @@ use Teapot::Bot::Object::PassportData; use Teapot::Bot::Object::InlineKeyboardMarkup; use Teapot::Bot::Object::ProximityAlertTriggered; use Teapot::Bot::Object::Dice; +use Teapot::Bot::Object::MessageAutoDeleteTimerChanged; +use Teapot::Bot::Object::VoiceChatStarted; +use Teapot::Bot::Object::VoiceChatEnded; +use Teapot::Bot::Object::VoiceChatParticipantsInvited; use Data::Dumper; use Carp qw(cluck); @@ -78,6 +82,7 @@ has 'delete_chat_photo'; has 'group_chat_created'; has 'supergroup_chat_created'; has 'channel_chat_created'; +has 'message_auto_delete_timer_changed'; # Optional. Service message: auto-delete timer settings changed in the chat has 'migrate_to_chat_id'; has 'migrate_from_chat_id'; has 'pinned_message'; # Message @@ -86,6 +91,9 @@ has 'successful_payment'; # SuccessfulPayment has 'connected_website'; has 'passport_data'; # PassportData has 'proximity_alert_triggered'; +has 'voice_chat_started'; # Optional. Service message: voice chat started +has 'voice_chat_ended'; # Optional. Service message: voice chat ended +has 'voice_chat_participants_invited'; # Optional. Service message: new participants invited to a voice chat has 'reply_markup'; # Array of InlineKeyboardMarkup sub fields { @@ -126,6 +134,10 @@ sub fields { 'Teapot::Bot::Object::InlineKeyboardMarkup' => [qw/reply_markup/], 'Teapot::Bot::Object::ProximityAlertTriggered' => [qw/proximity_alert_triggered/], 'Teapot::Bot::Object::Dice' => [qw/dice/], + 'Teapot::Bot::Object::MessageAutoDeleteTimerChanged' => [qw/message_auto_delete_timer_changed/], + 'Teapot::Bot::Object::VoiceChatStarted' => [qw/voice_chat_started/], + 'Teapot::Bot::Object::VoiceChatEnded' => [qw/voice_chat_ended/], + 'Teapot::Bot::Object::VoiceChatParticipantsInvited' => [qw/voice_chat_participants_invited/], }; } diff --git a/lib/Teapot/Bot/Object/MessageAutoDeleteTimerChanged.pm b/lib/Teapot/Bot/Object/MessageAutoDeleteTimerChanged.pm new file mode 100644 index 0000000..3bff092 --- /dev/null +++ b/lib/Teapot/Bot/Object/MessageAutoDeleteTimerChanged.pm @@ -0,0 +1,49 @@ +package Teapot::Bot::Object::MessageAutoDeleteTimerChanged; +# ABSTRACT: The base class for Telegram 'MessageAutoDeleteTimerChanged' type objects + +use Mojo::Base 'Teapot::Bot::Object::Base'; + +$Teapot::Bot::Object::MessageAutoDeleteTimerChanged::VERSION = '0.022'; + +has 'message_auto_delete_time'; + +sub fields { + return { + 'scalar' => [qw/message_auto_delete_time/], + }; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Teapot::Bot::Object::MessageAutoDeleteTimerChanged - The base class for Telegram 'MessageAutoDeleteTimerChanged' type objects + +=head1 VERSION + +version 0.022 + +=head1 DESCRIPTION +The base class for Telegram 'MessageAutoDeleteTimerChanged' type objects. + +See L for details of the +attributes available for L objects. + +=head1 AUTHOR + +Sergei Fedosov + +=head1 LICENSE AND COPYRIGHT + +This software is copyright (c) 2021 by Sergei Fedosov + +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 diff --git a/lib/Teapot/Bot/Object/Video.pm b/lib/Teapot/Bot/Object/Video.pm index a1237d7..c4679cc 100644 --- a/lib/Teapot/Bot/Object/Video.pm +++ b/lib/Teapot/Bot/Object/Video.pm @@ -7,16 +7,19 @@ use Teapot::Bot::Object::PhotoSize; $Teapot::Bot::Object::Video::VERSION = '0.022'; has 'file_id'; +has 'file_unique_id'; has 'width'; has 'height'; has 'duration'; -has 'thumb'; #PhotoSize -has 'mime_type'; -has 'file_size'; +has 'thumb'; # Optional. Video thumbnail +has 'file_name'; # Optional. Original filename as defined by sender +has 'mime_type'; # Optional. Mime type of a file as defined by sender +has 'file_size'; # Optional. File size sub fields { return { - scalar => [qw/file_id width height duration mime_type file_size/], + scalar => [qw/file_id file_unique_id width height duration file_name mime_type + file_size/], 'Teapot::Bot::Object::PhotoSize' => [qw/thumb/] }; } diff --git a/lib/Teapot/Bot/Object/VoiceChatEnded.pm b/lib/Teapot/Bot/Object/VoiceChatEnded.pm new file mode 100644 index 0000000..76661a6 --- /dev/null +++ b/lib/Teapot/Bot/Object/VoiceChatEnded.pm @@ -0,0 +1,48 @@ +package Teapot::Bot::Object::VoiceChatEnded; +# ABSTRACT: The base class for Telegram message 'VoiceChatEnded' type. + +use Mojo::Base 'Teapot::Bot::Object::Base'; + +$Teapot::Bot::Object::VoiceChatEnded::VERSION = '0.022'; + +# This object represents a service message about a voice chat started in the chat. Currently holds no information. +has 'duartion'; + +sub fields { + return { scalar => [qw/duration/] }; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Teapot::Bot::Object::VoiceChatEnded - The base class for Telegram message 'VoiceChatEnded' type + +=head1 VERSION + +version 0.022 + +=head1 DESCRIPTION +The base class for Telegram message 'VoiceChatEnded' type. + +See L for details of the +attributes available for L objects. + +=head1 AUTHOR + +Sergei Fedosov + +=head1 LICENSE AND COPYRIGHT + +This software is copyright (c) 2021 by Sergei Fedosov . + +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 diff --git a/lib/Teapot/Bot/Object/VoiceChatParticipantsInvited.pm b/lib/Teapot/Bot/Object/VoiceChatParticipantsInvited.pm new file mode 100644 index 0000000..cf61dbd --- /dev/null +++ b/lib/Teapot/Bot/Object/VoiceChatParticipantsInvited.pm @@ -0,0 +1,53 @@ +package Teapot::Bot::Object::VoiceChatParticipantsInvited; +# ABSTRACT: The base class for Telegram message 'VoiceChatParticipantsInvited' type. + +use Mojo::Base 'Teapot::Bot::Object::Base'; +use Teapot::Bot::Object::User; + +$Teapot::Bot::Object::VoiceChatParticipantsInvited::VERSION = '0.022'; + +# This object represents a service message about a voice chat started in the chat. Currently holds no information. +has 'users'; + +sub fields { + return { 'Teapot::Bot::Object::User' => [qw/users/] }; +} + +sub arrays { + return qw/users/; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Teapot::Bot::Object::VoiceChatParticipantsInvited - The base class for Telegram message 'VoiceChatParticipantsInvited' type + +=head1 VERSION + +version 0.022 + +=head1 DESCRIPTION +The base class for Telegram message 'VoiceChatParticipantsInvited' type. + +See L for details of the +attributes available for L objects. + +=head1 AUTHOR + +Sergei Fedosov + +=head1 LICENSE AND COPYRIGHT + +This software is copyright (c) 2021 by Sergei Fedosov . + +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 diff --git a/lib/Teapot/Bot/Object/VoiceChatStarted.pm b/lib/Teapot/Bot/Object/VoiceChatStarted.pm new file mode 100644 index 0000000..74b3097 --- /dev/null +++ b/lib/Teapot/Bot/Object/VoiceChatStarted.pm @@ -0,0 +1,48 @@ +package Teapot::Bot::Object::VoiceChatStarted; +# ABSTRACT: The base class for Telegram message 'VoiceChatStarted' type. + +use Mojo::Base 'Teapot::Bot::Object::Base'; + +$Teapot::Bot::Object::VoiceChatStarted::VERSION = '0.022'; + +# This object represents a service message about a voice chat started in the chat. Currently holds no information. +has 'stub'; + +sub fields { + return { scalar => [qw/stub/] }; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Teapot::Bot::Object::VoiceChatStarted - The base class for Telegram message 'VoiceChatStarted' type + +=head1 VERSION + +version 0.022 + +=head1 DESCRIPTION +The base class for Telegram message 'VoiceChatStarted' type. + +See L for details of the +attributes available for L objects. + +=head1 AUTHOR + +Sergei Fedosov + +=head1 LICENSE AND COPYRIGHT + +This software is copyright (c) 2021 by Sergei Fedosov . + +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