EV-Telegram-TDLib

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    EV::Telegram::TDLib binds TDLib's tdjson C interface to the EV event
    loop. A dedicated reader thread blocks in td_receive, copies each JSON
    result, and wakes the loop through ev_async; the loop decodes,
    correlates replies to pending requests by @extra, drives the
    authorization state machine, maintains user and chat caches, and calls
    your handlers.

    Asynchronous callbacks follow the family idiom: they receive "($result,
    $err)" where $err is undef on success and a decoded TDLib error object
    on failure. A TDLib error is never thrown; see "CONVENTIONS" for what
    does croak.

    Requires a perl with 64-bit integers: Telegram ids are int64 and message
    ids are shifted left by 20 bits, so they must never round-trip through
    an NV. The Makefile refuses to build otherwise.

    The bundled TDLib is 1.8.66, pinned by Alien::TDLib at commit
    022d60202e446ad1287b9fb68e687c8a0760788b.

CONSTRUCTOR
  new(%opt)
    Creates a client and registers it in a process-global registry. The
    client is held under a strong reference until close() completes; see
    "CAVEATS". Options:

    api_id, api_hash
        Telegram application credentials from https://my.telegram.org. Keep
        them in the environment, not in source; see "SECURITY".

    phone_number
        Phone number in international format for user authorization. Used
        when the state machine reaches authorizationStateWaitPhoneNumber,
        unless bot_token is present. Setting on_qr as well does not override
        it: a QR link is requested only when on_qr is set and no
        phone_number was given.

    bot_token
        Bot token from BotFather. When present it is sent automatically at
        authorizationStateWaitPhoneNumber and no further credential
        callbacks are needed.

    database_directory
        Session and database directory. Default "tdlib-db". See "SECURITY".

    files_directory
        Downloaded files directory. Defaults to database_directory.

    database_encryption_key
        Encryption key for the local database. Empty by default; set it.

    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().

    register
        Hashref "{ first_name => ..., last_name => ... }". When set,
        authorizationStateWaitRegistration is answered with registerUser;
        without it the state fails login.

    on_update, on_error, on_close, on_user, on_chat, on_message,
    on_connection_state
        Update handlers; see "UPDATES" and the mixin methods below.

    on_code, on_password, on_email, on_email_code, on_qr
        Authorization credential callbacks; see "AUTHORIZATION".

CONVENTIONS
    Three patterns run through the whole interface. Knowing them saves
    reading 300 method signatures.

  Cache readers against remote getters
    "chat($chat_id)" and "user($user_id)" are synchronous cache reads: they
    take no callback, do no I/O, and return undef for something the client
    has not seen. Everything else named after a noun -- "folder", "topic",
    "secret_chat", "supergroup", "basic_group", "message", "file" -- is an
    asynchronous getter that takes a callback and asks TDLib.

    The two cache readers predate the rest and are kept as they are because
    renaming a method already published on CPAN would break working code.
    When you want the server's answer for a chat rather than the cached one,
    use "fetch_chat($chat_id, $cb)".

  Booleans
    A method that turns something on or off takes the flag as its last
    positional argument and defaults to true, so "pin_topic($chat, $id)"
    pins and "pin_topic($chat, $id, 0)" unpins. That covers close_topic,
    pin_topic, pin_chat, mark_unread, hide_general_topic, folder_tags,
    pause_download, protect_content, the supergroup switches, and the
    process_join_request pair.

    Two older methods invert through an option instead ("block_user($id,
    unblock => 1)", "react(..., remove => 1)"), and a few pairs are separate
    methods where the two directions differ in more than a flag:
    "mute"/"unmute", "archive"/"unarchive", "enable_proxy"/"disable_proxy".

  Identifiers
    TL "int64" values cross the JSON interface as strings, because a number
    would lose precision above 2**53. This module does that for you, and
    hands them back as strings: session ids, callback and inline query ids,
    profile photo ids, custom emoji ids and Web App launch ids are all
    strings you should keep as strings. Chat, message and user ids are
    "int53" and stay numbers.

