1

Compare commits

...

20 Commits

Author SHA1 Message Date
eleksir
57120eb461 Bump ver in Teapot::Bot 0.021 -> 0.022 and clenup modules
- Remove Encode module from cpanfile and telegrambot.pm
+ Add Mojo::IOLoop, Mojo::UserAgent, IO::Socket::SSL
* Sort cpanfile
* Bump version Teapot::Bot 0.021 -> 0.022
* Add aleesa-telegram-bot.pid to .gitignore
2020-11-07 17:54:58 +03:00
eleksir
97eddd414d Lint Teapot::Bot with perlcritic
* Use List::Util' any instead of grep in Base.pm
* Use croak() in Base.pm
2020-10-31 13:49:37 +03:00
eleksir
a480786afa First run of Teapot::Bot fixes.
* Fix typos in Brain.pm
* Fix typos in User.pm
* Implement typing methods in Message object and make use of it
* Fix incorrect syntax of unless loops in telegrambot.pm
* Add Log::Any as it required by Teapot::Bot
* Do not use --update in bootstrap.sh
* Add data/lat to .gitignore
* Load ChatMember and ChatPermissions in Message object, so we can use 'em and avoid crash
* Supply missing $send_args to _post_request
2020-10-30 18:14:00 +03:00
eleksir
43c0286414 Use Teapot' sendChatAction, getChat and getChatMember, remove dups of these subs in telegramlib.pm 2020-10-30 16:15:11 +03:00
eleksir
f0b1ae9c43 Set default action to "typing" if not supplied in sendChatAction() 2020-10-30 16:14:28 +03:00
eleksir
29c1fa8d07 Breaking API changes (handle Mojo loop errors), fix sendMessage method broken in 033441c
* Use general method to handle Mojo loop unsuccessful operations
* Do not die if tg api returns error via Mojo loop, lift up error status to upper layer
* Die with confess only in case of Mojo loop does not returns either is_success or is_error set
* Handle incomming updates related to poll event
* Update inline POD in Brain.pm
* Fix overlooked die removal in sendMessage, now it is croak
2020-10-30 15:42:36 +03:00
eleksir
c1b6ca013d More safe actions in Brain.pm 2020-10-30 15:16:45 +03:00
eleksir
edcd382183 Change fields in Chat object
- Removed all_members_are_administrators
+ Add permissions;
+ Add slow_mode_delay;
2020-10-30 13:58:37 +03:00
eleksir
75ee83c94f Implement ChatPermissions object 2020-10-30 13:39:03 +03:00
eleksir
f93f974cb4 Fix Version in ChatMember.pm 2020-10-30 13:37:40 +03:00
eleksir
a1da4b193d Add field via_bot to Message object 2020-10-30 13:36:38 +03:00
eleksir
0576a1ea57 Implement getChat() with inline POD 2020-10-30 13:10:33 +03:00
eleksir
1a8fa3e089 Add new fields to User and MessageEntity objects 2020-10-29 16:28:43 +03:00
eleksir
74e58db1b8 Implement getChatMember() with inline POD 2020-10-29 16:06:19 +03:00
eleksir
5cba9755af Implement ChatMember object 2020-10-29 15:56:00 +03:00
eleksir
113a918010 Some more work on sendChatAction()
* Fix return value
* Add POD inline for this method
2020-10-29 15:53:31 +03:00
eleksir
45318757df Implement sendChatAction() 2020-10-28 18:19:29 +03:00
eleksir
033441c513 First touch to satisfy perlcritic 2020-10-28 18:18:09 +03:00
eleksir
f816840e14 Now Telegram::Bot is Teapot::Bot 2020-10-28 18:12:49 +03:00
eleksir
c3818e5dee Vendor Telegram::Bot 2020-10-28 18:06:21 +03:00
39 changed files with 2765 additions and 91 deletions

2
.gitignore vendored
View File

@@ -2,4 +2,6 @@ vendor_perl
data/config.json
data/cache
data/telegrambot-brains
data/lat
aleesa-telegram-bot.pid
TODO

View File

@@ -4,38 +4,38 @@ verbose = 8
# minorify some of warnings that are not really critical
[-InputOutput::RequireCheckedClose]
# what can we handle in case of error?
# What can we handle in case of error?
[-Modules::ProhibitExcessMainComplexity]
# noone cares
# Noone cares
[-Subroutines::ProhibitExcessComplexity]
# noone cares
# Noone cares
[-Subroutines::ProhibitExplicitReturnUndef]
# but it's very handy sometimes!
# But it's very handy sometimes!
[-ValuesAndExpressions::ProhibitMagicNumbers]
# this policy makes too much false positives
[-RegularExpressions::RequireLineBoundaryMatching]
# we use /m as needed
# We use /m as needed
[-RegularExpressions::RequireExtendedFormatting]
# we do not use extended formatting of regex, they still not THAT complex
# We do not use extended formatting of regex, they still not THAT complex
[-RegularExpressions::RequireDotMatchAnything]
# huh?
[-RegularExpressions::ProhibitEscapedMetacharacters]
# looks like it pointless
# Looks like it pointless
[-ControlStructures::ProhibitCascadingIfElse]
# I like long ifelse chains
# I like long if..else chains
[-ControlStructures::ProhibitPostfixControls]
# in short lines we can afford ourselves to use postfix controls
# but ofcorse we shoul avoid such constructions in long lines
# In short lines we can afford ourselves to use postfix controls
# but ofcorse we should avoid such constructions in long lines.
[-Subroutines::ProhibitSubroutinePrototypes]
# Contrary to Perl::Critic we consider prototypes as useful, even if
@@ -43,9 +43,9 @@ verbose = 8
# hints.
[-CodeLayout::RequireTidyCode]
# impossible to complete, because of on higher linting levels ## no critic
# Impossible to complete, because of on higher linting levels "## no critic..."
# require be per-case on same line where critique is, but tidy align them
# one line down
# one line down.
[-CodeLayout::ProhibitParensWithBuiltins]
# duh...
@@ -55,7 +55,7 @@ verbose = 8
# the recomended use of q{} looks too complex: my $var = q{};
[-ValuesAndExpressions::ProhibitNoisyQuotes]
# other people, other opinions: "," is better readable than qw(,)
# Other people, other opinions: "," is better readable than qw(,)
[-BuiltinFunctions::ProhibitSleepViaSelect]
# We do not wish to use too much external modules.
@@ -67,14 +67,22 @@ verbose = 8
# Noone care, really
[-ControlStructures::ProhibitUnlessBlocks]
# they should not be too complex - only one condition should be checked,
# They should not be too complex - only one condition should be checked,
# that's all
[-Miscellanea::ProhibitTies]
# Just allow it. It's very handy stuff and extremely simple and safe enugh to use.
[-ValuesAndExpressions::RequireNumberSeparators]
# not really
# Not really
[-InputOutput::RequireBracedFileHandleWithPrint]
# we prefer not to use braced file handles
# We prefer not to use braced file handles
[-Documentation::PodSpelling]
# It doesn't help, but emits annoying errors
[Documentation::RequirePodSections]
# Considering this as "soft" requirement. For modules that is (or will be)
# stand-alone libs well formed documentation is highly desired.
lib_sections = NAME | VERSION | DESCRIPTION | AUTHOR | LICENSE AND COPYRIGHT

View File

@@ -1,5 +1,5 @@
#!/bin/bash
cpanm -l vendor_perl --self-contained --force --update --installdeps .
cpanm -l vendor_perl --self-contained --force --installdeps .
# vim: set ft=sh noet ai ts=4 sw=4 sts=4:

View File

