How to get Telegram dialog icons as remote URLs using WTelegramClient (C#)

How to get Telegram dialog icons as remote URLs using WTelegramClient (C#)

I'm using the WTelegramClient library in a .NET application to load all my Telegram dialogs and their recent messages. I want to get the avatar (profile picture) of each dialog as a remote Uri, not download files to disk. This is to display user/chat icons in a UI via HTTP without local storage.

Here’s the relevant part of my current code:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    var user = await _client.LoginUserIfNeeded();
    Console.WriteLine($"Logged in as {user.username ?? user.first_name}");

    var dialogs = await _client.Messages_GetAllDialogs();

    var scope = _services.CreateScope();
    var store = scope.ServiceProvider.GetRequiredService<IMessageStore>();

    foreach (var chatBase in dialogs.chats.Values.OfType<Chat>())
        await store.AddOrUpdateChatAsync(chatBase);

    foreach (var usr in dialogs.users.Values.OfType<User>())
        await store.AddOrUpdateUserAsync(usr);

    var dialogsFiltered = dialogs.dialogs.OfType<Dialog>().ToList();

    foreach (var dlg in dialogsFiltered)
    {
        InputPeer peer = null!;

        if (dialogs.chats.TryGetValue(dlg.peer.ID, out var chatPeer))
            peer = chatPeer;
        else if (dialogs.users.TryGetValue(dlg.peer.ID, out var usrObj))
            peer = new InputPeerUser(dlg.peer.ID, usrObj.access_hash);

        if (peer is null) continue;

        var history = await _client.Messages_GetHistory(peer, limit: 50);
        foreach (var msg in history.Messages.OfType<Message>())
            await store.SaveOrUpdateMessageAsync(msg);

        // Here's where I want to get the dialog icon URI
    }

    await Task.Delay(Timeout.Infinite, stoppingToken);
}

Question: Is there a way to get a remote URL or public URI for a user's or chat's avatar (like https://t.me/i/userpic/...) using WTelegramClient, instead of downloading and serving them myself?

If this is not possible directly, is there a workaround to show user/chat avatars in a web UI without saving them locally?

I tried using this method to download profile pictures, but it saves them as local files instead of giving me any usable Uri:

private async Task<string?> GetAvatarUriAsync(IPeerInfo peer)
{
    try
    {
        var peerName = peer switch
        {
            User u => $"{u.id}",
            ChatBase c => $"{c.ID}",
            _ => null
        };

        if (peerName == null) return null;

        var avatarDir = Path.Combine(Directory.GetCurrentDirectory(), "avatars");
        Directory.CreateDirectory(avatarDir);

        var fileName = $"{peerName}.jpg";
        var fullPath = Path.Combine(avatarDir, fileName);

        var stream = new FileStream(fullPath, FileMode.Create);
        var avatarStream = await _client.DownloadProfilePhotoAsync(peer, stream, true);
        stream.Close();
        stream.Dispose();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Avatar download failed: {ex.Message}");
    }
    return null;
}

Answer

It's not possible.
As Telegram is a secure & encrypted messenger, all media & data stored in Telegram is inaccessible from normal web access.

The only exception is a public preview for some public channels via URLs like https://t.me/s/ProxyMTProto

With WTelegramClient, you can download media to memory (via MemoryStream) if you don't want to save them to disk

Enjoyed this question?

Check out more content on our blog or follow us on social media.

Browse more questions