mirror of
https://github.com/Trollobot/Telemax.git
synced 2026-10-21 05:29:59 +00:00
723 lines
57 KiB
HTML
723 lines
57 KiB
HTML
<!doctype html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Telemax — мост MAX ↔ Telegram: переписка из MAX прямо в Telegram</title>
|
||
<meta name="description" content="Telemax — бесплатный мост между MAX и Telegram с открытым кодом. Входит в ваш личный аккаунт MAX по номеру и приносит все чаты в Telegram: каждый чат — отдельная тема. Сообщения, файлы до 4 ГБ, реакции, кнопки ботов. Ставится на свой сервер одной командой.">
|
||
<meta name="keywords" content="MAX в Telegram, мост MAX Telegram, Макс в Телеграм, пересылка сообщений из MAX в Telegram, читать MAX в Telegram, MAX Telegram bridge, Telemax">
|
||
<link rel="canonical" href="https://telemax.svnest.ru/">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:locale" content="ru_RU">
|
||
<meta property="og:site_name" content="Telemax">
|
||
<meta property="og:title" content="Telemax — переписка из MAX прямо в Telegram">
|
||
<meta property="og:description" content="Бесплатный мост MAX ↔ Telegram с открытым кодом: все чаты MAX — темами в вашей группе Telegram. Свой сервер, одна команда для установки.">
|
||
<meta property="og:url" content="https://telemax.svnest.ru/">
|
||
<meta property="og:image" content="https://telemax.svnest.ru/og.png">
|
||
<meta property="og:image:width" content="780">
|
||
<meta property="og:image:height" content="440">
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<link rel="icon" type="image/png" href="icon.png">
|
||
<link rel="apple-touch-icon" href="icon.png">
|
||
<link rel="alternate" type="application/rss+xml" title="Новости Telemax" href="https://telemax.svnest.ru/news/feed.xml">
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "SoftwareApplication",
|
||
"name": "Telemax",
|
||
"description": "Бесплатный мост между мессенджерами MAX и Telegram с открытым кодом. Подключается к личному аккаунту MAX по номеру и приносит все чаты в группу Telegram, каждый чат — отдельной темой.",
|
||
"applicationCategory": "CommunicationApplication",
|
||
"operatingSystem": "Linux (Ubuntu 22.04+, Debian 12+)",
|
||
"url": "https://telemax.svnest.ru/",
|
||
"downloadUrl": "https://github.com/Trollobot/Telemax",
|
||
"license": "https://www.gnu.org/licenses/agpl-3.0.html",
|
||
"image": "https://telemax.svnest.ru/og.png",
|
||
"softwareVersion": "1.3.6",
|
||
"dateModified": "2026-10-13",
|
||
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "RUB" }
|
||
}
|
||
</script>
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "FAQPage",
|
||
"mainEntity": [
|
||
{ "@type": "Question", "name": "Как читать и отвечать на сообщения MAX в Telegram?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Поставьте Telemax на свой сервер и войдите в свой аккаунт MAX через бота. Все чаты MAX появятся в вашей группе Telegram отдельными темами: отвечаете в теме — ответ уходит в MAX от вашего имени." } },
|
||
{ "@type": "Question", "name": "Нужно ли приложение MAX?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Один раз — да: аккаунт MAX регистрируется в приложении, там же ставится пароль. Дальше переписка идёт через Telegram, и приложение можно не открывать." } },
|
||
{ "@type": "Question", "name": "Это бот в MAX или мой аккаунт?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Ваш личный аккаунт: Telemax входит по номеру телефона, поэтому приходят все ваши чаты, а не только те, куда добавлен бот. Со стороны Telegram работает ваш собственный бот." } },
|
||
{ "@type": "Question", "name": "Можно ли начать новый чат из Telegram?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Да: в пульте «Найти контакт» — по номеру в любом виде, по MAX ID или нику бота. Или отправьте в общую тему группы контакт из телефонной книги. Не найдётся только тот, кто закрыл поиск по номеру в настройках приватности MAX, — тогда пусть напишет первым." } },
|
||
{ "@type": "Question", "name": "Можно ли показать чат MAX тем, у кого нет MAX?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Да, трансляцией: команда /broadcast в теме чата — и новые сообщения этого чата копируются в обычную группу или канал Telegram. Мест сколько угодно, бота туда Telegram добавит сам. Трансляция идёт в одну сторону: что пишут там, в MAX не уходит." } },
|
||
{ "@type": "Question", "name": "Передаются ли файлы, голосовые и кружки?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Да, в обе стороны. Файлы больше 50 МБ из MAX приходят ссылкой на ваш сервер, а в MAX можно отправить файл до 4 ГБ через страницу загрузки. Для таких ссылок нужен белый IP сервера и открытые порты 80 и 443 — установщик проверит это сам и, если чего-то не хватает, объяснит." } },
|
||
{ "@type": "Question", "name": "Сколько это стоит?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Telemax бесплатный, весь функционал открыт. Платите только за свой сервер — хватит самого простого VPS." } },
|
||
{ "@type": "Question", "name": "Заработает ли на российском VPS?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Да. Если Telegram с сервера не открывается, мост может работать через прокси. Сам прокси нужен свой (SOCKS5 или HTTP) — его адрес указывают при установке, MAX при этом идёт напрямую." } },
|
||
{ "@type": "Question", "name": "Можно ли подключить два аккаунта MAX?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Да: второй мост ставится той же командой в соседний каталог, со своим ботом и своей группой. Автообновление обслуживает все мосты на сервере." } },
|
||
{ "@type": "Question", "name": "Что будет, если GitHub недоступен?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Установка и обновления сами переключатся на зеркало проекта. Каждый релиз подписан, и мост проверяет подпись перед установкой — неважно, откуда пришёл код." } },
|
||
{ "@type": "Question", "name": "Это безопасно?",
|
||
"acceptedAnswer": { "@type": "Answer", "text": "Соединения шифруются: MAX ↔ сервер по TLS, сервер ↔ Telegram по HTTPS. Код и данные — на вашем сервере, посредников нет, код открыт. Но шифрование не сквозное: сервер видит переписку, иначе не смог бы её пересылать, — поэтому его стоит защищать. Проект неофициальный — используйте на свой страх и риск." } }
|
||
]
|
||
}
|
||
</script>
|
||
<style>
|
||
:root{
|
||
--paper:#f5ecd9; --paper-2:#faf4e6; --card:#fffdf8;
|
||
--ink:#2b2119; --muted:#6f6152; --faint:#948676;
|
||
--line:#e4d4b6; --line-soft:#eaddc4;
|
||
--terra:#c2571f; --terra-dark:#9d4315; --terra-tint:#f0dcbb;
|
||
--olive:#7a7433; --ok:#4d7c2f;
|
||
--serif:Georgia,"Times New Roman","PT Serif",serif;
|
||
--radius:14px; --shadow:0 1px 2px rgba(70,45,20,.05),0 14px 34px rgba(90,55,20,.09);
|
||
}
|
||
*{box-sizing:border-box}
|
||
body{margin:0;background:var(--paper);color:var(--ink);
|
||
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
|
||
line-height:1.62;-webkit-font-smoothing:antialiased}
|
||
a{color:var(--terra-dark);text-decoration:none}
|
||
a:hover{text-decoration:underline}
|
||
.wrap{max-width:1000px;margin:0 auto;padding:0 22px}
|
||
h1,h2,h3{font-family:var(--serif);line-height:1.16;margin:0 0 .4em;font-weight:700}
|
||
h2{font-size:clamp(1.6rem,3.6vw,2.3rem)}
|
||
.sub{color:var(--muted)}
|
||
.btn{display:inline-block;padding:13px 22px;border-radius:12px;font-weight:700;border:1.5px solid transparent;transition:transform .05s}
|
||
.btn:active{transform:translateY(1px)}
|
||
.btn-primary{background:var(--terra);color:#fff8ef}
|
||
.btn-primary:hover{background:var(--terra-dark);text-decoration:none}
|
||
.btn-ghost{background:transparent;border-color:var(--line);color:var(--ink)}
|
||
.btn-ghost:hover{border-color:var(--terra);text-decoration:none}
|
||
header.nav{position:sticky;top:0;z-index:10;background:rgba(245,236,217,.86);
|
||
backdrop-filter:blur(8px);border-bottom:1px solid var(--line)}
|
||
.nav .wrap{display:flex;align-items:center;gap:16px;height:62px}
|
||
.brand{font-family:var(--serif);font-weight:700;font-size:1.35rem;letter-spacing:-.01em}
|
||
.brand .dot{color:var(--terra)}
|
||
.nav .spacer{flex:1}
|
||
.nav a.navlink{color:var(--muted);font-weight:600;font-size:.94rem;font-family:inherit}
|
||
.nav a.support{color:var(--terra-dark)}
|
||
@media(max-width:680px){.nav a.navlink{display:none}.nav a.support{display:inline}}
|
||
.eye{font-size:.82rem;font-weight:700;color:var(--terra-dark);letter-spacing:.02em;margin-bottom:14px}
|
||
.chip{display:inline-flex;align-items:center;gap:7px;background:var(--terra-tint);color:var(--terra-dark);
|
||
border:1px solid var(--line);padding:6px 13px;border-radius:999px;font-size:.82rem;font-weight:700;margin-bottom:20px}
|
||
/* hero */
|
||
.hero{padding:66px 22px 44px;text-align:center}
|
||
.hero h1{font-size:clamp(2.1rem,5.8vw,3.5rem);letter-spacing:-.01em;margin-bottom:.35em}
|
||
.hero h1 .hl{color:var(--terra)}
|
||
.hero p.lead{font-size:clamp(1.05rem,2.3vw,1.32rem);color:var(--muted);max-width:720px;margin:0 auto 28px}
|
||
.cta{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-bottom:38px}
|
||
.newsbar{display:inline-flex;align-items:center;gap:10px;max-width:100%;margin:-10px auto 34px;padding:6px 8px 6px 6px;
|
||
background:var(--card);border:1px solid var(--line);border-radius:999px;box-shadow:var(--shadow);color:var(--ink);font-size:.92rem}
|
||
.newsbar:hover{text-decoration:none;border-color:var(--terra)}
|
||
.newsbar .nb-tag{background:var(--terra);color:#fff8ef;font-weight:800;font-size:.76rem;border-radius:999px;padding:3px 10px;white-space:nowrap}
|
||
.newsbar .nb-text{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.newsbar .nb-go{color:var(--terra);font-weight:800;padding-right:6px}
|
||
section{padding:58px 0;border-top:1px solid var(--line-soft)}
|
||
section.alt{background:var(--paper-2)}
|
||
.kicker{color:var(--terra);font-weight:700;text-transform:uppercase;letter-spacing:.09em;font-size:.76rem;margin-bottom:10px;font-family:inherit}
|
||
/* differentiator */
|
||
.callout{background:var(--card);border:1px solid var(--line);border-left:5px solid var(--terra);
|
||
border-radius:0 var(--radius) var(--radius) 0;padding:28px 32px;box-shadow:var(--shadow)}
|
||
.callout .vs{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:22px}
|
||
@media(max-width:560px){.callout .vs{grid-template-columns:1fr}.callout{padding:22px 20px}}
|
||
.vs .c{background:var(--paper-2);border:1px solid var(--line);border-radius:12px;padding:16px 18px;font-size:.95rem;color:var(--muted)}
|
||
.vs .c.good{background:#f2f6e9;border-color:#d3e0bd}
|
||
.vs .tag{font-weight:700;font-size:.85rem;margin-bottom:6px;font-family:var(--serif)}
|
||
.vs .good .tag{color:var(--ok)} .vs .bad .tag{color:var(--faint)}
|
||
/* features */
|
||
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
|
||
@media(max-width:820px){.grid{grid-template-columns:repeat(2,1fr)}}
|
||
@media(max-width:520px){.grid{grid-template-columns:1fr}}
|
||
.feat{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:22px;box-shadow:var(--shadow)}
|
||
.feat .ic{font-size:1.6rem;margin-bottom:10px}
|
||
.feat h3{font-size:1.08rem;margin-bottom:.3em}
|
||
.feat p{color:var(--muted);font-size:.94rem;margin:0}
|
||
/* steps */
|
||
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;counter-reset:s}
|
||
@media(max-width:720px){.steps{grid-template-columns:1fr;gap:28px}}
|
||
.step{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:24px 22px 22px;position:relative}
|
||
.step::before{counter-increment:s;content:counter(s);position:absolute;top:-15px;left:22px;
|
||
width:34px;height:34px;border-radius:50%;background:var(--terra);color:#fff8ef;font-weight:800;font-family:var(--serif);
|
||
display:flex;align-items:center;justify-content:center}
|
||
.step h3{margin-top:8px;font-size:1.08rem}
|
||
.step p{color:var(--muted);margin:0;font-size:.94rem}
|
||
code{background:var(--terra-tint);color:var(--terra-dark);padding:2px 7px;border-radius:6px;
|
||
font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em}
|
||
.cmd{margin:26px 0 0}
|
||
.cmd .label{font-size:.88rem;color:var(--muted);margin:14px 0 6px}
|
||
.cmd pre{margin:0;background:#2b2119;color:#f6e6d2;border-radius:12px;padding:14px 16px;overflow-x:auto;
|
||
font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.9rem;line-height:1.5}
|
||
/* screenshots */
|
||
.shots{display:grid;grid-template-columns:repeat(2,1fr);gap:22px;align-items:start}
|
||
@media(max-width:700px){.shots{grid-template-columns:1fr}}
|
||
.shot{margin:0}
|
||
.shot.wide{grid-column:1/-1;justify-self:center;width:100%;max-width:640px}
|
||
.shot img{width:100%;height:auto;display:block;border-radius:14px;border:1px solid var(--line);box-shadow:var(--shadow);background:#0e1621}
|
||
.shot figcaption{text-align:center;font-size:.88rem;color:var(--muted);margin-top:10px}
|
||
/* limits */
|
||
.limits{margin:22px 0 0;padding:0;list-style:none;display:grid;gap:10px}
|
||
.limits li{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:12px 16px;color:var(--muted)}
|
||
/* support */
|
||
.support-box{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
|
||
padding:34px;text-align:center;box-shadow:var(--shadow)}
|
||
.support-box .heart{font-size:2rem;margin-bottom:8px}
|
||
.support-box p{color:var(--muted);max-width:560px;margin:0 auto 22px}
|
||
.crypto{margin-top:18px;font-size:.85rem;color:var(--faint)}
|
||
.crypto code{word-break:break-all}
|
||
/* faq */
|
||
details{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:2px 18px;margin-bottom:12px}
|
||
details summary{cursor:pointer;font-weight:700;padding:15px 0;list-style:none;font-family:var(--serif)}
|
||
details summary::-webkit-details-marker{display:none}
|
||
details summary::before{content:"+";color:var(--terra);font-weight:800;margin-right:10px}
|
||
details[open] summary::before{content:"-"}
|
||
details p{color:var(--muted);margin:0 0 15px;padding-left:24px}
|
||
footer{padding:44px 0 64px;color:var(--muted);border-top:1px solid var(--line)}
|
||
footer .links{display:flex;gap:12px 20px;flex-wrap:wrap;margin-bottom:18px}
|
||
.disc{font-size:.85rem;background:var(--paper-2);border:1px solid var(--line);border-radius:12px;padding:15px 18px}
|
||
.center{text-align:center}
|
||
/* hero animation: MAX ↔ your server ↔ Telegram (scenes: переписка, файлы, трансляция, всё ваше) */
|
||
.flow{margin:0 auto;max-width:760px;background:var(--card);border:1px solid var(--line);
|
||
border-radius:var(--radius);box-shadow:var(--shadow);padding:18px 18px 16px;text-align:center}
|
||
.flow-stage{position:relative;height:clamp(250px,42vw,320px);overflow:hidden;border-radius:10px;
|
||
background:
|
||
radial-gradient(circle at 50% 38%,rgba(194,87,31,.07),transparent 46%),
|
||
linear-gradient(var(--paper-2),var(--card))}
|
||
.flow-lines{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
|
||
.flow-lines line{stroke-linecap:round;vector-effect:non-scaling-stroke}
|
||
.flow-lines .track{stroke:var(--terra);stroke-width:3;stroke-dasharray:2 9;animation:march 1.2s linear infinite}
|
||
.flow-lines .branch{stroke:var(--terra);stroke-width:2;stroke-dasharray:2 8;opacity:0;transition:opacity .5s;animation:march 1.2s linear infinite}
|
||
.flow[data-scene="cast"] .flow-lines .branch{opacity:.75}
|
||
@keyframes march{to{stroke-dashoffset:-11}}
|
||
|
||
.fnode{position:absolute;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;justify-content:center;
|
||
z-index:2;font-family:var(--serif);font-weight:800;line-height:1.1;user-select:none}
|
||
.fnode small{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-weight:500;font-size:.68rem;color:var(--muted);margin-top:3px}
|
||
.fnode.round{width:clamp(74px,14vw,104px);height:clamp(74px,14vw,104px);border-radius:50%;background:var(--paper-2);border:2px solid var(--ink)}
|
||
.fmax{left:13%;top:38%;color:var(--olive);border-color:var(--olive)!important;font-size:clamp(1rem,2.6vw,1.3rem)}
|
||
.ftg{left:87%;top:38%;font-size:clamp(.82rem,2.1vw,1.02rem)}
|
||
.fsrv{left:50%;top:38%;width:clamp(104px,20vw,142px);height:clamp(58px,10vw,74px);border-radius:16px;background:var(--terra);color:#fff8ef;
|
||
font-size:clamp(.95rem,2.4vw,1.15rem);box-shadow:0 8px 22px rgba(157,67,21,.28)}
|
||
.fsrv small{color:#f6e6d2}
|
||
.flow[data-scene="own"] .fsrv{animation:glow 1.8s ease-in-out infinite}
|
||
@keyframes glow{50%{box-shadow:0 0 0 10px rgba(194,87,31,.14),0 8px 22px rgba(157,67,21,.28)}}
|
||
.cnt{position:absolute;top:2px;right:2px;min-width:22px;height:22px;padding:0 6px;border-radius:999px;background:var(--terra);color:#fff8ef;
|
||
font:800 .74rem/22px -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;opacity:0;transform:scale(.4);transition:opacity .2s,transform .25s}
|
||
.cnt.on{opacity:1;transform:scale(1)}
|
||
|
||
.ftarget{width:auto;height:auto;padding:7px 12px;border-radius:12px;background:var(--card);border:1.5px solid var(--terra);font-size:1.1rem;
|
||
flex-direction:row;gap:6px;opacity:0;transition:opacity .45s,transform .45s;transform:translate(-50%,-30%)}
|
||
.ftarget small{margin:0;font-size:.74rem;color:var(--ink);font-weight:700}
|
||
.fgroup{left:62%;top:84%}
|
||
.fchan{left:86%;top:84%}
|
||
.flow[data-scene="cast"] .ftarget{opacity:1;transform:translate(-50%,-50%)}
|
||
|
||
.fbadge{position:absolute;transform:translate(-50%,-50%) translateY(8px);z-index:3;opacity:0;transition:opacity .4s,transform .4s;
|
||
background:var(--card);border:1px solid var(--line);border-radius:999px;padding:4px 11px;font-size:clamp(.66rem,1.7vw,.8rem);font-weight:700;
|
||
color:var(--ink);white-space:nowrap;box-shadow:0 4px 12px rgba(90,55,20,.1)}
|
||
.fbadge.store{left:50%;top:72%;display:flex;align-items:center;gap:8px}
|
||
.fbadge.store .bar{display:inline-block;width:64px;height:6px;border-radius:9px;background:var(--terra-tint);overflow:hidden}
|
||
.fbadge.store .bar i{display:block;height:100%;width:0;background:var(--terra);border-radius:9px}
|
||
.flow[data-scene="files"] .fbadge.store{opacity:1;transform:translate(-50%,-50%)}
|
||
.fbadge.own{border-color:var(--terra);color:var(--terra-dark)}
|
||
.b-acc{left:13%;top:72%}.b-srv{left:50%;top:72%}.b-bot{left:87%;top:72%}
|
||
.b-free{left:50%;top:11%;background:var(--terra);color:#fff8ef;border-color:var(--terra);font-size:clamp(.72rem,1.9vw,.9rem);padding:5px 14px}
|
||
.flow[data-scene="own"] .fbadge.own{opacity:1;transform:translate(-50%,-50%)}
|
||
.flow[data-scene="own"] .b-srv{transition-delay:.15s}.flow[data-scene="own"] .b-bot{transition-delay:.3s}.flow[data-scene="own"] .b-free{transition-delay:.55s}
|
||
|
||
.fchip{position:absolute;left:0;top:0;z-index:4;white-space:nowrap;pointer-events:none;will-change:transform,opacity;
|
||
background:var(--card);border:1px solid var(--line);border-radius:14px 14px 14px 4px;padding:5px 11px;
|
||
font-size:clamp(.68rem,1.8vw,.86rem);font-weight:600;color:var(--ink);box-shadow:0 6px 16px rgba(90,55,20,.14);opacity:0}
|
||
.fchip.back{border-radius:14px 14px 4px 14px;background:#f2f6e9;border-color:#d3e0bd}
|
||
.fchip.big{border-color:var(--terra);font-weight:700}
|
||
.fchip.btn{background:var(--terra);color:#fff8ef;border-color:var(--terra);border-radius:10px}
|
||
.fchip.copy{font-size:clamp(.6rem,1.5vw,.72rem);padding:3px 8px}
|
||
|
||
.flow-cap{min-height:74px;margin-top:14px;transition:opacity .25s}
|
||
.flow-cap.fade{opacity:0}
|
||
.flow-title{font-family:var(--serif);font-weight:700;font-size:clamp(1.15rem,2.8vw,1.45rem);line-height:1.2}
|
||
.flow-sub{color:var(--muted);font-size:.94rem;max-width:560px;margin:4px auto 0}
|
||
.flow-steps{display:flex;justify-content:center;gap:8px;flex-wrap:wrap;margin-top:12px}
|
||
.flow-steps button{font:inherit;font-size:.82rem;font-weight:700;color:var(--muted);background:transparent;border:1px solid var(--line);
|
||
border-radius:999px;padding:5px 12px;cursor:pointer;position:relative;overflow:hidden}
|
||
.flow-steps button:hover{border-color:var(--terra);color:var(--terra-dark)}
|
||
.flow-steps button.on{color:#fff8ef;background:var(--terra);border-color:var(--terra)}
|
||
.flow-steps button.on::after{content:"";position:absolute;left:0;bottom:0;height:3px;background:rgba(255,248,239,.7);
|
||
animation:prog var(--dur,8s) linear forwards}
|
||
@keyframes prog{from{width:0}to{width:100%}}
|
||
@media(max-width:560px){
|
||
.flow{padding:12px 10px 14px}
|
||
.ftarget{padding:5px 8px;font-size:.92rem;gap:4px}.ftarget small{font-size:.64rem}
|
||
.fgroup{left:55%}.fchan{left:84%}
|
||
.b-acc{left:19%}.b-bot{left:83%}
|
||
.fbadge{padding:3px 8px}
|
||
}
|
||
@media(prefers-reduced-motion:reduce){.flow-lines .track,.flow-lines .branch{animation:none}.flow[data-scene="own"] .fsrv{animation:none}.flow-steps button.on::after{display:none}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<header class="nav">
|
||
<div class="wrap">
|
||
<span class="brand" style="display:inline-flex;align-items:center;gap:9px">
|
||
<img src="icon.png" alt="Telemax" width="30" height="30" style="border-radius:8px;display:block">
|
||
<span>Tele<span class="dot">max</span></span>
|
||
</span>
|
||
<span class="spacer"></span>
|
||
<a class="navlink" href="#features">Возможности</a>
|
||
<a class="navlink" href="max-v-telegram/">Инструкция</a>
|
||
<a class="navlink" href="news/">Новости</a>
|
||
<a class="navlink" href="#faq">Вопросы</a>
|
||
<a class="navlink" href="#contact">Связаться</a>
|
||
<a class="navlink" href="https://github.com/Trollobot/Telemax">GitHub</a>
|
||
<a class="navlink support" href="#support">♥ Поддержать</a>
|
||
</div>
|
||
</header>
|
||
|
||
<main>
|
||
<div class="hero wrap">
|
||
<div class="eye">бесплатно · открытый код · свой сервер</div>
|
||
<span class="chip">🔑 ваш личный аккаунт MAX, а не бот</span>
|
||
<h1>Переписка из MAX —<br>прямо в <span class="hl">Telegram</span></h1>
|
||
<p class="lead">
|
||
<b>Telemax</b> — бесплатный мост между <b>MAX</b> и <b>Telegram</b> с открытым кодом.
|
||
Он входит в ваш <b>личный аккаунт MAX по номеру</b> и приносит все чаты в Telegram:
|
||
каждый чат — отдельная тема в вашей группе. Читаете и отвечаете из привычного Телеграма,
|
||
а мост работает на вашем сервере.
|
||
</p>
|
||
<div class="cta">
|
||
<a class="btn btn-primary" href="#how">Как установить</a>
|
||
<a class="btn btn-ghost" href="https://github.com/Trollobot/Telemax">Открыть на GitHub</a>
|
||
</div>
|
||
<!-- news:latest -->
|
||
<a class="newsbar" href="news/#v1.3.6"><span class="nb-tag">Новое · v1.3.6</span><span class="nb-text">🖼️ Фото из MAX больше не теряются</span><span class="nb-go" aria-hidden="true">→</span></a>
|
||
<!-- /news:latest -->
|
||
|
||
<div class="flow" id="flow" data-scene="chat" role="region" aria-label="Как работает Telemax: MAX, ваш сервер и Telegram">
|
||
<div class="flow-stage" aria-hidden="true">
|
||
<svg class="flow-lines" viewBox="0 0 100 100" preserveAspectRatio="none">
|
||
<line class="track" x1="13" y1="38" x2="87" y2="38"/>
|
||
<line class="branch" data-to="group" x1="50" y1="38" x2="62" y2="84"/>
|
||
<line class="branch" data-to="chan" x1="50" y1="38" x2="86" y2="84"/>
|
||
</svg>
|
||
<div class="fnode round fmax" data-node="max">MAX<small>ваш аккаунт</small><span class="cnt"></span></div>
|
||
<div class="fnode fsrv" data-node="srv">Telemax<small>ваш сервер</small></div>
|
||
<div class="fnode round ftg" data-node="tg">Telegram<small>ваша группа</small><span class="cnt"></span></div>
|
||
<div class="fnode ftarget fgroup" data-node="group">👥<small>группа</small></div>
|
||
<div class="fnode ftarget fchan" data-node="chan">📢<small>канал</small></div>
|
||
<div class="fbadge store">💾 файл на вашем сервере <span class="bar"><i></i></span></div>
|
||
<div class="fbadge own b-acc">👤 ваш аккаунт</div>
|
||
<div class="fbadge own b-srv">🔑 ваш сервер</div>
|
||
<div class="fbadge own b-bot">🤖 ваш бот</div>
|
||
<div class="fbadge own b-free">🔓 открытый код · 0 ₽</div>
|
||
</div>
|
||
<div class="flow-cap" aria-live="polite"><div class="flow-title">Переписка в обе стороны</div><div class="flow-sub">Текст, голосовые, фото, кружки и стикеры идут из MAX в Telegram через ваш сервер, а ответы уходят обратно от вашего имени.</div></div>
|
||
<div class="flow-steps"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<section id="why" class="alt">
|
||
<div class="wrap">
|
||
<div class="kicker">Зачем это</div>
|
||
<h2>Все переписки — в одном мессенджере</h2>
|
||
<p class="sub" style="max-width:760px">
|
||
Работа, школьный чат, родня — в MAX, а всё остальное — в Telegram. Telemax собирает их вместе:
|
||
сообщения из Макса приходят в Телеграм, а ваши ответы уходят обратно от вашего имени.
|
||
Не нужно переключаться между приложениями и держать открытыми два мессенджера.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="diff">
|
||
<div class="wrap">
|
||
<div class="callout">
|
||
<div class="kicker">Главное отличие</div>
|
||
<h2>Личный аккаунт, а не бот</h2>
|
||
<p class="sub" style="margin:0">
|
||
Telemax входит вашим <b>личным аккаунтом MAX по номеру</b> — поэтому в Telegram
|
||
сами приходят <b>все</b> ваши чаты, диалоги и группы. Мостам-ботам это недоступно.
|
||
</p>
|
||
<div class="vs">
|
||
<div class="c good">
|
||
<div class="tag">Telemax — личный аккаунт</div>
|
||
Все чаты MAX приходят сами, ничего не нужно добавлять в каждый чат. Видите то же, что видели бы в приложении MAX.
|
||
</div>
|
||
<div class="c bad">
|
||
<div class="tag">Мосты-боты</div>
|
||
Работают только там, куда добавили бота. Личные диалоги и чужие группы — мимо. Везде подключать вручную.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="features" class="alt">
|
||
<div class="wrap">
|
||
<div class="kicker">Возможности</div>
|
||
<h2>Полноценная переписка в обе стороны</h2>
|
||
<div class="grid" style="margin-top:26px">
|
||
<div class="feat"><div class="ic">💬</div><h3>Все типы сообщений</h3><p>Текст, фото, видео, файлы, голосовые, кружки, стикеры (и анимированные), опросы, геолокация и контакты — туда и обратно.</p></div>
|
||
<div class="feat"><div class="ic">🗂️</div><h3>Чат = тема</h3><p>Каждый чат MAX — отдельная тема в группе Telegram. В групповых чатах видно, кто написал, есть список участников и личка в одно нажатие.</p></div>
|
||
<div class="feat"><div class="ic">↩️</div><h3>Ответы, правки, реакции</h3><p>Ответы с переходом к оригиналу, правки с пометкой, удаление в обе стороны. Реакции тоже синхронизируются.</p></div>
|
||
<div class="feat"><div class="ic">📁</div><h3>Большие файлы</h3><p>Из MAX больше 50 МБ — кнопкой «⬇️ Скачать» с вашего сервера. В MAX — до 4 ГБ через страницу загрузки, в обход ограничений бота.</p></div>
|
||
<div class="feat"><div class="ic">📤</div><h3>Свой файлообменник</h3><p>Положите на свой сервер файл любого размера и делитесь ссылкой где угодно — или отправьте его в любой чат MAX командой <code>/file</code>, не загружая заново.</p></div>
|
||
<div class="feat"><div class="ic">🤖</div><h3>Кнопки ботов MAX</h3><p>Ссылки открываются, «Скопировать код» копирует, нажатия уходят боту от вашего имени — как в приложении.</p></div>
|
||
<div class="feat"><div class="ic">📡</div><h3>Трансляция</h3><p>Новые сообщения чата MAX — в любые группы и каналы Telegram, для тех, у кого нет MAX. Командой <code>/broadcast</code>, мест сколько угодно.</p></div>
|
||
<div class="feat"><div class="ic">📇</div><h3>Контакты MAX</h3><p>Найденного человека — в контакты MAX одной кнопкой, и в <code>/info</code> тоже. Контакт из Telegram сохранится под тем же именем.</p></div>
|
||
<div class="feat"><div class="ic">👥</div><h3>Группы MAX из Telegram</h3><p>Создать группу, пригласить или удалить участника, переименовать, выйти — командами прямо из темы.</p></div>
|
||
<div class="feat"><div class="ic">🎛️</div><h3>Пульт управления</h3><p>Команда <code>/panel</code>: поиск по номеру, MAX ID или нику, новый чат в одно нажатие, файлы, статус сервера, пауза и бан чатов.</p></div>
|
||
<div class="feat"><div class="ic">🔐</div><h3>Вход в MAX в личке бота</h3><p>Номер, код из SMS и пароль вводятся в личных сообщениях бота — в группу они не попадают.</p></div>
|
||
<div class="feat"><div class="ic">⬆️</div><h3>Обновления по кнопке</h3><p>Бот сам сообщает о новой версии. Релизы подписаны, а если обновление сорвётся — мост вернётся на прежнюю версию.</p></div>
|
||
<div class="feat"><div class="ic">🔁</div><h3>Ничего не теряется</h3><p>Пропущенное, пока мост был недоступен, догружается само. Сбои связи не сбрасывают вход в MAX.</p></div>
|
||
<div class="feat"><div class="ic">🌐</div><h3>Прокси для Telegram</h3><p>Если сервер выходит в Telegram только через прокси — подключите свой SOCKS5 или HTTP. MAX при этом идёт напрямую.</p></div>
|
||
<div class="feat"><div class="ic">🖥️</div><h3>Несколько мостов</h3><p>Второй номер MAX — второй мост на том же сервере, той же командой. Обновляются все сразу.</p></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="privacy">
|
||
<div class="wrap">
|
||
<div class="kicker">Приватность</div>
|
||
<h2>Свой сервер и открытый код</h2>
|
||
<p class="sub" style="max-width:780px">
|
||
Telemax работает на <b>вашем</b> сервере с <b>вашим</b> Telegram-ботом: переписка идёт только между MAX,
|
||
вашим сервером и Telegram. Код открыт под лицензией AGPL-3.0 — можно прочитать каждую строчку.
|
||
Мост не держит открытых портов: 80 и 443 открываются, только пока живёт ссылка на файл.
|
||
Установщик предлагает поставить Fail2ban от подбора паролей SSH.
|
||
</p>
|
||
<p class="sub" style="max-width:780px;font-size:.94rem">
|
||
Разработчику уходят только анонимная статистика установок и отчёты об ошибках — без текста переписки,
|
||
названий чатов и номера телефона. Отключаются одной строкой <code>TELEMETRY=off</code>.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="how" class="alt">
|
||
<div class="wrap">
|
||
<div class="kicker">Установка</div>
|
||
<h2>Три шага — и мост работает</h2>
|
||
<div class="steps" style="margin-top:30px">
|
||
<div class="step"><h3>Сервер</h3><p>VPS на Ubuntu 22.04+ или Debian 12+. Хватит и меньше 1 ГБ памяти и 3 ГБ свободного места.</p></div>
|
||
<div class="step"><h3>Бот и группа</h3><p>Бот в <code>@BotFather</code>, группа с включёнными темами, бот в ней — администратор с правом «Управление темами».</p></div>
|
||
<div class="step"><h3>Одна команда</h3><p>Запустите от root команду ниже, затем <code>/login</code> в личке бота — и чаты MAX начнут появляться в группе.</p></div>
|
||
</div>
|
||
<div class="cmd">
|
||
<pre>curl -fsSL https://raw.githubusercontent.com/Trollobot/Telemax/main/install.sh | bash</pre>
|
||
<div class="label">Если GitHub с сервера недоступен — та же установка с зеркала:</div>
|
||
<pre>curl -fsSL https://zergont-gate.duckdns.org/install.sh | bash</pre>
|
||
</div>
|
||
<p class="center" style="margin-top:32px">
|
||
<a class="btn btn-primary" href="max-v-telegram/">Пошаговая инструкция</a>
|
||
<a class="btn btn-ghost" href="https://github.com/Trollobot/Telemax#быстрый-старт">README на GitHub</a>
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="shots">
|
||
<div class="wrap">
|
||
<div class="kicker">Как это выглядит</div>
|
||
<h2>Скриншоты</h2>
|
||
<div class="shots" style="margin-top:22px">
|
||
<figure class="shot"><img src="shot-group.png" alt="Группа Telegram сразу после установки Telemax: бот подключился и закрепил пульт" width="1432" height="994" loading="lazy"><figcaption>Сразу после установки: бот подключился и закрепил пульт</figcaption></figure>
|
||
<figure class="shot"><img src="shot-files.png" alt="Раздел «Файлы» в пульте Telemax: файлы на сервере и кнопка «Загрузить файл»" width="876" height="858" loading="lazy"><figcaption>«📁 Файлы»: большие файлы и свой файлообменник</figcaption></figure>
|
||
<figure class="shot"><img src="shot-chat.webp" alt="Переписка MAX в теме Telegram: геолокация и видеокружок" width="1344" height="1564" loading="lazy"><figcaption>Геолокация ушла в MAX, в ответ пришёл кружок</figcaption></figure>
|
||
<figure class="shot"><img src="shot-bot.png" alt="Бот MAX с кнопками в теме Telegram" width="1412" height="1832" loading="lazy"><figcaption>Бот MAX отвечает в теме, его кнопки работают в Telegram</figcaption></figure>
|
||
<figure class="shot wide"><img src="shot-status.png" alt="Карточка «Статус» в пульте Telemax: связь с MAX и Telegram, диск и память сервера" width="964" height="472" loading="lazy"><figcaption>«Статус»: связь, последние сообщения, диск и память сервера</figcaption></figure>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="limits" class="alt">
|
||
<div class="wrap">
|
||
<div class="kicker">Честно об ограничениях</div>
|
||
<h2>Что стоит знать заранее</h2>
|
||
<ul class="limits">
|
||
<li>Проект неофициальный и работает с вашим аккаунтом MAX на ваш страх и риск.</li>
|
||
<li>Соединения шифруются: MAX ↔ сервер по TLS, сервер ↔ Telegram по HTTPS. Но шифрование не сквозное: ваш сервер видит переписку — иначе он не смог бы её пересылать, — поэтому его стоит защищать.</li>
|
||
<li>Любой участник группы в Telegram видит все ваши чаты MAX — держите группу закрытой.</li>
|
||
<li>Аккаунт MAX нужен свой: зарегистрироваться и поставить пароль можно только в приложении MAX.</li>
|
||
<li>Для больших файлов нужен белый IP сервера и открытые порты 80 и 443. Если сервер дома за роутером без проброса портов — установщик предложит выключить большие файлы, всё остальное работает.</li>
|
||
<li>Звонки приходят только уведомлениями, мини-приложения ботов открываются в MAX.</li>
|
||
<li>Разработчик один: баги бывают, зато чинятся быстро.</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="faq">
|
||
<div class="wrap">
|
||
<div class="kicker">Вопросы</div>
|
||
<h2>Частые вопросы</h2>
|
||
<div style="margin-top:26px">
|
||
<details open><summary>Как читать и отвечать на сообщения MAX в Telegram?</summary><p>Поставьте Telemax на свой сервер и войдите в свой аккаунт MAX через бота. Все чаты MAX появятся в вашей группе Telegram отдельными темами: отвечаете в теме — ответ уходит в MAX от вашего имени.</p></details>
|
||
<details><summary>Нужно ли приложение MAX?</summary><p>Один раз — да: аккаунт MAX регистрируется в приложении, там же ставится пароль. Дальше переписка идёт через Telegram, и приложение можно не открывать.</p></details>
|
||
<details><summary>Это бот в MAX или мой аккаунт?</summary><p>Ваш личный аккаунт: Telemax входит по номеру телефона, поэтому приходят все ваши чаты, а не только те, куда добавлен бот. Со стороны Telegram работает ваш собственный бот.</p></details>
|
||
<details><summary>Можно ли начать новый чат из Telegram?</summary><p>Да: в пульте «Найти контакт» — по номеру в любом виде, по MAX ID или нику бота. Или отправьте в общую тему группы контакт из телефонной книги. Не найдётся только тот, кто закрыл поиск по номеру в настройках приватности MAX, — тогда пусть напишет первым.</p></details>
|
||
<details><summary>Можно ли показать чат MAX тем, у кого нет MAX?</summary><p>Да, трансляцией: команда <code>/broadcast</code> в теме чата — и новые сообщения этого чата копируются в обычную группу или канал Telegram. Мест сколько угодно, бота туда Telegram добавит сам. Трансляция идёт в одну сторону: что пишут там, в MAX не уходит.</p></details>
|
||
<details><summary>Передаются ли файлы, голосовые и кружки?</summary><p>Да, в обе стороны. Файлы больше 50 МБ из MAX приходят ссылкой на ваш сервер, а в MAX можно отправить файл до 4 ГБ через страницу загрузки. Для таких ссылок нужен белый IP сервера и открытые порты 80 и 443 — установщик проверит это сам и, если чего-то не хватает, объяснит.</p></details>
|
||
<details><summary>Сколько это стоит?</summary><p>Telemax бесплатный, весь функционал открыт. Платите только за свой сервер — хватит самого простого VPS.</p></details>
|
||
<details><summary>Заработает ли на российском VPS?</summary><p>Да. Если Telegram с сервера не открывается, мост может работать через прокси. Сам прокси нужен свой (SOCKS5 или HTTP) — его адрес указывают при установке, MAX при этом идёт напрямую.</p></details>
|
||
<details><summary>Можно ли подключить два аккаунта MAX?</summary><p>Да: второй мост ставится той же командой в соседний каталог, со своим ботом и своей группой. Автообновление обслуживает все мосты на сервере.</p></details>
|
||
<details><summary>Что будет, если GitHub недоступен?</summary><p>Установка и обновления сами переключатся на зеркало проекта. Каждый релиз подписан, и мост проверяет подпись перед установкой — неважно, откуда пришёл код.</p></details>
|
||
<details><summary>Это безопасно?</summary><p>Соединения шифруются: MAX ↔ сервер по TLS, сервер ↔ Telegram по HTTPS. Код и данные — на вашем сервере, посредников нет, код открыт. Но шифрование не сквозное: сервер видит переписку, иначе не смог бы её пересылать, — поэтому его стоит защищать. Проект неофициальный — используйте на свой страх и риск.</p></details>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="contact" class="alt">
|
||
<div class="wrap">
|
||
<div class="support-box">
|
||
<div class="heart">💬</div>
|
||
<div class="kicker">Обратная связь</div>
|
||
<h2>Нашли баг, есть идея или вопрос?</h2>
|
||
<p>
|
||
Напишите боту <b>@TelemaxSvv_bot</b> в Telegram: сообщение придёт разработчику, а ответ вернётся вам
|
||
в тот же чат. Вопросы по установке тоже сюда. Если мост уже стоит, ссылка на бота есть и в <code>/help</code>.
|
||
</p>
|
||
<a class="btn btn-primary" href="https://t.me/TelemaxSvv_bot">✉️ Написать в Telegram</a>
|
||
<a class="btn btn-ghost" href="https://github.com/Trollobot/Telemax/issues">Issues на GitHub</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="support">
|
||
<div class="wrap">
|
||
<div class="support-box">
|
||
<div class="heart">♥</div>
|
||
<div class="kicker">Поддержка</div>
|
||
<h2>Поддержать развитие проекта</h2>
|
||
<p>
|
||
Весь функционал бесплатный. Если мост пригодился — можно подогреть мотивацию разработчика:
|
||
здесь или командой <code>/donate</code> прямо в боте.
|
||
</p>
|
||
<a class="btn btn-primary" href="https://pay.cloudtips.ru/p/3c71b5e8">☕ Поддержать развитие проекта</a>
|
||
<div class="crypto">
|
||
или GRAM (TON): <code>UQALpK2PKI90-XpupOM8sRJGdwrFMsPcwQZPR0k180umXBcA</code>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<footer>
|
||
<div class="wrap">
|
||
<div class="links">
|
||
<a href="https://github.com/Trollobot/Telemax">GitHub</a>
|
||
<a href="news/">📰 Новости</a>
|
||
<a href="https://habr.com/ru/posts/1070812/">Первый пост на Хабре</a>
|
||
<a href="https://habr.com/ru/articles/1092754/">Статья на Хабре: бан на GitHub</a>
|
||
<a href="https://vc.ru/id973711/3179706-telemax-integratsiya-max-i-telegram">Статья на vc.ru</a>
|
||
<a href="https://t.me/TelemaxSvv_bot">Баг или идея — боту @TelemaxSvv_bot</a>
|
||
<a href="https://github.com/Trollobot/Telemax/issues">Issues</a>
|
||
<a href="https://telemax.svnest.ru/stats/">📊 Статистика посещений</a>
|
||
</div>
|
||
<div class="disc">
|
||
⚠️ Неофициальный проект с открытым кодом. Не связан с MAX и Telegram. Работает с вашим собственным
|
||
аккаунтом — на ваш страх и риск.
|
||
</div>
|
||
<p style="margin-top:16px">© Telemax — бесплатный мост MAX ↔ Telegram · AGPL-3.0</p>
|
||
</div>
|
||
</footer>
|
||
|
||
<script>
|
||
(function () {
|
||
var root = document.getElementById('flow');
|
||
if (!root || !root.animate) return;
|
||
var stage = root.querySelector('.flow-stage');
|
||
var reduce = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||
var token = 0, visible = true, timers = [];
|
||
|
||
var SCENES = [
|
||
{ id: 'chat', label: 'Переписка', title: 'Переписка в обе стороны',
|
||
sub: 'Текст, голосовые, фото, кружки и стикеры идут из MAX в Telegram через ваш сервер, а ответы уходят обратно от вашего имени.', dur: 7600,
|
||
play: function () {
|
||
at(0, function () { fly('💬 Привет! Ты где?', 'max', 'tg'); });
|
||
at(800, function () { fly('🎤 Голосовое · 0:14', 'max', 'tg'); });
|
||
at(1700, function () { fly('💬 Уже еду 🚗', 'tg', 'max'); });
|
||
at(2500, function () { fly('🖼️ Фото', 'max', 'tg'); });
|
||
at(3400, function () { fly('😄 Стикер', 'tg', 'max'); });
|
||
at(4200, function () { fly('⭕ Кружок · 0:09', 'max', 'tg'); });
|
||
} },
|
||
{ id: 'files', label: 'Файлы', title: 'Большие файлы — по ссылке',
|
||
sub: 'Видео на гигабайт ложится на ваш сервер, а в Telegram приходит кнопка «Скачать». В MAX уходят файлы до 4 ГБ.', dur: 8200,
|
||
play: function () {
|
||
var bar = stage.querySelector('.store .bar i');
|
||
bar.getAnimations().forEach(function (a) { a.cancel(); });
|
||
at(0, function () { fly('🎬 Видео · 1,2 ГБ', 'max', 'srv', { direct: true, dur: 1500, kind: 'big' }); });
|
||
at(1300, function () { bar.animate([{ width: '0%' }, { width: '100%' }], { duration: 1300, easing: 'ease-in-out', fill: 'forwards' }); });
|
||
at(2800, function () { fly('⬇️ Скачать · видео.mp4', 'srv', 'tg', { direct: true, dur: 1600, kind: 'btn' }); });
|
||
at(4300, function () { fly('📎 Отчёт.zip · 3 ГБ', 'tg', 'srv', { direct: true, dur: 1500, kind: 'big' }); });
|
||
at(5800, function () { fly('📎 Отчёт.zip', 'srv', 'max', { direct: true, dur: 1500 }); });
|
||
} },
|
||
{ id: 'cast', label: 'Трансляция', title: 'Трансляция',
|
||
sub: 'Новые сообщения чата копируются в любые группы и каналы Telegram — для тех, у кого нет MAX.', dur: 7800,
|
||
play: function () {
|
||
at(300, function () { cast('💬 Собрание в субботу'); });
|
||
at(1900, function () { cast('🖼️ Фото объявления'); });
|
||
at(3500, function () { cast('📊 Опрос: кто придёт?'); });
|
||
} },
|
||
{ id: 'own', label: 'Всё ваше', title: 'Всё ваше — и бесплатно',
|
||
sub: 'Ваш аккаунт, ваш сервер, ваш бот и открытый код. Никаких подписок — платите только за свой VPS.', dur: 7200,
|
||
play: function () {
|
||
at(900, function () { fly('💬 Спасибо!', 'max', 'tg'); });
|
||
at(2300, function () { fly('👍', 'tg', 'max'); });
|
||
at(3700, function () { fly('🎤 Голосовое · 0:05', 'max', 'tg'); });
|
||
} }
|
||
];
|
||
|
||
// --- helpers -----------------------------------------------------------------------------
|
||
function at(ms, fn) {
|
||
var t = token;
|
||
timers.push(setTimeout(function () { if (t === token) fn(); }, ms));
|
||
}
|
||
function node(name) { return stage.querySelector('[data-node="' + name + '"]'); }
|
||
function pt(name) {
|
||
var s = stage.getBoundingClientRect(), r = node(name).getBoundingClientRect();
|
||
return { x: r.left - s.left + r.width / 2, y: r.top - s.top + r.height / 2 };
|
||
}
|
||
function pulse(name) {
|
||
node(name).animate([{ transform: 'translate(-50%,-50%) scale(1)' }, { transform: 'translate(-50%,-50%) scale(1.09)' }, { transform: 'translate(-50%,-50%) scale(1)' }],
|
||
{ duration: 420, easing: 'ease-out' });
|
||
}
|
||
function bump(name) {
|
||
var c = node(name).querySelector('.cnt');
|
||
if (!c) return;
|
||
c.textContent = String((parseInt(c.textContent, 10) || 0) + 1);
|
||
c.classList.add('on');
|
||
c.animate([{ transform: 'scale(1.35)' }, { transform: 'scale(1)' }], { duration: 260, easing: 'ease-out' });
|
||
}
|
||
function resetCounters() {
|
||
stage.querySelectorAll('.cnt').forEach(function (c) { c.textContent = ''; c.classList.remove('on'); });
|
||
}
|
||
|
||
/** A message bubble from one node to another — through the server unless `direct`. Rightward rides above the line, leftward below. */
|
||
function fly(text, from, to, o) {
|
||
o = o || {};
|
||
var el = document.createElement('div');
|
||
var back = pt(to).x < pt(from).x;
|
||
el.className = 'fchip' + (back ? ' back' : '') + (o.kind ? ' ' + o.kind : '');
|
||
el.textContent = text;
|
||
stage.appendChild(el);
|
||
var W = stage.clientWidth, w = el.offsetWidth, h = el.offsetHeight;
|
||
var lift = o.dy != null ? o.dy : back ? 26 : -26;
|
||
function tf(p, sc) {
|
||
var x = Math.min(Math.max(p.x - w / 2, 4), W - w - 4);
|
||
return 'translate(' + x + 'px,' + (p.y - h / 2 + lift) + 'px) scale(' + sc + ')';
|
||
}
|
||
var A = pt(from), B = pt(to), dur = o.dur || 2700;
|
||
var frames;
|
||
if (o.direct) {
|
||
frames = [
|
||
{ transform: tf(A, .6), opacity: 0, offset: 0 },
|
||
{ transform: tf(A, 1), opacity: 1, offset: .14, easing: 'cubic-bezier(.4,0,.3,1)' },
|
||
{ transform: tf(B, 1), opacity: 1, offset: .86 },
|
||
{ transform: tf(B, .6), opacity: 0, offset: 1 }
|
||
];
|
||
} else {
|
||
var S = pt('srv');
|
||
frames = [
|
||
{ transform: tf(A, .6), opacity: 0, offset: 0 },
|
||
{ transform: tf(A, 1), opacity: 1, offset: .1, easing: 'cubic-bezier(.4,0,.3,1)' },
|
||
{ transform: tf(S, .8), opacity: 1, offset: .46 },
|
||
{ transform: tf(S, .8), opacity: 1, offset: .54, easing: 'cubic-bezier(.4,0,.3,1)' },
|
||
{ transform: tf(B, 1), opacity: 1, offset: .9 },
|
||
{ transform: tf(B, .6), opacity: 0, offset: 1 }
|
||
];
|
||
at(dur * .48, function () { pulse('srv'); });
|
||
}
|
||
var anim = el.animate(frames, { duration: dur, fill: 'forwards' });
|
||
at(dur * (o.direct ? .86 : .9), function () { pulse(to); bump(to); if (o.onArrive) o.onArrive(); });
|
||
anim.finished.then(function () { el.remove(); }, function () { el.remove(); });
|
||
}
|
||
|
||
/** A message of a broadcast chat: MAX → server → Telegram, and copies from the server to the group and the channel. */
|
||
function cast(text) {
|
||
fly(text, 'max', 'tg', { dur: 2700 });
|
||
at(1350, function () {
|
||
fly(text, 'srv', 'group', { direct: true, dur: 1500, kind: 'copy', dy: 0 });
|
||
fly(text, 'srv', 'chan', { direct: true, dur: 1600, kind: 'copy', dy: 0 });
|
||
});
|
||
}
|
||
|
||
/** Branch lines end where the targets actually are (their spot differs on narrow screens). */
|
||
function placeBranches() {
|
||
var s = stage.getBoundingClientRect();
|
||
if (!s.width) return;
|
||
stage.querySelectorAll('.branch').forEach(function (l) {
|
||
var p = pt(l.getAttribute('data-to'));
|
||
l.setAttribute('x2', (p.x / s.width * 100).toFixed(1));
|
||
l.setAttribute('y2', (p.y / s.height * 100).toFixed(1));
|
||
});
|
||
}
|
||
window.addEventListener('resize', placeBranches);
|
||
|
||
// --- scenes ------------------------------------------------------------------------------
|
||
var steps = root.querySelector('.flow-steps');
|
||
var cap = root.querySelector('.flow-cap');
|
||
SCENES.forEach(function (s, i) {
|
||
var b = document.createElement('button');
|
||
b.type = 'button';
|
||
b.textContent = s.label;
|
||
b.addEventListener('click', function () { show(i); });
|
||
steps.appendChild(b);
|
||
});
|
||
|
||
function clearStage() {
|
||
timers.forEach(clearTimeout);
|
||
timers = [];
|
||
stage.querySelectorAll('.fchip').forEach(function (c) { c.remove(); });
|
||
}
|
||
function show(i) {
|
||
token++;
|
||
clearStage();
|
||
resetCounters();
|
||
var s = SCENES[i];
|
||
root.dataset.scene = s.id;
|
||
steps.querySelectorAll('button').forEach(function (b, k) {
|
||
b.classList.toggle('on', k === i);
|
||
b.style.setProperty('--dur', s.dur + 'ms');
|
||
if (k === i) { b.classList.remove('on'); void b.offsetWidth; b.classList.add('on'); } // restart the progress line
|
||
});
|
||
cap.classList.add('fade');
|
||
setTimeout(function () {
|
||
cap.querySelector('.flow-title').textContent = s.title;
|
||
cap.querySelector('.flow-sub').textContent = s.sub;
|
||
cap.classList.remove('fade');
|
||
}, 180);
|
||
setTimeout(placeBranches, 500); // after the targets' slide-in
|
||
if (reduce) return; // a still picture per scene, no flying and no auto-advance
|
||
s.play();
|
||
at(s.dur, function () { next(i); });
|
||
}
|
||
function next(i) {
|
||
if (!visible || document.hidden) { setTimeout(function () { next(i); }, 600); return; }
|
||
show((i + 1) % SCENES.length);
|
||
}
|
||
if ('IntersectionObserver' in window) {
|
||
new IntersectionObserver(function (e) { visible = e[0].isIntersecting; }).observe(root);
|
||
}
|
||
placeBranches();
|
||
show(reduce ? 3 : 0);
|
||
})();
|
||
</script>
|
||
|
||
<script>
|
||
// Счётчик посещений без cookie: сообщает только, откуда пришли и на каком адресе открыт сайт.
|
||
// Сервер сразу раскладывает это по счётчикам и IP не хранит — см. /stats/.
|
||
(function () {
|
||
var h = location.hostname;
|
||
if (location.protocol !== 'https:' || h === 'localhost' || h === '127.0.0.1') return;
|
||
try {
|
||
var body = JSON.stringify({ r: document.referrer || '', h: h });
|
||
var url = 'https://telemax.svnest.ru/api/site/hit';
|
||
if (navigator.sendBeacon) navigator.sendBeacon(url, new Blob([body], { type: 'text/plain' }));
|
||
else fetch(url, { method: 'POST', body: body, keepalive: true, mode: 'no-cors' });
|
||
} catch (e) {}
|
||
})();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|