EV-Telegram-TDLib

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    use_test_dc
        Use the Telegram test data centers instead of production. Always set
        this in tests.

    use_file_database, use_chat_info_database, use_message_database,
    use_secret_chats
        TDLib feature switches, all defaulting to true.

    application_name
        The platform identifier sent with every Mini App request, which the
        app receives as "tgWebAppPlatform". Defaults to "tdesktop". See
        "MINI APPS" for why the value matters and what it may contain.

    system_language_code, device_model, system_version, application_version
        Client identification sent with setTdlibParameters. Defaults: "en",
        "EV::Telegram::TDLib", $^O, this distribution's version.

    auto_auth
        Drive the authorization state machine automatically (default true).
        With auto_auth false, only the login and close lifecycle
        continuations run; every credential step is left to you via send().

README  view on Meta::CPAN

  The platform identifier
    "application_name" is not a free-form label. It is sent to Telegram as
    the platform string and handed to the page as "tgWebAppPlatform".
    Telegram accepts 0-64 characters from "A-Za-z0-9_" and rejects anything
    else with "PLATFORM_INVALID", an error that names nothing near the real
    cause; a hyphen is the easy way to trip it. This module validates the
    value when the client is constructed, so the failure arrives with an
    explanation instead.

    Any accepted value works, but the value still matters. Real clients send
    a conventional identifier ("android", "ios", "macos", "tdesktop",
    "weba", "webk") and Mini App pages branch on it to pick layout, theming
    and available features. An invented name passes validation and then
    lands in whatever an app does with an unrecognised platform. The default
    is "tdesktop".

  Launch URLs carry credentials
    The URL returned by open_web_app and the web_app_*_url methods has the
    signed init data in its fragment: the user's name, username, photo URL
    and an authentication hash. It is a credential. Do not log it, paste it
    into a bug report, or store it anywhere the page itself would not go.

AUTHORIZATION
    TDLib drives authorization as a state machine reported through
    updateAuthorizationState; "auth_state()" exposes the current state. With

lib/EV/Telegram/TDLib.pm  view on Meta::CPAN

        pending   => {},
        abandoned => {},
        cache     => {},
        opt       => \%opt,
        auto_auth => exists $opt{auto_auth} ? $opt{auto_auth} : 1,
        state     => 'created',
    }, $class;

    $self->{$_} = $opt{$_} for grep { /^on_/ } keys %opt;
    $self->{application_name} = EV::Telegram::TDLib::WebApps::_check_application_name(
        $opt{application_name} // 'tdesktop');
    $self->{client_id} = _create_client_id();
    $CLIENTS{ $self->{client_id} } = $self;
    _pump_ref();
    return $self;
}

sub on_update {
    my ($self, $cb) = @_;
    $self->{on_update} = $cb if $cb;
    return $self->{on_update};

lib/EV/Telegram/TDLib.pm  view on Meta::CPAN

Use the Telegram test data centers instead of production. Always set
this in tests.

=item use_file_database, use_chat_info_database, use_message_database, use_secret_chats

TDLib feature switches, all defaulting to true.

=item application_name

The platform identifier sent with every Mini App request, which the app
receives as C<tgWebAppPlatform>. Defaults to C<tdesktop>. See
L</MINI APPS> for why the value matters and what it may contain.

=item system_language_code, device_model, system_version, application_version

Client identification sent with setTdlibParameters. Defaults: C<en>,
C<EV::Telegram::TDLib>, C<$^O>, this distribution's version.

=item auto_auth

Drive the authorization state machine automatically (default true).

lib/EV/Telegram/TDLib.pm  view on Meta::CPAN

C<application_name> is not a free-form label. It is sent to Telegram as
the platform string and handed to the page as C<tgWebAppPlatform>.
Telegram accepts 0-64 characters from C<A-Za-z0-9_> and rejects
anything else with C<PLATFORM_INVALID>, an error that names nothing
near the real cause; a hyphen is the easy way to trip it. This module
validates the value when the client is constructed, so the failure
arrives with an explanation instead.

Any accepted value works, but the value still matters. Real clients
send a conventional identifier (C<android>, C<ios>, C<macos>,
C<tdesktop>, C<weba>, C<webk>) and Mini App pages branch on it to pick
layout, theming and available features. An invented name passes
validation and then lands in whatever an app does with an unrecognised
platform. The default is C<tdesktop>.

=head2 Launch URLs carry credentials

The URL returned by open_web_app and the web_app_*_url methods has the
signed init data in its fragment: the user's name, username, photo URL
and an authentication hash. It is a credential. Do not log it, paste it
into a bug report, or store it anywhere the page itself would not go.

=head1 AUTHORIZATION

t/23_webapps.t  view on Meta::CPAN

    my %opt = @_;
    return EV::Telegram::TDLib->new(
        api_id => 1, api_hash => 'x', database_directory => 't/tmp-webapps', %opt);
}

