NAME
Bot::ChatBots::Telegram::LongPoll - Telegram updates receiver, long-poll
SYNOPSIS
use Bot::ChatBots::Telegram::LongPoll;
my $lp = Bot::ChatBots::Telegram::LongPoll->new(
token => $ENV{TOKEN},
processor => \&processor,
start => 1,
);
sub processor { # tube-compliant
my $record = shift;
# ... your business logic goes here...
my $message = 'Howdy!';
if (automatic_via_sender()) { # same as WebHook
$record->{send_response} = $message;
}
elsif (do_it_yourself_via_sender()) { # same as WebHook
my $sender = $record->{source}{refs}{sender};
$sender->send_response($message, record => $record);
}
# else nothing is sent back, just a HTTP 204 by default
return $record; # follow on..
}
DESCRIPTION
This is an updates receiver and dispatcher for the Telegram infrastructure. It connects to Telegram's API for long-poll style (i.e. pulling updates continuously), so it's somehow inefficient but should let you get started in all conditions in which you can at least browse the Internet (webhook require that your endpoint lives in a routable place).
At the base, you have to provide at least the "token" and the "processor". The former is needed to connect to Telegram and get updates, the latter is what will be invoked for each update that is received.
When you have an object, you have to "start" to get the ball rolling. You can also pass start
in the constructor, this will start the Mojo::IOLoop directly (so you can use it in case you don't have other stuff to do).
When invoked, the "processor" tube can return a record with the send_response
field set. In this case, this update receiver can act also on the other way around, and send the response towards Telegram using a Bot::ChatBots::Telegram::Sender.
. ..Bot Application.....
: :
__________________ : ____________ :
/ \ : / \ :
| |<----------1-| | :
| Telegram Server | : | LongPoll | :
| |-2---------->| | :
\__________________/ : \____________/ :
| ^ : | :
5 | : 3 "send_response"
| | : | :
| | : ___v______ :
| | : / \ :
| +---------------4-| | :
| : | Sender | :
+------------------->| | :
: \__________/ :
: :
:....................:
1, 2: Poll for new Update(s)
3 : internal call
4, 5: Telegram API Request/Response
ACCESSORS
This class consumes roles Bot::ChatBots::Telegram::Role::Source and Bot::ChatBots::Role::Source and all its accessors.
connect_timeout
my $to = $obj->connect_timeout;
$obj->connect_timeout(10);
Acccessor for the connection timeout for Bot::ChatBots::Telegram::Sender's user agent (this is Mojo::UserAgent).
interval
$secs = $obj->interval;
$obj->interval(0.2); # secs
Accessor for the interval of scheduling calls to getUpdates
. You can set this to a pretty low value (default is 0.1 seconds) because there is a flag that prevents calls from being sent if another one is ongoing.
max_redirects
my $n = $obj->max_redirects;
$obj->max_redirects(7); # default is 5
Accessors for maximum number of redirects acceptable for the underlying Mojo::UserAgent. Defaults to 5.
update_timeout
my $to = $obj->update_timeout;
$obj->update_timeout(30);
Accessor to set/get the update_timeout
set in the getUpdates
call to the Telegram API. Defaults to 300 seconds, i.e. you should get at least one update every 5 minutes.
METHODS
This class consumes roles Bot::ChatBots::Telegram::Role::Source and Bot::ChatBots::Role::Source and all its methods.
BUILD
Method called upon construction. It checks for the presence of a start
parameter set to true and in case calls "start".
class_custom_pairs
my @pairs = $obj->class_custom_pairs;
Returns custom pairs, used by role Bot::ChatBots::Role::Source. It adds a token
to the parameters put in the source
key inside the record passed to the process
method, when invoked.
parse_response
my @updates = $obj->parse_response($res, $threshold_id);
Parse the response to the polling request ($res
is a Mojo::Message::Result object) and filters all updates whose identifier (according to field update_id
) are greater than, or equal to, the $threshold_id
. It takes care to check the return values and the rest.
If you get unknown error
here, chances are there were issues in the interaction with the Telegram website. If this is the case, you can activate tracing on the logging channel (which depends on what you use as a backend for Log::Any, of course).
poller
my $subref = $obj->poller(%args);
$subref = $obj->poller(\%args);
Build a polling sub reference suitable for being installed as a repetitive task in "start". This poller sends one single request to the Telegram endpoint for the longpoll and processes one single response.
In particular, it extracts the list of updates from the response and calls "process_updates" in Bot::ChatBots::Role::Source on them.
The source
key in the record that is eventually generated contains:
refs
withsender
,tx
andua
an additional item in
source
that is a hash reference associated to the keyquery
. Inside this you can find a keyoffset
that you can use to increase the offset to be used in following calls. This is done automatically in "process".
process
my $retval = $self->process($record);
Wrapper around "process" in Bot::ChatBots::Role::Source to cope with the need to increase the offset
for each incoming update (see "poller" for additional details).
start
$obj->start(%args); # OR
$obj->start(\%args);
Start polling Telegram for new updates. "poller" is called to retrieve a sub reference that is then installed as a recurring job according to "interval".
This method is called automatically upon object construction if option start
is present and set to a true value.
SEE ALSO
Bot::ChatBots, Bot::ChatBots::Telegram::WebHooks.
AUTHOR
Flavio Poletti <polettix@cpan.org>
COPYRIGHT AND LICENSE
Copyright (C) 2016, 2018 by Flavio Poletti <polettix@cpan.org>
This module is free software. You can redistribute it and/or modify it under the terms of the Artistic License 2.0.
This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.