@@ -1,15 +1,22 @@
requires 'Carp';
requires 'Cwd::utf8';
requires 'DB_File';
requires 'Digest::MD5';
requires 'Encode';
requires 'Data::Dumper';
requires 'File::Basename';
requires 'File::Path';
requires 'HTTP::Tiny';
requires 'Hailo';
requires 'HTTP::Tiny';
requires 'IO::Socket::SSL';
requires 'JSON';
requires 'JSON::XS';
requires 'JSON::PP';
requires 'Mojo::Base';
requires 'Telegram::Bot';
requires 'URI::URL';
requires 'JSON::XS';
requires 'List::Util';
requires 'local::lib';
requires 'Log::Any';
requires 'Mojo::Base';
requires 'Mojo::IOLoop';
requires 'Mojo::UserAgent';
#requires 'Telegram::Bot';
#requires 'Test::Exception';
requires 'URI::URL';

100
lib/Teapot/Bot.pm Normal file
View File

@@ -0,0 +1,100 @@
package Teapot::Bot;
use strict;
use warnings;
$Teapot::Bot::VERSION = '0.022';
# ABSTRACT: A base class to make your very own Telegram bot
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot
=head1 DESCRIPTION
A base class to make your very own Telegram bot
=head1 VERSION
version 0.022
=head1 SYNOPSIS
NOTE: This API should not yet be considered stable.
Creating a bot is easy:
package MyBot;
use Mojo::Base 'Teapot::Bot::Brain';
has token => 'YOURTOKENHERE';
# send a polite reply, to either a group or a single user,
# depending on where we were addressed from
sub _be_polite {
my ($self, $msg) = @_;
return unless $msg->text =~ /hello/;
# is this a 1-on-1 ?
if ($msg->chat->is_user) {
$msg->reply("hello there");
# send them a picture as well
$self->sendPhoto({chat_id => $msg->chat->id, photo => $image_filename});
}
# group chat
else {
$msg->reply("hello to everyone!");
}
}
# setup our bot
sub init {
my $self = shift;
$self->add_listener(\&_be_polite);
}
1;
Now just:
perl -MMyBot -E 'MyBot->new->think'
and you've got yourself a stew, baby! Or a bot, anyway.
Note that for the bot to see messages that do not start with a leading '/', you will need to use
the C<'/setprivacy'> command on Telegram's C<@botfather> interface to change the privacy settings.
=head1 DEPENDENCIES
IO::Socket::SSL
Log::Any
Mojolicious
Test::Exception
=head1 EXAMPLES
This distribution's C<ex/> directory contains some complete examples that may be
instructive to look at.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

574
lib/Teapot/Bot/Brain.pm Normal file
View File

@@ -0,0 +1,574 @@
package Teapot::Bot::Brain;
# ABSTRACT: A base class to make your very own Telegram bot
use Mojo::Base -base;
use strict;
use warnings;
use Mojo::IOLoop;
use Mojo::UserAgent;
use Carp qw/croak cluck confess/; # use croak where we return error up to app that supply something wrong
# use cluck where we want to say that something bad but non-critical happen in
# lower layer (Mojo loop)
# use confess where we want to say that fatal error happen in lower layer (Mojo loop)
use Log::Any;
use Data::Dumper;
use Teapot::Bot::Object::Message;
$Teapot::Bot::Brain::VERSION = '0.022';
# base class for building telegram robots with Mojolicious
has longpoll_time => 60;
has ua => sub { Mojo::UserAgent->new->inactivity_timeout(shift->longpoll_time + 15) };
has token => sub { croak 'You need to supply your own token'; };
has tasks => sub { [] };
has listeners => sub { [] };
has log => sub { Log::Any->get_logger };
sub add_repeating_task {
my $self = shift;
my $seconds = shift;
my $task = shift;
my $repeater = sub {
# Perform operation every $seconds seconds
my $last_check = time();
Mojo::IOLoop->recurring(0.1 => sub {
my $loop = shift;
my $now = time();
return if ($now - $last_check) < $seconds;
$last_check = $now;
$task->($self);
});
};
# keep a copy
push @{ $self->tasks }, $repeater;
# kick it off
$repeater->();
return;
}
sub add_listener {
my $self = shift;
my $coderef = shift;
push @{ $self->listeners }, $coderef;
return;
}
sub init {
croak 'init() was not overridden!';
}
sub think {
my $self = shift;
$self->init();
$self->_add_getUpdates_handler;
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
return;
}
sub getMe {
my $self = shift;
my $token = $self->token || croak 'No token supplied to getMe()?';
my $url = "https://api.telegram.org/bot${token}/getMe";
my $api_response = $self->_post_request($url);
if ($api_response) {
return Teapot::Bot::Object::User->create_from_hash($api_response, $self);
}
else {
return {'error' => 1};
}
}
sub getChatMember {
my $self = shift;
my $args = shift || {};
my $send_args = {};
croak 'No chat_id supplied to getChatMember()' unless $args->{chat_id};
croak 'No user_id supplied to getChatMember()' unless $args->{user_id};
$send_args->{chat_id} = $args->{chat_id};
$send_args->{user_id} = $args->{user_id};
my $token = $self->token || croak 'No token supplied to getChatMember?';
my $url = "https://api.telegram.org/bot${token}/getChatMember";
my $api_response = $self->_post_request($url, $send_args);
if ($api_response) {
return Teapot::Bot::Object::ChatMember->create_from_hash($api_response, $self);
}
else {
return {'error' => 1};
}
}
sub getChat {
my $self = shift;
my $args = shift || {};
my $send_args = {};
croak 'No chat_id supplied to getChat()' unless $args->{chat_id};
$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}/getChat";
my $api_response = $self->_post_request($url, $send_args);
if ($api_response) {
return Teapot::Bot::Object::Chat->create_from_hash($api_response, $self);
}
else {
return {'error' => 1};
}
}
sub sendMessage {
my $self = shift;
my $args = shift || {};
my $send_args = {};
croak 'No chat_id supplied in sendMessage()' unless $args->{chat_id};
$send_args->{chat_id} = $args->{chat_id};
croak 'No text supplied in sendMessage()' unless $args->{text};
$send_args->{text} = $args->{text};
# these are optional, send if they are supplied
$send_args->{parse_mode} = $args->{parse_mode} if exists $args->{parse_mode};
$send_args->{disable_web_page_preview} = $args->{disable_web_page_preview} if exists $args->{disable_web_page_preview};
$send_args->{disable_notification} = $args->{disable_notification} if exists $args->{disable_notification};
$send_args->{reply_to_message_id} = $args->{reply_to_message_id} if exists $args->{reply_to_message_id};
# check reply_markup is the right kind
if (exists $args->{reply_markup}) {
my $reply_markup = $args->{reply_markup};
if ( ref($reply_markup) ne 'Teapot::Bot::Object::InlineKeyboardMarkup' &&
ref($reply_markup) ne 'Teapot::Bot::Object::ReplyKeyboardMarkup' &&
ref($reply_markup) ne 'Teapot::Bot::Object::ReplyKeyboardRemove' &&
ref($reply_markup) ne 'Teapot::Bot::Object::ForceReply' ) {
croak 'Incorrect reply_markup in sendMessage()';
}
$send_args->{reply_markup} = $reply_markup;
}
my $token = $self->token || croak 'No token supplied to sendMessage()?';
my $url = "https://api.telegram.org/bot${token}/sendMessage";
my $api_response = $self->_post_request($url, $send_args);
if ($api_response) {
return Teapot::Bot::Object::Message->create_from_hash($api_response, $self);
}
else {
return {'error' => 1};
}
}
sub forwardMessage {
my $self = shift;
my $args = shift || {};
my $send_args = {};
croak 'No chat_id supplied in forwardMessage()' unless $args->{chat_id};
$send_args->{chat_id} = $args->{chat_id};
croak 'No from_chat_id supplied in forwardMessage()' unless $args->{from_chat_id};
$send_args->{from_chat_id} = $args->{from_chat_id};
croak 'No message_id supplied in forwardMessage()' unless $args->{message_id};
$send_args->{message_id} = $args->{message_id};
# these are optional, send if they are supplied
$send_args->{disable_notification} = $args->{disable_notification} if exists $args->{disable_notification};
my $token = $self->token || croak 'No token supplied to forwardMessage()?';
my $url = "https://api.telegram.org/bot${token}/forwardMessage";
my $api_response = $self->_post_request($url, $send_args);
if ($api_response) {
return Teapot::Bot::Object::Message->create_from_hash($api_response, $self);
}
else {
return {'error' => 1};
}
}
sub sendPhoto {
my $self = shift;
my $args = shift || {};
my $send_args = {};
croak 'No chat_id supplied to sendPhoto()' unless $args->{chat_id};
$send_args->{chat_id} = $args->{chat_id};
# photo can be a string (which might be either a URL for telegram servers
# to fetch, or a file_id string) or a file on disk to upload - we need
# to handle that last case here as it changes the way we create the HTTP
# request
croak 'No photo supplied in sendPhoto()' unless $args->{photo};
if (-e $args->{photo}) {
$send_args->{photo} = { photo => { file => $args->{photo} } };
}
else {
$send_args->{photo} = $args->{photo};
}
my $token = $self->token || croak 'No token in sendPhoto()?';
my $url = "https://api.telegram.org/bot${token}/sendPhoto";
my $api_response = $self->_post_request($url, $send_args);
if ($api_response) {
return Teapot::Bot::Object::Message->create_from_hash($api_response, $self);
}
else {
return {'error' => 1};
}
}
sub sendChatAction {
my $self = shift;
my $args = shift || {};
my $send_args = {};
croak 'No chat_id supplied in sendChatAction()' unless $args->{chat_id};
$send_args->{chat_id} = $args->{chat_id};
unless (defined $args->{action}) {
$args->{action} = 'typing';
$send_args->{action} = 'typing';
}
if ($args->{action} eq 'upload_photo') {
$send_args->{action} = 'upload_photo';
}
elsif ($args->{action} eq 'record_video') {
$send_args->{action} = 'record_video';
}
elsif ($args->{action} eq 'upload_video') {
$send_args->{action} = 'upload_video';
}
elsif ($args->{action} eq 'record_audio') {
$send_args->{action} = 'record_audio';
}
elsif ($args->{action} eq 'upload_audio') {
$send_args->{action} = 'upload_audio';
}
elsif ($args->{action} eq 'upload_document') {
$send_args->{action} = 'upload_document';
}
elsif ($args->{action} eq 'find_location') {
$send_args->{action} = 'find_location';
}
elsif ($args->{action} eq 'record_video_note') {
$send_args->{action} = 'record_video_note';
}
elsif ($args->{action} eq 'upload_video_note') {
$send_args->{action} = 'upload_video_note';
}
else {
$send_args->{action} = 'typing';
}
my $token = $self->token || croak 'No token in sendChatAction()?';
my $url = "https://api.telegram.org/bot${token}/sendChatAction";
my $api_response = $self->_post_request ($url, $send_args);
return;
}
sub _add_getUpdates_handler {
my $self = shift;
my $http_active = 0;
my $last_update_id = -1;
my $token = $self->token;
Mojo::IOLoop->recurring(0.1 => sub {
# do nothing if our previous longpoll is still going
return if $http_active;
my $offset = $last_update_id + 1;
my $updateURL = "https://api.telegram.org/bot${token}/getUpdates?offset=${offset}&timeout=60";
$http_active = 1;
$self->ua->get($updateURL => sub {
my ($ua, $tx) = @_;
my $res = $tx->res->json;
my $items = $res->{result};
foreach my $item (@{$items}) {
$last_update_id = $item->{update_id};
$self->_process_message($item);
}
$http_active = 0;
});
});
return;
}
# process a message which arrived via getUpdates
sub _process_message {
my $self = shift;
my $item = shift;
my $update_id = $item->{update_id};
# 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};
# if we got to this point without creating a response, it must be a type we
# don't handle yet
if (! $update) {
cluck 'Do not know how to handle this update: ' . Dumper($item);
}
foreach my $listener (@{ $self->listeners }) {
# call the listener code, supplying ourself and the update
$listener->($self, $update);
}
return;
}
sub _post_request {
my $self = shift;
my $url = shift;
my $form_args = shift || {};
my $res = $self->ua->post($url, form => $form_args)->result;
if ($res->is_success) {
return $res->json->{result};
}
elsif ($res->is_error) {
# This can be non-fatal error: api change.
cluck 'Failed to post: ' . $res->message;
return 0; # to handle this as false in upper layers
}
else {
# This must be something fatal for sure, because either is_success or is_error must be set by Mojo
confess 'Not sure what went wrong';
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Brain - A base class to make your very own Telegram bot
=head1 VERSION
version 0.022
=head1 SYNOPSIS
package MyApp::Coolbot;
use Mojo::Base 'Teapot::Bot::Brain';
has token => 'token-you-got-from-@botfather';
sub init {
my $self = shift;
$self->add_repeating_task(600, \&timed_task);
$self->add_listener(\&respond_to_messages);
}
Elsewhere....
my $bot = MyApp::Coolbot->new();
$bot->think; # this will block unless there is already an event
# loop running
=head1 DESCRIPTION
This base class makes it easy to create your own Bot classes that
interface with the Telegram Bot API.
Internally it uses the Mojo::IOLoop event loop to provide non-blocking
access to the Bot API, allowing your bot to listen for events via the
longpoll getUpdates API method and also trigger timed events that can
run without blocking.
As with any bot framework, the principle is that the framework allows you
to interact with other users on Telegram. The Telegram API provides a rich
set of typed objects. This framework will allow you to create those objects
to send into the API (for instance, sending text messages, sending photos,
and more) as well as call your code (via L<add_listener> when your bot
receives messages (which might be text, or images, and so on).
How bots work with Telegram is out of scope for this document, a good
starting place is L<https://core.telegram.org/bots>.
=head1 METHODS
=head2 add_repeating_task
This method will add a sub to run every C<$seconds> seconds. Pass this method
two parameters, the number of seconds between executions, and the coderef to
execute.
Your coderef will be passed the L<Teapot::Bot::Brain> object when it is
executed.
=head2 add_listener
Respond to messages we receive. It takes a single argument, a coderef to execute
for each update that is sent to us. These are *typically* C<Teapot::Bot:Object::Message>
objects, though that is not the only type of update that may be sent (see
L<https://core.telegram.org/bots/api#update>).
Multiple listeners can be added, they will receive the incoming update in the order
that they are registered.
Any or all listeners can choose to ignore or take action on any particular update.
=head2 think
Start this bot thinking.
Calls your init method and then enters a blocking loop (unless a Mojo::IOLoop
is already running).
=head2 getMe
This is the wrapper around the C<getMe> API method. See
L<https://core.telegram.org/bots/api#getme>.
Takes no arguments, and returns the L<Teapot::Bot::Object::User> that
represents this bot.
On error returns hash reference with error set to 1
=head2 getChatMember
This is the wrapper around the C<getChatMember> API method. See
L<https://core.telegram.org/bots/api#getchatmember>.
Takes chat_id, and user_id as arguments.
Returns the L<Teapot::Bot::Object::ChatMember> that represents properties
of Chat User.
On error returns hash reference with error set to 1
=head2 getChat
This is the wrapper around the C<getChat> API method. See
L<https://core.telegram.org/bots/api#getchat>.
Takes chat_id as argument.
Returns the L<Teapot::Bot::Object::Chat> that represents properties of Chat.
On error returns hash reference with error set to 1
=head2 sendMessage
See L<https://core.telegram.org/bots/api#sendmessage>.
Returns a L<Teapot::Bot::Object::Message> object.
On error returns hash reference with error set to 1
=head2 forwardMessage
See L<https://core.telegram.org/bots/api#forwardmessage>.
Returns a L<Teapot::Bot::Object::Message> object.
On error returns hash reference with error set to 1
=head2 sendPhoto
See L<https://core.telegram.org/bots/api#sendphoto>.
Returns a L<Teapot::Bot::Object::Message> object.
On error returns hash reference with error set to 1
=head2 sendChatAction
See L<https://core.telegram.org/bots/api#sendchataction>.
Returns nothing, it's send-only method (Telegram API returns true on success)
=head1 SEE ALSO
=over 4
=item *
L<Mojolicious>
=item *
L<https://core.telegram.org/bots>
=back
=head1 Telegram Bot API methods
The following methods are relatively thin wrappers around the various
methods available in the Telgram Bot API to send messages and perform other
updates.
L<https://core.telegram.org/bots/api#available-methods>
They all return immediately with the corresponding Teapot::Bot::Object
subclass - consult the documenation for each below to see what to expect.
Note that not all methods have yet been implemented.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,59 @@
package Teapot::Bot::Object::Animation;
# ABSTRACT: The base class for Telegram message 'Animation' type.
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::PhotoSize;
use Carp qw/croak/;
$Teapot::Bot::Object::Animation::VERSION = '0.022';
has 'file_id';
has 'width';
has 'height';
has 'duration';
has 'thumb'; #PhotoSize
has 'file_name';
has 'mime_type';
has 'file_size';
sub fields {
return { scalar => [qw/file_id width height duration file_name mime_type file_size/],
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Animation - The base class for Telegram message 'Animation' type
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram message 'Animation' type.
See L<https://core.telegram.org/bots/api#animation> for details of the
attributes available for L<Teapot::Bot::Object::Animation> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,55 @@
package Teapot::Bot::Object::Audio;
# ABSTRACT: The base class for Telegram 'Audio' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::Audio::VERSION = '0.022';
has 'file_id';
has 'duration';
has 'performer';
has 'title';
has 'mime_type';
has 'file_size';
has 'thumb'; #PhotoSize
sub fields {
return { scalar => [qw/file_id duration performer title mime_type file_size/],
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Audio - The base class for Telegram 'Audio' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Audio' type objects.
See L<https://core.telegram.org/bots/api#audio> for details of the
attributes available for L<Teapot::Bot::Object::Audio> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,184 @@
package Teapot::Bot::Object::Base;
# ABSTRACT: The base class for all Teapot::Bot::Object objects.
use Mojo::Base -base;
use List::Util qw/any/;
use Carp qw/croak/;
$Teapot::Bot::Object::Base::VERSION = '0.022';
has '_brain'; # a reference to our brain
sub arrays { return qw// } # override if needed
sub _field_is_array {
my $self = shift;
my $field = shift;
if (any { /^$field$/ } $self->arrays) {
return 1;
}
return;
}
sub array_of_arrays { return qw// } #override if needed
sub _field_is_array_of_arrays {
my $self = shift;
my $field = shift;
if (any { /^$field$/ } $self->array_of_arrays) {
return 1;
}
return;
}
# create an object from a hash. Needs to deal with the nested types, and
# arrays
sub create_from_hash {
my $class = shift;
my $hash = shift;
my $brain = shift || croak 'No brain supplied to create_from_hash()';
my $obj = $class->new(_brain => $brain);
# deal with each type of field
foreach my $type (keys %{ $class->fields }) {
my @fields_of_this_type = @{ $class->fields->{$type} };
foreach my $field (@fields_of_this_type) {
# ignore fields for which we have no value in the hash
next if (! defined $hash->{$field} );
# warn "type: $type field $field\n";
if ($type eq 'scalar') {
if ($obj->_field_is_array($field)) {
# simple scalar array ref, so just copy it
my $val = $hash->{$field};
# deal with boolean stuff so we don't pollute our object
# with JSON
if (ref($val) eq 'JSON::PP::Boolean') {
$val = !!$val;
}
$obj->$field($val);
}
elsif ($obj->_field_is_array_of_arrays) {
croak 'Not yet implemented for scalars';
}
else {
my $val = $hash->{$field};
if (ref($val) eq 'JSON::PP::Boolean') {
$val = 0+$val;
}
$obj->$field($val);
}
}
else {
if ($obj->_field_is_array($field)) {
my @sub_array;
foreach my $data ( @{ $hash->{$field} } ) {
push @sub_array, $type->create_from_hash($data, $brain);
}
$obj->$field(\@sub_array);
}
elsif ($obj->_field_is_array_of_arrays) {
croak 'Not yet implemented for scalars';
}
else {
$obj->$field($type->create_from_hash($hash->{$field}, $brain));
}
}
}
}
return $obj;
}
sub as_hashref {
my $self = shift;
my $hash = {};
# add the simple scalar values
foreach my $type ( keys %{ $self->fields }) {
my @fields = @{ $self->fields->{$type} };
foreach my $field (@fields) {
if ($type eq 'scalar') {
$hash->{$field} = $self->$field;
}
else {
# non array types
$hash->{$field} = $self->$field->as_hashref
if (ref($self->$field) ne 'ARRAY' && defined $self->$field);
# array types
$hash->{$field} = [
map { $_->as_hashref } @{ $self->$field }
] if (ref($self->$field) eq 'ARRAY');
}
}
}
return $hash;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Base - The base class for all Telegram::Bot::Object objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for all Telegram::Bot::Object objects.
This class should not be instantiated itself. Instead, instantiate a sub-class.
You should generally not need to instantiate objects of sub-classes of L<Teapot::Bot::Object::Base>,
instead the appropriate objects will be created from an incoming request via
L<Teapot::Bot::Brain>.
You can then use the methods referenced below on those objects.
=head1 METHODS
=head2 arrays
Should be overridden by subclasses, returning an array listing of which fields
for the object are arrays.
=head2 array_of_arrays
Should be overridden by subclasses, returning an array listing od which fields
for the object are arrays of arrays.
=head2 create_from_hash
Create an object of the appropriate class, including any sub-objects of
other types, as needed.
=head2 as_hashref
Return this object as a hashref.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,47 @@
package Teapot::Bot::Object::CallbackGame;
# ABSTRACT: The base class for Telegram message 'CallbackGame' type.
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::CallbackGame::VERSION = '0.022';
# https://core.telegram.org/bots/api#callbackgame
# "A placeholder, currently holds no information. Use BotFather to set up your game"
sub fields {
return { },
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::CallbackGame - The base class for Telegram message 'CallbackGame' type
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram message 'CallbackGame' type.
See L<https://core.telegram.org/bots/api#callbackgame> for details of the
attributes available for L<Teapot::Bot::Object::CallbackGame> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,91 @@
package Teapot::Bot::Object::Chat;
# ABSTRACT: The base class for Telegram 'Chat' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::ChatPhoto;
use Teapot::Bot::Object::Message;
use Teapot::Bot::Object::ChatPermissions;
$Teapot::Bot::Object::Chat::VERSION = '0.022';
has 'id';
has 'type';
has 'title'; # Optional.
has 'username'; # Optional.
has 'first_name'; # Optional.
has 'last_name'; # Optional.
has 'photo'; # Teapot::Bot::Object::ChatPhoto. Optional. Returned only in getChat.
has 'description'; # Optional. Returned only in getChat.
has 'invite_link'; # Optional. Returned only in getChat.
has 'pinned_message'; # Teapot::Bot::Object::Message
has 'permissions'; # Teapot::Bot::Object::ChatPermissions. Optional. Default chat member permissions, for
# groups and supergroups. Returned only in getChat.
has 'slow_mode_delay'; # Optional. Returned only in getChat.
has 'sticker_set_name'; # Optional. Returned only in getChat.
has 'can_set_sticker_set'; # Optional. Returned only in getChat.
sub fields {
return {
'scalar' => [qw/id type title username first_name last_name description
invite_link slow_mode_delay sticker_set_name
can_set_sticker_set /],
'Teapot::Bot::Object::ChatPhoto' => [qw/photo/],
'Teapot::Bot::Object::Message' => [qw/pinned_message/],
'Teapot::Bot::Object::ChatPermissions' => [qw/permissions/],
};
}
sub is_user {
return shift->id > 0;
}
sub is_group {
return shift->id < 0;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Chat - The base class for Telegram 'Chat' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Chat' type objects.
See L<https://core.telegram.org/bots/api#chat> for details of the
attributes available for L<Teapot::Bot::Object::Chat> objects.
=head1 METHODS
=head2 is_user
Returns true is this is a chat is a single user.
=head2 is_group
Returns true if this is a chat is a group.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,72 @@
package Teapot::Bot::Object::ChatMember;
# ABSTRACT: The base class for Telegram 'ChatMember' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::User;
$Teapot::Bot::Object::ChatMember::VERSION = '0.022';
has 'user';
has 'status';
has 'custom_title'; # optional. Owner and administrators only.
has 'until'; # optional. Restricted and kicked only.
has 'can_be_edited'; # optional. Administrators only.
has 'can_post_messages'; # optional. Administrators only.
has 'can_edit_messages'; # optional. Administrators only.
has 'can_delete_messages'; # optional. Administrators only.
has 'can_restrict_members'; # optional. Administrators only.
has 'can_promote_members'; # optional. Administrators only.
has 'can_change_info'; # optional. Administrators and restricted only.
has 'can_invite_users'; # optional. Administrators and restricted only.
has 'can_pin_messages'; # optional. Administrators and restricted only.
has 'is_member'; # optional. Restricted only.
has 'can_send_messages'; # optional. Restricted only.
has 'can_send_media_messages'; # optional. Restricted only.
has 'can_send_polls'; # optional. Restricted only.
has 'can_send_other_messages'; # optional. Restricted only.
has 'can_add_web_page_previews'; # optional. Restricted only.
sub fields {
return {
'scalar' => [qw/status custom_title until 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/],
'Teapot::Bot::Object::User' => [qw/user/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::ChatMember - The base class for Telegram 'ChatMember' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'ChatMember' type objects.
See L<https://core.telegram.org/bots/api#chatmember> for details of the
attributes available for L<Teapot::Bot::Object::ChatMember> objects.
=head1 AUTHOR
Sergei Fedosov <eleksir@gmail.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2020 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

View File

@@ -0,0 +1,64 @@
package Teapot::Bot::Object::ChatPermissions;
# ABSTRACT: The base class for Telegram 'ChatPermissions' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::ChatPermissions::VERSION = '0.022';
# 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
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
# and voice notes, 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,
# implies can_send_media_messages
has 'can_add_web_page_previews'; # True, if the user is allowed to add web page previews to their messages, implies
# can_send_media_messages
has 'can_change_info'; # True, if the user is allowed to change the chat title, photo and other settings.
# Ignored in public supergroups
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
sub fields {
return {
'scalar' => [qw/can_send_messages can_send_media_messages can_send_polls
can_send_other_messages can_add_web_page_previews can_change_info
can_invite_users can_pin_messages/]
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::ChatPermissions - The base class for Telegram 'ChatPermissions' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'ChatPermissions' type objects.
See L<https://core.telegram.org/bots/api#chatpermissions> for details of the
attributes available for L<Teapot::Bot::Object::ChatPermissions> objects.
=head1 AUTHOR
Sergei Fedosov <eleksir@gmail.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2020 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

View File

@@ -0,0 +1,50 @@
package Teapot::Bot::Object::ChatPhoto;
# ABSTRACT: The base class for Telegram 'ChatPhoto' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::ChatPhoto::VERSION = '0.022';
has 'small_file_id';
has 'big_file_id';
sub fields {
return {
'scalar' => [qw/small_file_id big_file_id/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::ChatPhoto - The base class for Telegram 'ChatPhoto' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'ChatPhoto' type objects.
See L<https://core.telegram.org/bots/api#chatphoto> for details of the
attributes available for L<Teapot::Bot::Object::ChatPhoto> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,52 @@
package Teapot::Bot::Object::Contact;
# ABSTRACT: The base class for Telegram 'Contact' objects.
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::Contact::VERSION = '0.022';
has 'phone_number';
has 'first_name';
has 'last_name';
has 'user_id';
sub fields {
return {
scalar => [qw/phone_number first_name last_name user_id/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Contact - The base class for Telegram 'Contact' objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Contact' objects.
See L<https://core.telegram.org/bots/api#contact> for details of the
attributes available for L<Teapot::Bot::Object::Contact> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,56 @@
package Teapot::Bot::Object::Document;
# ABSTRACT: The base class for Telegram 'Document' objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::PhotoSize;
$Teapot::Bot::Object::Document::VERSION = '0.022';
has 'file_id';
has 'thumb'; #PhotoSize
has 'file_name';
has 'mime_type';
has 'file_size';
sub fields {
return {
scalar => [qw/file_id file_name mime_type file_size/],
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/]
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Document - The base class for Telegram 'Document' objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Document' objects.
See L<https://core.telegram.org/bots/api#document> for details of the
attributes available for L<Teapot::Bot::Object::Document> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,49 @@
package Teapot::Bot::Object::EncryptedCredentials;
# ABSTRACT: The base class for Telegram 'EncryptedCredentials' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::EncryptedCredentials::VERSION = '0.022';
has 'data';
has 'hash';
has 'secret';
sub fields {
return { 'scalar' => [qw/ data hash secret/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::EncryptedCredentials - The base class for Telegram 'EncryptedCredentials' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'EncryptedCredentials' type objects.
See L<https://core.telegram.org/bots/api#encryptedcredentials> for details of the
attributes available for L<Teapot::Bot::Object::EncryptedCredentials> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,57 @@
package Teapot::Bot::Object::EncryptedPassportElement;
# ABSTRACT: The base class for Telegram 'EncryptedPassportElement' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::EncryptedPassportElement::VERSION = '0.022';
# XXX Implement rest of this
# https://core.telegram.org/bots/api#encryptedpassportelement
has 'type';
has 'data';
has 'phone_number';
has 'email';
# XXX more here
sub fields {
return { 'scalar' => [qw/type data phone_number email/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::EncryptedPassportElement - The base class for Telegram 'EncryptedPassportElement' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'EncryptedPassportElement' type objects.
See L<https://core.telegram.org/bots/api#encryptedpassportelement> for details of the
attributes available for L<Teapot::Bot::Object::EncryptedPassportElement> objects.
Note that this type is not yet fully implemented.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,63 @@
package Teapot::Bot::Object::Game;
# ABSTRACT: The base class for Telegram message 'Game' type.
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::PhotoSize;
use Teapot::Bot::Object::Animation;
use Teapot::Bot::Object::MessageEntity;
$Teapot::Bot::Object::Game::VERSION = '0.022';
has 'title';
has 'description';
has 'photo'; # Array of PhotoSize
has 'text';
has 'text_entities'; #Array of MessageEntity
has 'animation'; #Animation
sub fields {
return {
scalar => [qw/title description text/],
'Teapot::Bot::Object::PhotoSize' => [qw/photo/],
'Teapot::Bot::Object::MessageEntity' => [qw/text_entities/],
'Teapot::Bot::Object::Animation' => [qw/animation/],
};
}
sub arrays { return qw/photo text_entities/; }
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Game - The base class for Telegram message 'Game' type
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram message 'Game' type.
See L<https://core.telegram.org/bots/api#game> for details of the
attributes available for L<Teapot::Bot::Object::Game> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,61 @@
package Teapot::Bot::Object::InlineKeyboardButton;
# ABSTRACT: The base class for Telegram 'InlineKeyboardButton' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::LoginUrl;
use Teapot::Bot::Object::CallbackGame;
$Teapot::Bot::Object::InlineKeyboardButton::VERSION = '0.022';
has 'text';
has 'url';
has 'login_url'; #LoginUrl
has 'callback_data';
has 'switch_inline_query';
has 'switch_inline_query_current_chat';
has 'callback_game'; # CallbackGame
has 'pay';
sub fields {
return { 'scalar' => [qw/text url callback_data switch_inline_query
switch_inline_query_current_chat switch_inline_query_current_chat
pay/],
'Teapot::Bot::Object::LoginUrl' => [qw/login_url/],
'Teapot::Bot::Object::CallbackGame' => [qw/callback_game/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::InlineKeyboardButton - The base class for Telegram 'InlineKeyboardButton' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'InlineKeyboardButton' type objects.
See L<https://core.telegram.org/bots/api#inlinekeyboardbutton> for details of the
attributes available for L<Teapot::Bot::Object::InlineKeyboardButton> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,52 @@
package Teapot::Bot::Object::InlineKeyboardMarkup;
# ABSTRACT: The base class for Telegram 'InlineKeyboardMarkup' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::InlineKeyboardButton;
$Teapot::Bot::Object::InlineKeyboardMarkup::VERSION = '0.022';
has 'inline_keyboard';
sub fields {
return { 'Teapot::Bot::Object::InlineKeyboardButton' => [qw/inline_keyboard/] };
}
sub array_of_arrays {
return qw/inline_keyboard/;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::InlineKeyboardMarkup - The base class for Telegram 'InlineKeyboardMarkup' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'InlineKeyboardMarkup' type objects.
See L<https://core.telegram.org/bots/api#inlinekeyboardmarkup> for details of the
attributes available for L<Teapot::Bot::Object::InlineKeyboardMarkup> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,51 @@
package Teapot::Bot::Object::Invoice;
# ABSTRACT: The base class for Telegram 'Invoice' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::Invoice::VERSION = '0.022';
has 'title';
has 'description';
has 'start_parameter';
has 'currency';
has 'total_amount';
sub fields {
return { scalar => [qw/title description start_parameter currency total_amount/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Invoice - The base class for Telegram 'Invoice' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Invoice' type objects.
See L<https://core.telegram.org/bots/api#invoice> for details of the
attributes available for L<Teapot::Bot::Object::Invoice> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,48 @@
package Teapot::Bot::Object::Location;
# ABSTRACT: The base class for Telegram message 'Location' type.
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::Location::VERSION = '0.022';
has 'longitude';
has 'latitude';
sub fields {
return { scalar => [qw/longitude latitude/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Location - The base class for Telegram message 'Location' type
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram message 'Location' type.
See L<https://core.telegram.org/bots/api#location> for details of the
attributes available for L<Teapot::Bot::Object::Location> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,50 @@
package Teapot::Bot::Object::LoginUrl;
# ABSTRACT: The base class for Telegram 'LoginUrl' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::LoginUrl::VERSION = '0.022';
has 'url';
has 'forward_text';
has 'bot_username';
has 'request_write_access';
sub fields {
return { 'scalar' => [qw/url forward_text bot_username request_write_access/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::LoginUrl - The base class for Telegram 'LoginUrl' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'LoginUrl' type objects.
See L<https://core.telegram.org/bots/api#loginurl> for details of the
attributes available for L<Teapot::Bot::Object::LoginUrl> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,193 @@
package Teapot::Bot::Object::Message;
# ABSTRACT: The base class for the Telegram type "Message".
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::User;
use Teapot::Bot::Object::Chat;
use Teapot::Bot::Object::ChatMember;
use Teapot::Bot::Object::ChatPermissions;
use Teapot::Bot::Object::MessageEntity;
use Teapot::Bot::Object::Audio;
use Teapot::Bot::Object::Document;
use Teapot::Bot::Object::Animation;
use Teapot::Bot::Object::Game;
use Teapot::Bot::Object::PhotoSize;
use Teapot::Bot::Object::Sticker;
use Teapot::Bot::Object::Video;
use Teapot::Bot::Object::Voice;
use Teapot::Bot::Object::VideoNote;
use Teapot::Bot::Object::Contact;
use Teapot::Bot::Object::Location;
use Teapot::Bot::Object::Poll;
use Teapot::Bot::Object::Location;
use Teapot::Bot::Object::PhotoSize;
use Teapot::Bot::Object::Invoice;
use Teapot::Bot::Object::Venue;
use Teapot::Bot::Object::SuccessfulPayment;
use Teapot::Bot::Object::PassportData;
use Teapot::Bot::Object::InlineKeyboardMarkup;
use Data::Dumper;
$Teapot::Bot::Object::Message::VERSION = '0.022';
# basic message stuff
has 'message_id';
has 'from'; # User
has 'date';
has 'chat'; # Chat
has 'forward_from'; # User
has 'forward_from_chat'; # Chat
has 'forward_from_message_id';
has 'forward_signature';
has 'forward_sender_name';
has 'forward_date';
has 'reply_to_message'; # Message
has 'via_bot'; # User
has 'edit_date';
has 'media_group_id';
has 'author_signature';
has 'text';
has 'entities'; # Array of MessageEntity
has 'caption_entities'; # Array of MessageEntity
has 'audio'; # Audio
has 'document'; # Document
has 'animation'; # Animation
has 'game'; # Game
has 'photo'; # Array of PhotoSize
has 'sticker'; # Sticker
has 'video'; # Video
has 'voice'; # Voice
has 'video_note'; # VideoNote
has 'caption';
has 'contact'; # Contact
has 'location'; # Location
has 'venue'; # Venue
has 'poll'; # Poll
has 'new_chat_members'; # Array of User
has 'left_chat_member'; # User
has 'new_chat_title';
has 'new_chat_photo'; # Array of PhotoSize
has 'delete_chat_photo';
has 'group_chat_created';
has 'supergroup_chat_created';
has 'channel_chat_created';
has 'migrate_to_chat_id';
has 'migrate_from_chat_id';
has 'pinned_message'; # Message
has 'invoice'; # Invoice
has 'successful_payment'; # SuccessfulPayment
has 'connected_website';
has 'passport_data'; # PassportData
has 'reply_markup'; # Array of InlineKeyboardMarkup
sub fields {
return {
'scalar' => [qw/message_id date forward_from_message_id
forward_signature forward_sender_name
forward_date edit_date media_group_id
author_signature text caption
new_chat_title delete_chat_photo
group_chat_created supergroup_chat_created
channel_chat_created migrate_to_chat_id
migrate_from_chat_id connected_website/],
'Teapot::Bot::Object::User' => [qw/from forward_from via_bot new_chat_members left_chat_member /],
'Teapot::Bot::Object::Chat' => [qw/chat forward_from_chat/],
'Teapot::Bot::Object::Message' => [qw/reply_to_message pinned_message/],
'Teapot::Bot::Object::MessageEntity' => [qw/entities caption_entities /],
'Teapot::Bot::Object::Audio' => [qw/audio/],
'Teapot::Bot::Object::Document' => [qw/document/],
'Teapot::Bot::Object::Animation' => [qw/animation/],
'Teapot::Bot::Object::Game' => [qw/game/],
'Teapot::Bot::Object::PhotoSize' => [qw/photo new_chat_photo/],
'Teapot::Bot::Object::Sticker' => [qw/sticker/],
'Teapot::Bot::Object::Video' => [qw/video/],
'Teapot::Bot::Object::Voice' => [qw/voice/],
'Teapot::Bot::Object::VideoNote' => [qw/video_note/],
'Teapot::Bot::Object::Contact' => [qw/contact/],
'Teapot::Bot::Object::Location' => [qw/location/],
'Teapot::Bot::Object::Venue' => [qw/venue/],
'Teapot::Bot::Object::Poll' => [qw/poll/],
'Teapot::Bot::Object::Invoice' => [qw/invoice/],
'Teapot::Bot::Object::SuccessfulPayment' => [qw/successful_payment/],
'Teapot::Bot::Object::PassportData' => [qw/passport_data/],
'Teapot::Bot::Object::InlineKeyboardMarkup' => [qw/reply_markup/],
};
}
sub arrays {
return qw/photo entities caption_entities new_chat_members new_chat_photo/;
}
sub reply {
my $self = shift;
my $text = shift;
return $self->_brain->sendMessage({chat_id => $self->chat->id, text => $text});
}
sub typing {
my $self = shift;
return $self->_brain->sendChatAction({chat_id => $self->chat->id});
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Message - The base class for the Telegram type "Message"
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for the Telegram type "Message".
See L<https://core.telegram.org/bots/api#message> for details of the
attributes available for L<Teapot::Bot::Object::Message> objects.
=head1 METHODS
=head2 reply
A convenience method to reply to a message with text.
Will return the L<Teapot::Bot::Object::Message> object representing the message
sent.
=head2 typing
Sends notification to chat that bot is "typing" something.
Returns nothing that should be checked.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,56 @@
package Teapot::Bot::Object::MessageEntity;
# ABSTRACT: The base class for Telegram 'MessageEntity' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::User;
$Teapot::Bot::Object::MessageEntity::VERSION = '0.022';
has 'type';
has 'offset';
has 'length';
has 'url'; # Optional.
has 'user'; # Optional. Teapot::Bot::Object::User
has 'language'; # Optional. For “pre” only, the programming language of the entity text
sub fields {
return {
'scalar' => [qw/type offset length url language/],
'Teapot::Bot::Object::User' => [qw/user/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::MessageEntity - The base class for Telegram 'MessageEntity' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'MessageEntity' type objects.
See L<https://core.telegram.org/bots/api#messageentity> for details of the
attributes available for L<Teapot::Bot::Object::MessageEntity> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,57 @@
package Teapot::Bot::Object::PassportData;
# ABSTRACT: The base class for Telegram 'PassportData' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::EncryptedPassportElement;
use Teapot::Bot::Object::EncryptedCredentials;
$Teapot::Bot::Object::PassportData::VERSION = '0.022';
has 'data'; # Array of EncryptedPassportElement
has 'credentials'; # EncryptedCredentials
sub fields {
return {
'Teapot::Bot::Object::EncryptedPassportElement' => [qw/data/],
'Teapot::Bot::Object::EncryptedCredentials' => [qw/credentials/],
};
}
sub arrays {
return qw/data/;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::PassportData - The base class for Telegram 'PassportData' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'PassportData' type objects.
See L<https://core.telegram.org/bots/api#passportdata> for details of the
attributes available for L<Teapot::Bot::Object::PassportData> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,51 @@
package Teapot::Bot::Object::PhotoSize;
# ABSTRACT: The base class for Telegram message 'PhotoSize' type.
use Mojo::Base 'Teapot::Bot::Object::Base';
use Carp qw/croak/;
$Teapot::Bot::Object::PhotoSize::VERSION = '0.022';
has 'file_id';
has 'width';
has 'height';
has 'file_size';
sub fields {
return { scalar => [qw/file_id width height file_size/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::PhotoSize - The base class for Telegram message 'PhotoSize' type
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram message 'PhotoSize' type.
See L<https://core.telegram.org/bots/api#photosize> for details of the
attributes available for L<Teapot::Bot::Object::PhotoSize> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,58 @@
package Teapot::Bot::Object::Poll;
# ABSTRACT: The base class for Telegram 'Poll' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::PollOption;
$Teapot::Bot::Object::Poll::VERSION = '0.022';
has 'id';
has 'question';
has 'options'; # Array of PollOption
has 'is_closed';
sub fields {
return {
scalar => [qw/id question is_closed/],
'Teapot::Bot::Object::PollOption' => [qw/options/],
};
}
sub arrays {
return qw/options/;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Poll - The base class for Telegram 'Poll' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Poll' type objects
See L<https://core.telegram.org/bots/api#poll> for details of the
attributes available for L<Teapot::Bot::Object::Poll> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,48 @@
package Teapot::Bot::Object::PollOption;
# ABSTRACT: The base class for Telegram 'PollOption' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::PollOption::VERSION = '0.022';
has 'text';
has 'voter_count';
sub fields {
return { scalar => [qw/text voter_count/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::PollOption - The base class for Telegram 'PollOption' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'PollOption' type objects.
See L<https://core.telegram.org/bots/api#polloption> for details of the
attributes available for L<Teapot::Bot::Object::PollOption> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,58 @@
package Teapot::Bot::Object::Sticker;
# ABSTRACT: The base class for Telegram message 'Sticker' type.
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::PhotoSize;
$Teapot::Bot::Object::Sticker::VERSION = '0.022';
has 'file_id';
has 'width';
has 'height';
has 'thumb'; # PhotoSize
has 'emoji';
has 'set_name';
# has 'mask_position'; # XXX TODO
has 'file_size';
sub fields {
return {
scalar => [ qw/file_id width height emoji set_name file_size/ ],
'Teapot::Bot::Object::PhotoSize' => [ qw/thumb/ ],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Sticker - The base class for Telegram message 'Sticker' type
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram message 'Sticker' type.
See L<https://core.telegram.org/bots/api#sticker> for details of the
attributes available for L<Teapot::Bot::Object::Sticker> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,58 @@
package Teapot::Bot::Object::SuccessfulPayment;
# ABSTRACT: The base class for Telegram 'SuccessfulPayment' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
# use Teapot::Bot::Object::OrderInfo;
$Teapot::Bot::Object::SuccessfulPayment::VERSION = '0.022';
has 'currency';
has 'total_amount';
has 'invoice_payload';
has 'shipping_option_id';
# has 'order_info'; #OrderInfo XXX
has 'telegram_payment_charge_id';
has 'provider_payment_charge_id';
sub fields {
return {
scalar => [qw/currency total_amount invoice_payload shipping_option_id
telegram_payment_charge_id provider_payment_charge_id/],
# 'Teapot::Bot::Object::OrderInfo' => [qw/order_info/],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::SuccessfulPayment - The base class for Telegram 'SuccessfulPayment' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'SuccessfulPayment' type objects.
See L<https://core.telegram.org/bots/api#successfulpayment> for details of the
attributes available for L<Teapot::Bot::Object::SuccessfulPayment> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,59 @@
package Teapot::Bot::Object::User;
# ABSTRACT: The base class for Telegram message 'User' type.
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::User::VERSION = '0.022';
has 'id';
has 'is_bot';
has 'first_name';
has 'last_name'; # optional
has 'username'; # optional
has 'language_code'; # optional
has 'can_join_groups'; # optional, only for getMe() method
has 'can_read_all_group_messages';# optional, only for getMe() method
has 'supports_inline_queries'; # optional, only for getMe() method
sub fields {
return {
scalar => [qw/id is_bot first_name last_name username language_code can_join_groups
can_read_all_group_messages supports_inline_queries/]
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::User - The base class for Telegram message 'User' type
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram message 'User' type.
See L<https://core.telegram.org/bots/api#user> for details of the
attributes available for L<Teapot::Bot::Object::User> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,56 @@
package Teapot::Bot::Object::Venue;
# ABSTRACT: The base class for Telegram 'LoginUrl' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::Location;
$Teapot::Bot::Object::Venue::VERSION = '0.022';
has 'location'; #Location
has 'title';
has 'address';
has 'foursquare_id';
has 'foursquare_type';
sub fields {
return {
'scalar' => [qw/title address foursquare_id foursquare_type/],
'Teapot::Bot::Object::Location' => [qw/location/]
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Venue - The base class for Telegram 'LoginUrl' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'LoginUrl' type objects.
See L<https://core.telegram.org/bots/api#venue> for details of the
attributes available for L<Teapot::Bot::Object::Venue> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,57 @@
package Teapot::Bot::Object::Video;
# ABSTRACT: The base class for Telegram 'Video' object.
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::PhotoSize;
$Teapot::Bot::Object::Video::VERSION = '0.022';
has 'file_id';
has 'width';
has 'height';
has 'duration';
has 'thumb'; #PhotoSize
has 'mime_type';
has 'file_size';
sub fields {
return {
scalar => [qw/file_id width height duration mime_type file_size/],
'Teapot::Bot::Object::PhotoSize' => [qw/thumb/]
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Video - The base class for Telegram 'Video' object
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Video' object.
See L<https://core.telegram.org/bots/api#video> for details of the
attributes available for L<Teapot::Bot::Object::Video> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,57 @@
package Teapot::Bot::Object::VideoNote;
# ABSTRACT: The base class for Telegram 'VideoNote' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
use Teapot::Bot::Object::PhotoSize;
$Teapot::Bot::Object::VideoNote::VERSION = '0.022';
has 'file_id';
has 'length';
has 'duration';
has 'mime_type';
has 'thumb'; #PhotoSize
has 'file_size';
sub fields {
return {
scalar => [qw/file_id length duration mime_type file_size/],
'Teapot::Bot::Object::PhotoSize' => [qw/thumb /],
};
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::VideoNote - The base class for Telegram 'VideoNote' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'VideoNote' type object.
See L<https://core.telegram.org/bots/api#videonote> for details of the
attributes available for L<Teapot::Bot::Object::VideoNote> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -0,0 +1,50 @@
package Teapot::Bot::Object::Voice;
# ABSTRACT: The base class for Telegram 'Voice' type objects
use Mojo::Base 'Teapot::Bot::Object::Base';
$Teapot::Bot::Object::Voice::VERSION = '0.022';
has 'file_id';
has 'duration';
has 'mime_type';
has 'file_size';
sub fields {
return { scalar => [qw/file_id duration mime_type file_size/] };
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Teapot::Bot::Object::Voice - The base class for Telegram 'Voice' type objects
=head1 VERSION
version 0.022
=head1 DESCRIPTION
The base class for Telegram 'Voice' type objects.
See L<https://core.telegram.org/bots/api#voice> for details of the
attributes available for L<Teapot::Bot::Object::Voice> objects.
=head1 AUTHOR
Justin Hawkins <justin@eatmorecode.com>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2019 by Justin Hawkins.
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

View File

@@ -10,12 +10,11 @@ use Data::Dumper;
use open qw(:std :utf8);
use File::Path qw( mkpath );
use Hailo;
use Encode;
use Mojo::Base 'Telegram::Bot::Brain';
use Mojo::Base 'Teapot::Bot::Brain';
use conf qw(loadConf);
use botlib qw(weather logger trim randomCommonPhrase);
use telegramlib qw(getChat getChatMember sendChatAction visavi);
use telegramlib qw(visavi);
use lat qw(latAnswer);
use Exporter qw(import);
@@ -56,7 +55,13 @@ sub __on_msg {
$can_talk = 0;
unless ($myid) {
my $myObj = Telegram::Bot::Brain::getMe ($self);
my $myObj = Teapot::Bot::Brain::getMe ($self);
unless ($myObj) {
sleep 3;
$myObj = Teapot::Bot::Brain::getMe ($self);
}
$myid = $myObj->id;
# TODO: use these values instead of pre-defined in config!
$myusername = $myObj->username;
@@ -100,12 +105,23 @@ sub __on_msg {
# works only for public chats, so id shoud be < 0.
if ($chatid < 0) {
my $chatobj = getChat ($self, $chatid);
my $chatobj = Teapot::Bot::Brain::getChat ($self, { 'chat_id' => $chatid });
unless ($chatobj) {
sleep 3;
$chatobj = Teapot::Bot::Brain::getChat ($self, { 'chat_id' => $chatid });
}
# actually evaluates to 1 for true and to 0 for false
$group_talk = int ($chatobj->{permissions}->{can_send_messages});
my $chatObj = getChatMember ($self, $chatid, $myid);
my $me = Teapot::Bot::Brain::getChatMember ($self, { 'chat_id' => $chatid, 'user_id' => $myid });
if ($chatObj->{'status'} eq 'administrator') {
unless ($me) {
sleep 3;
$me = Teapot::Bot::Brain::getChatMember ($self, { 'chat_id' => $chatid, 'user_id' => $myid });
}
if ($me->{'status'} eq 'administrator') {
logger "I can talk in group chat $chatname ($chatid)";
$can_talk = 1;
} else {
@@ -114,7 +130,7 @@ sub __on_msg {
$can_talk = $group_talk;
}
} else {
# private chat, so definely can talk
# private chat, so definely bot can talk
logger "I can talk in private chat $chatname ($chatid)";
$can_talk = 1;
}
@@ -165,14 +181,14 @@ sub __on_msg {
sleep (int ( rand (2) + 1));
for (0..(4 + int (rand (3)))) {
sendChatAction ($self, $chatid);
$msg->typing();
sleep(3);
sleep 3 unless ($_);
}
sleep ( 3 + int ( rand (2)));
Telegram::Bot::Brain::sendMessage ($self, $send_args);
Teapot::Bot::Brain::sendMessage ($self, $send_args);
return;
}
@@ -242,7 +258,7 @@ sub __on_msg {
}
}
sendChatAction ($self, $chatid);
$msg->typing();
sleep 1;
logger sprintf ("Private chat bot reply to $vis_a_vi: %s", $reply);
$msg->reply ($reply);
@@ -324,7 +340,7 @@ sub __on_msg {
MYHELP
$send_args->{parse_mode} = 'Markdown';
$send_args->{chat_id} = $chatid;
Telegram::Bot::Brain::sendMessage ($self, $send_args);
Teapot::Bot::Brain::sendMessage ($self, $send_args);
return;
} elsif (substr ($text, 1) eq 'ping') {
$reply = 'Pong.';
@@ -385,7 +401,7 @@ MYHELP
$reply = randomCommonPhrase();
}
sendChatAction ($self, $chatid);
$msg->typing();
sleep (int (rand (2)));
logger sprintf ('In public chat %s (%s) bot reply to %s: %s', $chatname, $chatid, $vis_a_vi, $reply);
$msg->reply ($reply);

View File

@@ -1,5 +1,5 @@
package telegramlib;
# store here functions that are not implemented in Telegram::Bot
# store here functions that are not implemented in Teapot::Bot
use 5.018;
use strict;
@@ -8,67 +8,15 @@ use utf8;
use open qw(:std :utf8);
use botlib qw(trim);
use Telegram::Bot::Brain;
use Teapot::Bot::Brain;
# module shit
use vars qw/$VERSION/;
use Exporter qw(import);
our @EXPORT_OK = qw(getChat getChatMember sendChatAction visavi);
our @EXPORT_OK = qw(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;
}
# complete framework with our sendChatAction()
# sets bot status to "typing" for 5 seconds
# # TODO: more actions!
sub sendChatAction {
my $self = shift;
my $chatid = shift;
my $send_args = {};
$send_args->{chat_id} = $chatid;
$send_args->{action} = 'typing';
my $token = $self->token;
my $url = "https://api.telegram.org/bot${token}/sendChatAction";
my $api_response = $self->_post_request ($url, $send_args);
# return Telegram::Bot::Object::User->create_from_hash($api_response, $self);
return;
}
sub visavi {
my ($userid, $username, $fullname) = @_;
my $name = '';