WWW::T...:BotAPI(3pm)
π NAME π
WWW::Telegram::BotAPI β a Perl implementation of the Telegram Bot API, bestie. That's the whole vibe. It lives in section 3pm of the User Contributed Perl Documentation, iykyk. π
β¨ SYNOPSIS β¨
okay so first thing, you load it and you make an object with your token. that's it, that's the whole setup πΈ
use WWW::Telegram::BotAPI;
my $api = WWW::Telegram::BotAPI->new (
token => 'my_token'
);
# The API methods die when an error occurs.
say $api->getMe->{result}{username};
# ... but error handling is available as well.
my $result = eval { $api->getMe }
or die 'Got error message: ', $api->parse_error->{msg};
# Uploading files is easier than ever.
$api->sendPhoto ({
chat_id => 123456,
photo => {
file => '/home/me/cool_pic.png'
},
caption => 'Look at my cool photo!'
});
# Complex objects are as easy as writing a Perl object.
$api->sendMessage ({
chat_id => 123456,
# Object: ReplyKeyboardMarkup
reply_markup => {
resize_keyboard => \1, # \1 = true when JSONified, \0 = false
keyboard => [
# Keyboard: row 1
[
# Keyboard: button 1
'Hello world!',
# Keyboard: button 2
{
text => 'Give me your phone number!',
request_contact => \1
}
]
]
}
});
# Asynchronous request are supported with Mojo::UserAgent.
$api = WWW::Telegram::BotAPI->new (
token => 'my_token',
async => 1 # WARNING: may fail if Mojo::UserAgent is not available!
);
$api->sendMessage ({
chat_id => 123456,
text => 'Hello world!'
}, sub {
my ($ua, $tx) = @_;
die 'Something bad happened!' if $tx->error;
say $tx->res->json->{ok} ? 'YAY!' : ':('; # Not production ready!
});
Mojo::IOLoop->start;
so let's break the energy down for you π
- every single API method dies when something goes wrong. like, no chill. so wrap it in
evalif you want to catch it, and then$api->parse_error->{msg}hands you the message. slay π«Ά - uploading files? easier than ever, no cap. you literally just hand it
file => '/home/me/cool_pic.png'. - complex objects are as easy as writing a Perl object, fr fr. nested hashes and arrays all the way down, and
\1means true once it gets JSONified,\0means false. iconic β¨ - async requests are supported with Mojo::UserAgent β you pass a callback and it gets
($ua, $tx).
β οΈ real talk though: withasync => 1, the warning in the original is "may fail if Mojo::UserAgent is not available!" β so don't come crying to me if you skipped the install. and that# Not production ready!comment in the callback? that's not me being cute, that's literally in the docs. π
also note that the callback example calls Mojo::IOLoop->start; at the end, because nothing happens until the loop starts. periodt π
π¦ DESCRIPTION π¦
This module provides an easy to use interface for the Telegram Bot API <https://core.telegram.org/bots/api>. π
It also supports async requests out of the box using Mojo::UserAgent, which makes this module easy to integrate with an existing Mojolicious application. π
so yeah β you already have a Mojolicious app and you want a bot in it? it just... fits. no glue code, no drama, main character energy only. π
more of this page is coming, bestie β don't go anywhere π
β¨ METHODS β¨
Okay bestie, this is where the magic happens. WWW::Telegram::BotAPI comes with these methods, and they're all iconic. π
πΈ new πΈ
my $api = WWW::Telegram::BotAPI->new (%options);
Creates a new WWW::Telegram::BotAPI instance. Slay.
WARNING: you should only create one instance of this module and reuse it when needed. Callingneweach time you run an async request causes unexpected behavior withMojo::UserAgentand won't work correctly. See also issue #13 on GitHub<https://github.com/Robertof/perl-www-telegram-botapi/issues/13>. π
%options may contain the following:
token => 'my_token'β The token that will be used to authenticate the bot.
This is required! The method will croak if this option is not specified. No token, no vibes. π«
api_url => 'https://api.example.com/token/%s/method/%s'β A format string that will be used to create the final API URL. The first parameter specifies the token, the second one specifies the method.
Defaults to https://api.telegram.org/bot%s/%s. β¨
async => 1β Enables asynchronous requests.
This requires Mojo::UserAgent, and the method will croak if it isn't found.
Defaults to 0. π¦
force_lwp => 1β Forces the usage ofLWP::UserAgentinstead ofMojo::UserAgent, even if the latter is available.
By default, the module tries to load Mojo::UserAgent, and on failure it uses LWP::UserAgent. π
π AUTOLOAD π
$api->getMe;
$api->sendMessage ({
chat_id => 123456,
text => 'Hello world!'
});
# with async => 1 and the IOLoop already started
$api->setWebhook ({ url => 'https://example.com/webhook' }, sub {
my ($ua, $tx) = @_;
die if $tx->error;
say 'Webhook set!'
});
This module makes use of "Autoloading" in perlsub. This means that every current and future method of the Telegram Bot API can be used by calling its Perl equivalent, without requiring an update of the module. It's giving future-proof. π
If you'd like to avoid using AUTOLOAD, then you may simply call the api_request method specifying the method name as the first argument.
$api->api_request ('getMe');
This is, by the way, the exact thing the AUTOLOAD method of this module does. No cap. π§
π api_request π
# Remember: each of these samples can be aliased with
# $api->methodName ($params).
$api->api_request ('getMe');
$api->api_request ('sendMessage', {
chat_id => 123456,
text => 'Oh, hai'
});
# file upload
$api->api_request ('sendDocument', {
chat_id => 123456,
document => {
filename => 'dump.txt',
content => 'secret stuff'
}
});
# complex objects are supported natively since v0.04
$api->api_request ('sendMessage', {
chat_id => 123456,
reply_markup => {
keyboard => [ [ 'Button 1', 'Button 2' ] ]
}
});
# with async => 1 and the IOLoop already started
$api->api_request ('getMe', sub {
my ($ua, $tx) = @_;
die if $tx->error;
# ...
});
This method performs an API request. The first argument must be the method name (here's a list <https://core.telegram.org/bots/api#available-methods>).
Once the request is completed, the response is decoded using JSON::MaybeXS and then returned. If Mojo::UserAgent is used as the user-agent, then the response is decoded automatically using Mojo::JSON. β¨
If the request is not successful or the server tells us something isn't "ok", then this method dies with the first available error message (either the error description or the status line). You can make this method non-fatal using eval:
my $response = eval { $api->api_request ($method, $args) }
or warn "Request failed with error '$@', but I'm still alive!";
Further processing of error messages can be obtained using parse_error.
Request parameters can be specified using an hash reference. Additionally, complex objects can be specified like you do in JSON. See the previous examples or the example bot provided in "SEE ALSO".
File uploads can be specified using an hash reference containing the following mappings:
file => '/path/to/file.ext'β Path to the file you want to upload.
Required only if content is not specified.
filename => 'file_name.ext'β An optional filename that will be used instead of the real name of the file.
Particularly recommended when content is specified.
content => 'Being a file is cool :-)'β The content of the file to send. When using this,filemust not be specified.AnyCustom => 'Header'β Custom headers can be specified as hash mappings.
Upload of multiple files is not supported. See "tx" in Mojo::UserAgent::Transactor for more information about file uploads. π«
To resend files, you don't need to perform a file upload at all. Just pass the ID as a normal parameter.
$api->sendPhoto ({
chat_id => 123456,
photo => $photo_id
});
When asynchronous requests are enabled, a callback can be specified as an argument. The arguments passed to the callback are, in order, the user-agent (a Mojo::UserAgent object) and the response (a Mojo::Transaction::HTTP object). More information can be found in the documentation of Mojo::UserAgent and Mojo::Transaction::HTTP.
NOTE: ensure that the event loop Mojo::IOLoop is started when using asynchronous requests. This is not needed when using this module inside a Mojolicious app.
The order of the arguments, except of the first one, does not matter:
$api->api_request ('sendMessage', $parameters, $callback);
$api->api_request ('sendMessage', $callback, $parameters); # same thing!
π¦ parse_error π¦
unless (eval { $api->doSomething(...) }) {
my $error = $api->parse_error;
die "Unknown error: $error->{msg}" if $error->{type} eq 'unknown';
# Handle error gracefully using "type", "msg" and "code" (optional)
}
# Or, use it with a custom error message.
my $error = $api->parse_error ($message);
When sandboxing calls to WWW::Telegram::BotAPI methods using eval, it is useful to parse error messages using this method.
WARNING: up until version 0.09, this method incorrectly stopped at the first occurence of "at" in error messages, producing results such as "missing ch" instead of "missing chat". π
This method accepts an error message as its first argument, otherwise $@ is used.
An hash reference containing the following elements is returned:
type => unknown|agent|apiβ The source of the error.
api specifies an error originating from Telegram's BotAPI. When type is api, the key code is guaranteed to exist.
agent specifies an error originating from this module's user-agent. This may indicate a network issue, a non-200 HTTP response code or any error not related to the API.
unknown specifies an error with no known source.
msg => ...β The error message.code => ...β The error code. This key only exists whentypeisapi.
π agent π
my $user_agent = $api->agent;
Returns the instance of the user-agent used by the module. You can determine if the module is using LWP::UserAgent or Mojo::UserAgent by using isa:
my $is_lwp = $user_agent->isa ('LWP::UserAgent');
π USING A PROXY π
Since all the painful networking stuff is delegated to one of the two supported user agents (either LWP::UserAgent or Mojo::UserAgent), you can use their built-in support for proxies by accessing the user agent object. An example of how this may look like is the following:
my $user_agent = $api->agent;
if ($user_agent->isa ('LWP::UserAgent')) {
# Use LWP::Protocol::connect (for https)
$user_agent->proxy ('https', '...');
# Or if you prefer, load proxy settings from the environment.
# $user_agent->env_proxy;
} else {
# Mojo::UserAgent (builtin)
$user_agent->proxy->https ('...');
# Or if you prefer, load proxy settings from the environment.
# $user_agent->detect;
}
NOTE: Unfortunately,Mojo::UserAgentreturns an opaque "Proxy connection failed" when something goes wrong with theCONNECTrequest made to the proxy. To alleviate this, since version 0.12, this module prints the real reason of failure in debug mode. See "DEBUGGING". If you need to access the real error reason in your code, please see issue #29 on GitHub<https://github.com/Robertof/perl-www-telegram-botapi/issues/29>.
π DEBUGGING π
To perform some cool troubleshooting, you can set the environment variable TELEGRAM_BOTAPI_DEBUG to a true value:
TELEGRAM_BOTAPI_DEBUG=1 perl script.pl
This dumps the content of each request and response in a friendly, human-readable way. It also prints the version and the configuration of the module. As a security measure, the bot's token is automatically removed from the output of the dump. π
Since version 0.12, enabling this flag also gives more details when a proxy connection fails.
WARNING: using this option along with an old Mojolicious version (< 6.22) leads to a warning, and forcesLWP::UserAgentinstead ofMojo::UserAgent. This is becauseMojo::JSONused incompatible boolean values up to version 6.21, which led to an horrible death ofJSON::MaybeXSwhen serializing the data. π
β οΈ CAVEATS β οΈ
When asynchronous mode is enabled, no error handling is performed. You have to do it by yourself as shown in the "SYNOPSIS". You're the main character, bestie. Handle your own errors. π
π SEE ALSO π
LWP::UserAgent, Mojo::UserAgent, <https://core.telegram.org/bots/api>, <https://core.telegram.org/bots>, example implementation of a Telegram bot <https://git.io/vlOK0>, example implementation of an async Telegram bot <https://git.io/vDrwL>
π©βπ» AUTHOR π©βπ»
Roberto Frenna (robertof AT cpan DOT org)
π BUGS π
Please report any bugs or feature requests to <https://github.com/Robertof/perl-www-telegram-botapi>.
π THANKS π
Thanks to the authors of Mojolicious for inspiration about the license and the documentation.
π LICENSE π
Copyright (C) 2015, Roberto Frenna.
This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.
And that's the whole vibe, bestie! This was documented with perl v5.40.0 on 2024-09-13 β the WWW::T...:BotAPI(3pm) page, periodt. π
β¨
π¦ where this page comes from
- ubuntu resolute: libwww-telegram-botapi-perl 0.12-2 Β· Artistic-2.0
- ubuntu stonking: libwww-telegram-botapi-perl 0.12-2 Β· Artistic-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms