Карточка профиля одной картинкой
Вводите имя пользователя на GitHub, Twitch или в Telegram — получаете аккуратную PNG-карточку со статистикой: подписчики, репозитории, звёзды, «зелёные квадратики» вкладов, языки, стрим и последний пост канала. Оформление настраивается целиком: темы, градиенты, скругления, шрифты, форма аватара и список видимых блоков. Ничего устанавливать не надо, регистрации нет, картинка собирается прямо в браузере.
- 3 сети
- PNG до 2400 px
- Без регистрации
- MIT
- 3сети в одном интерфейсе
- 2400пикселей по ширине на 3×
- 0аккаунтов и установок
- 5 минкэш — повтор ничего не стоит
// попробуйте прямо здесь
Соберите карточку прямо на этой странице
Ровно те ручки, с которых начинают в самом генераторе. Выключайте блоки — карточка ужимается по высоте, как и настоящая. Данные здесь образцовые; в приложении на их месте будет живой профиль.
card.png · ширина 2400 px · 3 блока · высота — по содержимому
В генераторе к этому добавляются градиенты под своим углом, три шрифта, скругление самой карточки, переключатель каждого поля по отдельности и настоящая кнопка «Скачать PNG».
// источники
Три сети, три разных набора данных
Каждая отдаёт своё, и карточка подстраивается: лишние блоки просто не рисуются, а высота ужимается под включённые. Щёлкните по колонке, чтобы разглядеть одну сеть.
Таблица прокручивается вбок →
- Аватар, имя, ник ✓ ✓ ✓
- Описание профиля ✓ ~ через официальный Helix ✓
- Подписчики ✓ ✓ ✓
- Числовая статистика ✓ репозитории, звёзды, форки, гисты, год ✓ зрители и аптайм —
- График вкладов и стрики ✓ — —
- Языковая полоса ✓ — —
- Ачивки и метки ✓ Pro, GitHub Star, множители ~ Партнёр / Компаньон ~ канал, группа, бот
- Организации ✓ — —
- Блок репозиториев ✓ пины, топ по звёздам или свой список — —
- Эфир: LIVE, зрители, игра — ✓ —
- Баннер обложкой или фоном — ~ только offline-заставка —
- Последний пост — — ✓ текст, дата, просмотры, фото
- Привязанный канал — — ~ юзернейм вводится руками
t.me тоже не раскрывает — юзернейм канала вводится руками. Значок «~» в таблице стоит ровно там, где данные приходят с такой оговоркой.
// устройство
Работу делает ваш браузер
Главное решение здесь такое: всё, что отдаёт заголовок CORS, браузер забирает сам, минуя наш сервер. Это не экономия на хостинге — это то, почему сервису не нужен ни один ключ.
- Ваш браузер api.github.com профиль, репозитории, организации CORS: *
- Ваш браузер CDN картинок аватарки, ачивки, баннеры — сразу в data-URL CORS: *
- Наш сервер github.com · t.me календарь вкладов, ачивки и весь Telegram CORS нет
Два потока из трёх идут мимо нас. Лимит GitHub — 60 запросов в час — тратится с вашего адреса, а не с общего на всех посетителей.
- график вкладов
- ачивки и метки
- Telegram целиком
# одна карточка GitHub целиком GET api.github.com/users/torvalds → браузер, без токена GET api.github.com/users/torvalds/repos → браузер GET avatars.githubusercontent.com/… → браузер, CORS * GET /api/github/torvalds → наш сервер: только календарь и ачивки # сервер лежит? карточка всё равно соберётся — просто без квадратиков GET /healthz {"ok":true}
// публичный деплой
Ни одного ключа и почти ничего о вас
Сервис не хранит токенов — их попросту нечему утекать. А то немногое, что всё же уходит с нашего адреса, обложено защитой: скрейпинг чужих страниц — ровно то, за что банят по IP.
- Токен GitHub не нуженREST API дёргает ваш браузер, и лимит 60 в час — ваш личный, а не общий на всех посетителей
- Наружу не уходит ни одного ключаотдельный тест следит, чтобы с сервера никогда не ушёл заголовок Authorization
- Кэш на 5 минутповторная загрузка того же профиля не стоит ничего
- Кэш хранит промис, а не значениедесять одновременных запросов на холодный ключ дают ОДИН поход наверх, а не десять
- 30 запросов / 5 мин на адресчеловеку хватает с запасом, перебору по чужим никам — нет
- Таймаут 8 секунд наружузависший чужой сервер не держит наш сокет вечно
node:test — без единой новой зависимости — плюс сквозной прогон в браузере до настоящей выгрузки PNG. Отдельно закрыты разборщики чужой вёрстки: GitHub и Telegram меняют разметку молча, и карточка тогда теряет блок без всякой ошибки. Тест ловит это раньше пользователя.
// о проекте
Зачем вообще карточка картинкой
Картинка едет туда, куда не едет виджет
Статистику профиля показывают десятком способов: динамические бейджи в README, виджеты для сайта, встраиваемые ифреймы. Все они живут только там, где есть браузер и разрешена подгрузка со стороннего домена. Как только карточка нужна в презентации, в резюме в формате PDF, в шапке telegram-канала или просто в чате — виджет не подходит, а скриншот куска страницы выглядит именно скриншотом: чужие поля, обрезанные края, случайный масштаб.
PNG снимает этот вопрос целиком. Файл лежит у вас, ничего не запрашивает при показе, не протухает вместе с чужим сервисом и одинаково выглядит в любом просмотрщике. Обратная сторона честная: картинка не обновляется сама. Поэтому генератор и сделан так, чтобы пересобрать её заново стоило полминуты — ник уже введён, оформление помнится, остаётся нажать «скачать».
Почему PNG собирается в браузере, а не на сервере
Обычный путь для такого сервиса — рисовать картинку на сервере: headless-браузер или библиотека вроде sharp собирают PNG и отдают его ссылкой. Это удобно ровно до момента публичного запуска: рендер стоит памяти и процессорного времени, а карточка — вещь, которую легко попросить тысячу раз подряд, просто перебирая чужие ники в адресной строке.
Здесь холст рисуется у вас в браузере, и повторить его тысячу раз можно только за свой счёт. Сервер остаётся тонким: он ходит лишь туда, куда браузеру не пускает политика домена, — за календарём вкладов на github.com и за всем Telegram. Отсюда и вся конструкция: кэш на пять минут, лимит на адрес, таймаут наружу. Не потому что «так принято», а потому что это единственные три места, где чужой запрос вообще может нам чего-то стоить.
Что оказалось сложным
Главная засада была не в API, а в холсте. Библиотека, снимающая PNG с вёрстки, отказывается работать, если внутри есть картинка с чужого домена без разрешающего заголовка: холст считается «испорченным», и выгрузка молча падает. Классическое лечение — гонять все картинки через свой прокси, и первая версия так и делала, вместе с белым списком доменов и защитой от подсунутого SVG.
Прокси оказался не нужен: все CDN, из которых берутся аватарки, ачивки и баннеры, отдают Access-Control-Allow-Origin: *. Вместо проксирования картинки вплавляются в data-URL до отрисовки — к моменту снимка в разметке уже нет ни одной внешней ссылки, и холст чист при любом кэше и редиректе. Вместе с прокси из проекта уехал и токен GitHub: раз запросы делает браузер посетителя, лимит считается на его адрес, и хранить на сервере нечего.
Своя карточка — за полминуты
Ник, тема, кнопка «скачать». Картинка годится в шапку профиля, в презентацию, в резюме или просто в чат — хвастаться стриком.
Поддержать автораИнструмент бесплатный и без рекламы. Если пригодился — купите кофе.donationalerts.com/r/bormotoon