my $td = client();

# --- open parameters
my $p = EV::Telegram::TDLib::WebApps::_open_params($td, {});
is $p->{'@type'}, 'webAppOpenParameters', 'builds a webAppOpenParameters';
is $p->{application_name}, 'tdesktop', 'defaults to a conventional platform';
is $p->{mode}{'@type'}, 'webAppOpenModeFullSize', 'defaults to full size';
ok !exists $p->{theme}, 'theme is omitted when not asked for';

is(EV::Telegram::TDLib::WebApps::_open_params($td, { mode => 'compact' })
    ->{mode}{'@type'}, 'webAppOpenModeCompact', 'compact mode');
is(EV::Telegram::TDLib::WebApps::_open_params($td, { mode => 'full_screen' })
    ->{mode}{'@type'}, 'webAppOpenModeFullScreen', 'full screen mode');

my $err = do { local $@;
    eval { EV::Telegram::TDLib::WebApps::_open_params($td, { mode => 'huge' }) }; $@ };

t/23_webapps.t  view on Meta::CPAN

like $err, qr/application_name/, 'a non-ASCII letter is refused';

$err = do { local $@;
    eval { EV::Telegram::TDLib::WebApps::_open_params($td, { application_name => 'bad name' }) };
    $@ };
like $err, qr/application_name/, 'a per-call override is validated too';

is(EV::Telegram::TDLib::WebApps::_open_params($td, { application_name => 'weba' })
    ->{application_name}, 'weba', 'a valid override is used');
is(EV::Telegram::TDLib::WebApps::_open_params($td, { application_name => undef })
    ->{application_name}, 'tdesktop', 'an explicit undef falls back to the default');

# --- discovery
$td->web_app(42, 'probe', sub {});
my $r = last_req();
is $r->{'@type'}, 'searchWebApp', 'web_app sends searchWebApp';
is $r->{web_app_short_name}, 'probe', 'short name passed through';
like last_json(), qr/"bot_user_id":42[,}]/, 'bot id crosses as a JSON number';

$td->web_app_link(-100, 42, 'probe', start_parameter => 'ref1', sub {});
$r = last_req();
is $r->{'@type'}, 'getWebAppLinkUrl', 'web_app_link sends getWebAppLinkUrl';
is $r->{chat_id}, -100, 'chat id passed through';
is $r->{start_parameter}, 'ref1', 'start parameter passed through';
is $r->{parameters}{application_name}, 'tdesktop', 'open params are built in';
like last_json(), qr/"allow_write_access":false/, 'write access is a JSON boolean';

$td->main_web_app(-100, 42, mode => 'compact', sub {});
$r = last_req();
is $r->{'@type'}, 'getMainWebApp', 'main_web_app sends getMainWebApp';
is $r->{parameters}{mode}{'@type'}, 'webAppOpenModeCompact', 'mode reaches the request';

$td->web_app_url(42, url => 'https://example.com/', sub {});
$r = last_req();
is $r->{'@type'}, 'getWebAppUrl', 'web_app_url sends getWebAppUrl';

t/23_webapps.t  view on Meta::CPAN

is last_req()->{'@type'}, 'getWebAppPlaceholder', 'web_app_placeholder sends its method';

$err = do { local $@; eval { $td->web_app(undef, 'probe', sub {}) }; $@ };
like $err, qr/required/, 'a missing bot id is refused';

# --- launch and data
$td->open_web_app(-100, 42, 'https://example.com/', sub {});
$r = last_req();
is $r->{'@type'}, 'openWebApp', 'open_web_app sends openWebApp';
is $r->{url}, 'https://example.com/', 'button url passed through';
is $r->{parameters}{application_name}, 'tdesktop', 'open params are built in';

# int64: above 2^53 a JSON number would lose precision, and only the raw
# JSON can prove it went as a string
$td->close_web_app('7239857203948572039', sub {});
is last_req()->{'@type'}, 'closeWebApp', 'close_web_app sends closeWebApp';
like last_json(), qr/"web_app_launch_id":"7239857203948572039"/,
    'launch id crosses as a JSON string';

$td->send_web_app_data(42, 'Open probe', '{"n":1}', sub {});
$r = last_req();



( run in 1.053 second using v1.01-cache-2.11-cpan-b16cb0d3907 )