README  view on Meta::CPAN

  Secret mixin
    End-to-end encrypted chats. A secret chat is a separate object from the
    chat that displays it: creating one yields a chat whose type is
    chatTypeSecret, and the methods below take the secret chat id found in
    that type, not the chat id.

    Secret chats live only in the local database. They are not on the
    server, cannot be read from another device, and do not survive losing
    the database.

   new_secret_chat($user_id, $cb), open_secret_chat($secret_chat_id, $cb), secret_chat($secret_chat_id, $cb), close_secret_chat($secret_chat_id, $cb)
    Start a secret chat with a user, reopen a known one, read its state, and
    close it.

   search_secret_messages($query, %opt, $cb)
    Searches the local database, since secret messages exist nowhere else.
    Options: "chat_id" to scope to one chat, "filter" (a
    searchMessagesFilter name, with or without the prefix), "offset",
    "limit".

   set_database_encryption_key($key, $cb), session_accepts_secret_chats($session_id, $on, $cb)
    Change the key the local database is encrypted with, and choose whether
    a logged-in session may accept secret chats at all. Losing the key loses
    every secret chat with it, as nothing on the server can restore them.

MINI APPS
    A Mini App (Telegram also calls it a Web App) is a web page a bot
    offers, opened inside a Telegram client. TDLib does not render it. It
    resolves the app, returns a URL and a launch id, and relays the data the
    page sends back; hosting a webview and loading the URL is the
    application's job. Nothing here needs a browser if all you want is the
    data channel.

    The usual flow is:

        $td->web_app($bot_id, 'probe', sub {
            my ($found, $err) = @_;
            ...
        });
        $td->open_web_app($chat_id, $bot_id, $button_url, sub {
            my ($info, $err) = @_;
            # hand $info->{url} to a webview, keep $info->{launch_id}
        });
        $td->close_web_app($launch_id, sub { });

    Data flows back either through "send_web_app_data($bot_user_id,
    $button_text, $data, $cb)", which a client calls on the page's behalf
    and the bot receives through "on_web_app_data($cb)", or through
    "answer_web_app_query($query_id, \%result, $cb)" for the inline variant.

  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
    auto_auth on (the default), each state is answered automatically or
    routed to a credential callback:

    authorizationStateWaitTdlibParameters
        setTdlibParameters is sent automatically from the constructor
        options. No callback. An error reply (bad api credentials, an
        unwritable database_directory) fails login: the values come from the
        constructor, so there is no interactive channel to retry through.

    authorizationStateWaitPhoneNumber
        bot_token is sent when given; otherwise requestQrCodeAuthentication
        when on_qr is set and no phone_number was given; otherwise the
        phone_number is sent. No callback in any branch. An error reply (an
        invalid phone number or bot token) fails login, for the same reason
        as above.

    authorizationStateWaitCode
        "on_code" receives "($info, $submit)": $info is the decoded
        authenticationCodeInfo, $submit is a code ref that sends the code.
        The split exists so the code can come from anywhere (a prompt, a
        GUI, a queue) without blocking the loop. A missing callback fails
        login.

        A rejected submission does not fail login: TDLib stays in the state
        after an error reply (a mistyped code, an expired one), so the
        handler is called again as "($info, $submit, $err)" with the decoded
        error as the third argument, and may submit a corrected value. To
        give up instead, close the client.

    authorizationStateWaitPassword
        "on_password" receives "($info, $submit)"; $info carries the
        password_hint. A missing callback fails login. A rejected password
        re-asks with the error as a third argument, as above.

    authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode
        "on_email" and "on_email_code", same "($info, $submit)" shape and
        the same retry-on-error behaviour.

    authorizationStateWaitOtherDeviceConfirmation
        "on_qr" receives "($link)" only. The signature is deliberately
        asymmetric: QR confirmation has nothing to submit, the other device
        confirms the login, so there is no $submit callback.

    authorizationStateWaitRegistration
        Answered automatically from the register option; without it login
        fails. An error reply from registerUser fails login: like the other
        automatic steps, it has no interactive channel.

    authorizationStateWaitPremiumPurchase
        Cannot be satisfied programmatically; login fails with an error.



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