Программирование

Ссылка на профиль Telegram по ID: tg://user?id= в Telegraf

Почему tg://user?id= не работает для ссылок на профиль других пользователей в Telegram ботах на Telegraf. Ограничения API, альтернативы: t.me/username, text_mention, deep links и примеры кода.

Можно ли отправить в сообщении бота ссылку на профиль другого пользователя по его Telegram ID (tg://user?id=…)? Использую telegraf, отправляю так:

js
bot.command('profile', async ctx => {
 await ctx.reply(
 `<a href="tg://user?id=12345">Профиль</a>`,
 { parse_mode: 'HTML' }
 );
});

Это работает только если указан id текущего аккаунта — для других пользователей ссылка не открывается. Как правильно сформировать ссылку на профиль по id, чтобы она работала для других пользователей, или есть ли ограничения Telegram/клиентов, из-за которых это невозможно? Какие альтернативы существуют (username, t.me/username, deep link и т.п.)?

Короткий ответ: нет — отправить надёжную публичную ссылку на профиль другого пользователя только по его числовому Telegram ID (tg://user?id=…) нельзя: клиенты Telegram в большинстве случаев игнорируют такой deep‑link, а он применяется в ограничённых сценариях Bot API. В Telegraf вместо этого используйте публичный username (https://t.me/username / tg://resolve?domain=…), или — если username отсутствует — создавайте внутри чата кликабельное упоминание через Bot API (MessageEntity type text_mention) либо отправляйте контакт / просите пользователя поставить username.


Содержание


Ссылка на профиль по ID (tg://user?id=…)

Ваш пример кода:

js
bot.command('profile', async ctx => {
 await ctx.reply(
 `<a href="tg://user?id=12345">Профиль</a>`,
 { parse_mode: 'HTML' }
 );
});

Работает ли это? Частично — но не так, как вы, возможно, ожидаете. Официальная документация по deep links описывает разные схемы (t.me/…, tg://resolve?.. и т.п.), и отмечает, что поведение схем вроде tg://user?id=… ограничено и не гарантируется клиентами на всех платформах — такие ссылки в ряде случаев игнорируются клиентом и не открывают профиль другого пользователя https://core.telegram.org/api/links. Обсуждения разработчиков показывают, что tg://user?id= чаще используется в контексте Bot API для внутренних упоминаний, но не служит универсальной публичной ссылкой на профиль https://stackoverflow.com/questions/40048452/telegram-bot-how-to-mention-user-by-its-id-not-its-username. Практические статьи и генераторы ссылок подчёркивают, что для браузера и большинства клиентов надёжнее использовать https://t.me/username или tg://resolve?domain=username https://umnico.com/blog/telegram-link-generator/.


Почему это не работает для других пользователей

Коротко — потому что такое поведение заложено в реализации клиентов и в API:

  • Клиенты (особенно web/desktop) часто игнорируют tg://user?id=… или не интерпретируют его как публичную ссылку. В мобильном приложении поведение тоже неоднородно.
  • tg://user?id= не создаёт «публичную» человечески-читаемую ссылку вида t.me/username — это внутренний deep‑link, и он не предназначен для массового внешнего распространения. См. документацию по deep links https://core.telegram.org/api/links.
  • Для безопасности и приватности Telegram не даёт простой универсальной привязки «по id → публичная страница», если у пользователя нет username. Numeric ID не заменяет публичное имя.
  • Отсюда наблюдаемое вами поведение: ссылка может работать для аккаунта, к которому привязана сессия (то есть вы «открываете себя»), но не для произвольного третьего пользователя.

Резюмируя: по ID создать кросс‑платформенную кликабельную ссылку на профиль — нельзя. Лучше ориентироваться на username или на упоминания внутри чата.


Альтернативы: t.me/username и deep links

Самая простая и надёжная альтернатива — ссылка по username:

  • Публичный профиль: https://t.me/username — работает во всех клиентах и в браузере.
  • Внутри приложения можно использовать tg://resolve?domain=username, но https://t.me/… более кросс‑платформенный.

Пример для Telegraf (если у пользователя есть username):

js
// самый надёжный вариант — https://t.me/username
bot.command('profile', async ctx => {
 const username = 'targetusername'; // достаёте заранее
 await ctx.replyWithHTML(`<a href="https://t.me/${username}">Открыть профиль</a>`);
});

Или через inline-кнопку (удобно в ботах):

js
const { Markup } = require('telegraf');

bot.command('profile', async ctx => {
 const username = 'targetusername';
 await ctx.reply('Профиль:', Markup.inlineKeyboard([
 Markup.button.url('Открыть в Telegram', `https://t.me/${username}`)
 ]));
});

Если username отсутствует — публичной ссылки нет. Есть редкие «временные/спец» ссылки (вроде некоторых contact‑link flows), но они используются в узких сценариях и не являются заменой t.me для общего доступа https://umnico.com/blog/telegram-link-generator/.


Упоминание по ID в Bot API / Telegraf (text_mention)

Что делать, если у пользователя нет username, но вам нужно сделать кликабельное упоминание внутри чата? Bot API поддерживает сущность MessageEntity типа text_mention, которая создаёт кликабельное упоминание и «связывает» текст с User‑объектом (в интерфейсе это выглядит как ссылка на профиль внутри Telegram). Ограничения:

  • Бот должен иметь User‑объект целевого пользователя (обычно это возможно, если пользователь писал боту или находится в том же чате).
  • Это не даёт внешней публичной URL — упоминание работает внутри сообщений Telegram.

Пример (через bot.telegram.sendMessage):

js
const name = 'Иван Иванов';
await bot.telegram.sendMessage(ctx.chat.id, name, {
 entities: [
 {
 type: 'text_mention',
 offset: 0,
 length: name.length,
 user: { id: 12345, is_bot: false, first_name: 'Иван' }
 }
 ]
});

Важно: если бот не может подтвердить User (пользователь никогда не взаимодействовал с ботом и не в чате), сервер может не принять такого «вручную подставленного» User‑объекта или упоминание не будет работать как ссылка. Обсуждение этого подхода есть в сообществе разработчиков https://stackoverflow.com/questions/40048452/telegram-bot-how-to-mention-user-by-its-id-not-its-username.


Практические советы и примеры кода для Telegraf

Что рекомендую делать в рабочем боте:

  1. Храните username, когда пользователь взаимодействует с ботом. Тогда вы сможете генерировать https://t.me/username для внешних ссылок.
  2. Для пользователей без username используйте внутри чата text_mention, но учитывайте, что это работает только при наличии User‑объекта.
  3. Если нужно поделиться контактной информацией — отправляйте sendContact (ctx.replyWithContact) с номером телефона (если он у вас есть и пользователь разрешил). Это не профиль, но рабочая альтернатива.
  4. Не пытайтесь «форсить» tg://user?id для внешних ссылок — это ненадёжно и будет ломаться на большинстве клиентов.

Конкретный пример: комбинированный обработчик

js
bot.command('profile', async ctx => {
 const userId = 12345; // ваш id цели
 const username = await lookupUsernameById(userId); // ваша логика БД / кэш

 if (username) {
 // Надёжный вариант — публичный t.me
 return ctx.replyWithHTML(`<a href="https://t.me/${username}">Открыть профиль</a>`);
 }

 // Попробуем создать text_mention (если у бота есть информация о user)
 const displayName = 'Пользователь';
 try {
 await bot.telegram.sendMessage(ctx.chat.id, displayName, {
 entities: [{
 type: 'text_mention',
 offset: 0,
 length: displayName.length,
 user: { id: userId, is_bot: false, first_name: displayName }
 }]
 });
 } catch (e) {
 // fallback: простое уведомление
 await ctx.reply('Профиль недоступен: у пользователя нет username, а упоминание невозможно.');
 }
});

Небольшая ремарка: вместо ручной подстановки user можно пытаться вызвать Bot API методы (например, getChat(user_id)), но такие вызовы работают только если бот имеет доступ к информации о пользователе (пользователь взаимодействовал с ботом или находится в том же чате). Проверяйте ответы API и обрабатывайте ошибки.


Источники


Заключение

tg://user?id=… не даёт универсальной публичной ссылки на профиль другого пользователя — клиенты Telegram и Bot API применяют такие схемы в ограничённом контексте, и поведение нестабильно. Для внешних ссылок используйте https://t.me/username (или tg://resolve?domain=... внутри приложения). Если у пользователя нет username, от вас остаются два реалистичных пути: упоминание внутри чата через text_mention (требует наличия User‑объекта) или отправка контакта/запрос на установку username. В Telegraf проще и надёжнее опираться на username и хранить его, когда пользователь взаимодействует с ботом.

Авторы
Проверено модерацией
Модерация
Ссылка на профиль Telegram по ID: tg://user?id= в Telegraf