Search code examples
c#telegram-apiwtelegramclientmtproto

telegram bot URL authorization


There are tg bots, which has opportunities to open websites in a webview(iframe), inside of a telegram app. Whenewer you press on a button inside bot, it opens a webview with specific url. This allows to understand for opened website, that this url was opened buy SOME_USER and his auth data is correct (at least I think so).

Example of an url:

https://SOME_WEBSITE/#/login?
user=USER_GUID
&tgWebAppVersion=7.2
&linkBot=https://t.me/SOME_BOT_bot
&tgWebAppData=query_id=QUERY_ID
&user={
   "id":1,
   "first_name":"FirstName",
   "last_name":"LastName",
   "username":"UserName",
   "language_code":"en",
   "allows_write_to_pm":true
}
&auth_date=1713881657
&hash=SOME_HASH
&tgWebAppVersion=7.2
&tgWebAppPlatform=weba
&tgWebAppThemeParams={"bg_color":"#ffffff", ......... , "destructive_text_color":"#e53935"}

This url is not generated by bot. The bot contains only https://SOME_WEBSITE/#/login this part inside of a button. But when you press on a button, the telegram itself add all this specific auth data to url params. And opens this url in a webview(I've have intercept this url after pressing the button).

Question: "How can I generate such params for URL, by my own ?"

What I've tried alredy:

  1. reading docs and found perhaps something I need "https://corefork.telegram.org/api/url-authorization"
  2. try to use this methods(Messages_RequestUrlAuth, Messages_AcceptUrlAuth) from "wtelegramclient" library. Whitout success, maybe doing something wrong(receiving null's)
var resolvedUser = await _client.Contacts_ResolveUsername("someBotUserName");
var msgBase = await _client.Messages_GetHistory(new InputPeerUser(resolvedUser.User.ID, resolvedUser.User.access_hash), limit: 1);

var test1 = await _client.Messages_RequestUrlAuth(url: "https://some_url");
var test2 = await _client.Messages_AcceptUrlAuth(new InputPeerUser(resolvedUser.User.ID, resolvedUser.User.access_hash), msg_id: msgBase.Messages[0].ID, url: "https://some_url");

Solution

  • Finally! After long time searching telegram api docs + gramJS lib, the solution was found!

    We need to use Messages_RequestWebView method from WTelegramClinet, same method also exists in gramJS.

    //some basic theme params, perhaps it may be different per user, but it doesn't matter
    
    var tgThemeParams = new
    {
        bg_color = "#ffffff",
        text_color = "#000000",
        hint_color = "#707579",
        link_color = "#3390ec",
        //......
    };
    
    var themeParams = JsonConvert.SerializeObject(tgThemeParams);
    
    //resolvedUser is the chat(bot) where you need to sign in
    
    var resolvedUser = await _client.Contacts_ResolveUsername(setting.ChatName!);
    var userPeer = new InputPeerUser(resolvedUser.User.ID, resolvedUser.User.access_hash);
    
    var webViewRes = await client.Messages_RequestWebView(
        peer: userPeer,
        bot: userPeer,
        platform: "android",
        reply_to: null,
        url: "url from button / or url you need to sign in",
        theme_params: new DataJSON { data = themeParams },
        start_param: null,
        send_as: null,
        from_bot_menu: true,
        silent: false
    );
    

    The result will be url with all auth data needed!