Как подключить бота
-
Подключите бота в кабинете
В веб-кабинете нажмите «Подключить бота» и вставьте токен из @BotFather. Токен передаётся по HTTPS, хранится в зашифрованном виде и больше нигде не показывается.
-
Дождитесь модерации
Мы проверим бота. Пока бот на модерации, API отвечает
403 The bot on moderation. -
Настройте показы
Предложите тематики бота (их утверждает модерация), при желании отключите нежелательные категории рекламы и разрешите или запретите откровенные посты (в рамках правил Telegram). Язык рекламы подбирается автоматически по языку Telegram пользователя.
-
Получите API-ключ
Ключ показывается один раз — сразу после подключения бота; новый ключ можно выпустить в настройках бота в веб-кабинете. Храните его на сервере и не публикуйте в клиентском коде.
Запрос
POST https://hiviews.net/ с JSON-телом.
Заголовки
| Заголовок | Значение |
|---|---|
Authorization | API-ключ как есть, без префикса Bearer |
Content-Type | application/json |
Поля тела
| Поле | Тип | Описание |
|---|---|---|
UserId | int | ID пользователя Telegram. Только личные чаты — группы и каналы не поддерживаются. |
MessageId | int | ID сообщения пользователя — реклама придёт ответом на него. |
UserFirstName | string | null | Имя пользователя, подставляется вместо $name в тексте поста. Можно передать null — тогда возьмём имя из Telegram. $username в посте заменяется на @username зрителя (или имя, если username нет) — передавать его не нужно. |
StartPlace | bool, необязательное | true или отсутствует — приветственный показ, отправляйте при /start. false — обычный показ в других местах бота. |
Пример тела
{
"UserId": 123456789,
"MessageId": 45,
"UserFirstName": "Ivan",
"StartPlace": true
}Когда вызывать
- Приветственный показ — первой строкой обработчика
/start(StartPlace: trueили без поля). Дождитесь ответа: при успехе API отвечает примерно через 2 секунды — пользователю даётся время прочитать рекламу, затем ваш бот показывает своё приветствие. - Обычный показ — в ответ на реальное действие пользователя (
StartPlace: false), после того как бот выдал результат: сначала отправьте пользователю то, за чем он пришёл (видео, файл, ответ), и только затем запрашивайте рекламу. Так пост окажется последним сообщением в чате. Если реклама придёт до результата, результат сразу её перекроет: такие показы почти не кликают, и бот получает меньше рекламы с оплатой за переходы. - Правила одинаковы для ботов и мини-приложений (Mini Apps).
Лимиты частоты: пользователь получает не больше одной рекламы в час во всей сети (и не больше дневного лимита), а приветственный показ в одном боте — не чаще раза в сутки. Лишние вызовы просто вернут No posts found for this user.
Запросы разрешены только в личных чатах и только в ответ на реальный /start (первой строкой обработчика) или реальную активность пользователя.
Нельзя отправлять запросы без сообщения пользователя, отвечать на старые /start и подменять параметры (UserId, MessageId, StartPlace). За нарушения бот или мини-приложение блокируется, начисления отменяются; показы фейковым и пустым аккаунтам не оплачиваются.
Ответы
Тело ответа — простой текст, не JSON. Ориентируйтесь на HTTP-код и текст.
| Код | Текст ответа | Что означает |
|---|---|---|
| 200 | Post sent! | Рекламный пост отправлен пользователю. Ответ приходит примерно через 2 с — время на прочтение рекламы. |
| 400 | No posts found for this user | Сейчас нет подходящей рекламы для этого пользователя. Это нормально — просто игнорируйте. |
| 400 | JSON not found… | Тело запроса пустое или не является JSON. |
| 400 | "UserId" field not found… | Не передано поле UserId. |
| 400 | "MessageId" field not found… | Не передано поле MessageId. |
| 400 | "UserFirstName" field not found… | Не передано поле UserFirstName (передайте хотя бы null). |
| 400 | "Place" field not found… | Не удалось определить место показа — проверьте поле StartPlace (bool). |
| 400 | Chat type must be private (not group) | Реклама отправляется только в личные чаты. |
| 400 | API key not found… | Нет заголовка Authorization или ключ неверный. |
| 400 | Invalid BotFather token! (Refresh it in t.me/HiViewsBot) | Токен бота отозван или изменён — обновите его в @HiViewsBot («Обновить токен» в карточке бота). |
| 400 | Текст ошибки Telegram, например Forbidden: bot was blocked by the user | Telegram отказал в отправке — чаще всего пользователь заблокировал бота. |
| 403 | The bot on moderation | Бот ещё на модерации. |
| 403 | The bot is blocked | Бот заблокирован — напишите в поддержку. |
| 403 | The bot is disabled (enable in t.me/HiViewsBot) | Показы выключены — включите их в веб-кабинете. |
Примеры кода
curl -X POST https://hiviews.net/sendMessage \
-H "Authorization: <API-ключ>" \
-H "Content-Type: application/json" \
-d '{
"UserId": 123456789,
"MessageId": 45,
"UserFirstName": "Ivan",
"StartPlace": true
}'import asyncio
import logging
import httpx
from aiogram import Bot, Dispatcher, F, Router
from aiogram.filters import CommandStart
from aiogram.types import Message
HIVIEWS_URL = "https://hiviews.net/sendMessage"
HIVIEWS_KEY = "<API-ключ>"
router = Router()
router.message.filter(F.chat.type == "private") # только личные чаты
http = httpx.AsyncClient(timeout=5.0)
async def show_ad(message: Message, start_place: bool) -> None:
# При успехе API отвечает примерно через 2 с — это время на прочтение рекламы.
try:
resp = await http.post(
HIVIEWS_URL,
headers={"Authorization": HIVIEWS_KEY},
json={
"UserId": message.from_user.id,
"MessageId": message.message_id,
"UserFirstName": message.from_user.first_name,
"StartPlace": start_place,
},
)
# "No posts found" — подходящей рекламы нет, это нормально
if resp.status_code != 200 and resp.text != "No posts found for this user":
logging.warning("HiViews: %s %s", resp.status_code, resp.text)
except httpx.HTTPError as e:
logging.warning("HiViews request failed: %s", e)
@router.message(CommandStart())
async def on_start(message: Message) -> None:
await show_ad(message, start_place=True) # первой строкой, ждём ответа
await message.answer("Привет! Чем помочь?") # затем — ваше приветствие
async def main() -> None:
bot = Bot("<BOT_TOKEN>")
dp = Dispatcher()
dp.include_router(router)
try:
await dp.start_polling(bot)
finally:
await http.aclose()
if __name__ == "__main__":
asyncio.run(main())import logging
import requests
HIVIEWS_URL = "https://hiviews.net/sendMessage"
HIVIEWS_KEY = "<API-ключ>"
def show_ad(user_id: int, message_id: int, first_name: str | None,
start_place: bool = True) -> None:
# При успехе API отвечает примерно через 2 с — это время на прочтение рекламы.
try:
resp = requests.post(
HIVIEWS_URL,
headers={"Authorization": HIVIEWS_KEY},
json={
"UserId": user_id,
"MessageId": message_id,
"UserFirstName": first_name,
"StartPlace": start_place,
},
timeout=5,
)
if resp.status_code != 200 and resp.text != "No posts found for this user":
logging.warning("HiViews: %s %s", resp.status_code, resp.text)
except requests.RequestException as e:
logging.warning("HiViews request failed: %s", e)
# в обработчике /start (личный чат) — первой строкой, дождавшись ответа:
# show_ad(user.id, message.message_id, user.first_name, start_place=True)
# send_greeting(user.id) # затем — ваше приветствие// Node.js 18+ (встроенный fetch)
const HIVIEWS_URL = "https://hiviews.net/sendMessage";
const HIVIEWS_KEY = process.env.HIVIEWS_KEY; // <API-ключ>
// При успехе API отвечает примерно через 2 с — это время на прочтение рекламы.
async function showAd({ userId, messageId, firstName = null, startPlace = true }) {
try {
const res = await fetch(HIVIEWS_URL, {
method: "POST",
headers: { "Authorization": HIVIEWS_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
UserId: userId,
MessageId: messageId,
UserFirstName: firstName,
StartPlace: startPlace,
}),
signal: AbortSignal.timeout(5000),
});
const text = await res.text();
if (res.status !== 200 && text !== "No posts found for this user") {
console.warn("HiViews:", res.status, text);
}
} catch (err) {
console.warn("HiViews request failed:", err.message);
}
}
// в обработчике /start (личный чат) — первой строкой, дождавшись ответа:
// await showAd({ userId: ctx.from.id, messageId: ctx.message.message_id,
// firstName: ctx.from.first_name, startPlace: true });
// await ctx.reply("Привет! Чем помочь?"); // затем — ваше приветствие<?php
const HIVIEWS_KEY = '<API-ключ>';
// При успехе API отвечает примерно через 2 с — это время на прочтение рекламы.
function hiviews_show_ad(int $userId, int $messageId, ?string $firstName, bool $startPlace = true): void
{
$ch = curl_init('https://hiviews.net/sendMessage');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . HIVIEWS_KEY,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'UserId' => $userId,
'MessageId' => $messageId,
'UserFirstName' => $firstName,
'StartPlace' => $startPlace,
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code !== 200 && $body !== 'No posts found for this user') {
error_log("HiViews: $code $body");
}
}
// в обработчике /start (личный чат) — первой строкой, дождавшись ответа:
// $msg = $update['message'];
// hiviews_show_ad($msg['from']['id'], $msg['message_id'], $msg['from']['first_name'] ?? null, true);
// send_greeting($msg['chat']['id']); // затем — ваше приветствиеPost sent!
Подключение без токена
Если вы не хотите передавать токен бота, подключите бота в кабинете в режиме «Без токена». Вы подтверждаете, что бот ваш, кодом в его описании (Edit About в @BotFather), и получаете API-ключ. Дальше бот сам запрашивает рекламу и сам отправляет её пользователю.
- Оплата — за подтверждённые показы и за переходы. Бот без токена сразу получает все кампании сети — приветственные и обычные показы, с оплатой за показы и за клики — и внешнюю рекламу; отдельного одобрения ждать не нужно. Оплачивается каждый показ, отправку которого подтвердил сам Telegram, поэтому отправляйте пост ровно в том виде, в каком получили. Переходы по рекламе с оплатой за клик — $0,04 за переход. Ставка за показ без токена ниже, чем с токеном: с токеном рекламу отправляем мы и подтверждение не требуется.
- Запрос:
POST https://hiviews.net/api/partner/adс заголовкомAuthorization: API-ключ. Поля:UserId(обязательно),UserFirstName,Username,Language(язык пользователя из Telegram),StartPlace—trueпри /start,falseпосле выдачи результата. - Ответ всегда JSON. Если реклама есть —
"ok": trueи объектad: отправьте его пользователю как есть. Если рекламы нет —"ok": false, просто продолжайте работу. - Ничего не меняйте в посте. Ссылки в кнопках ведут через hiviews.net — по ним считаются переходы. Изменённая ссылка не оплачивается.
- Подтверждение отправки. В начале текста стоит невидимая ссылка: когда бот отправляет пост, Telegram сам запрашивает её — так мы узнаём, что пост действительно ушёл. Поэтому не отключайте превью ссылок (
disable_web_page_preview) и не вырезайте ссылки из текста. Неподтверждённый пост не оплачивается: ни показ, ни переходы по нему. delete_after— если поле есть, удалите пост через столько секунд.- Переход на полный режим. Когда будете готовы, вставьте токен бота на его странице в кабинете. Код менять не нужно: тот же запрос продолжит работать, рекламу начнём отправлять мы (ответ будет без
ad), и каждый показ будет оплачиваться по ставке с токеном, без подтверждения. - Защита от накрутки: все ссылки в рекламе идут через трекинг HiViews, и мы знаем, как часто по тем же кампаниям переходят в ботах с токеном. Бот, у которого переходы не сходятся с показами (намного меньше или намного больше ожидаемого), автоматически теряет оплачиваемые показы и возвращается к оплате только за переходы; бот, который на деле не отправляет большую часть взятых постов, перестаёт получать рекламу. Оплачивается не больше одного перехода с одного IP-адреса в час; при неправдоподобно высокой доле переходов оплата приостанавливается.
- Сеть ботов. Полная инструкция — на странице «Сеть ботов». Если у вас много ботов, не нужно подключать каждый: по запросу в поддержку мы выдаём один ключ на всю сеть. Запрос тот же, плюс поле
Bot— имя бота, для которого нужна реклама (без @):{"UserId": 123, "UserFirstName": "Ivan", "Language": "ru", "StartPlace": true, "Bot": "my_first_bot"}. Бот регистрируется при первом запросе, статистика ведётся по каждому боту и по сети целиком. Ответыbad_bot(имя не похоже на имя бота) иbot_taken(этот бот уже подключён кем-то отдельно) означают, что рекламу для этого имени получить нельзя.
Ответ
{
"ok": true,
"ad": {
"text": "Ivan, look at this…",
"parse_mode": "HTML",
"reply_markup": {"inline_keyboard": [[{"text": "Open", "url": "https://hiviews.net/api/go/…"}]]},
"photo": "https://hiviews.net/api/go/m/…",
"delete_after": 60
}
}Готовый код: Python, aiogram 3
import asyncio, aiohttp
from aiogram import Bot
from aiogram.types import InlineKeyboardMarkup
HIVIEWS_KEY = "YOUR_API_KEY"
async def show_ad(bot: Bot, user, start: bool = False) -> None:
payload = {"UserId": user.id, "UserFirstName": user.first_name, "Username": user.username,
"Language": user.language_code, "StartPlace": start}
try:
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=5)) as s:
async with s.post("https://hiviews.net/api/partner/ad", json=payload,
headers={"Authorization": HIVIEWS_KEY}) as r:
ad = (await r.json()).get("ad")
if not ad:
return
kw = {"parse_mode": "HTML", "reply_markup": InlineKeyboardMarkup.model_validate(ad["reply_markup"])}
if ad.get("photo"):
msg = await bot.send_photo(user.id, ad["photo"], caption=ad["text"], **kw)
elif ad.get("video"):
msg = await bot.send_video(user.id, ad["video"], caption=ad["text"], **kw)
elif ad.get("animation"):
msg = await bot.send_animation(user.id, ad["animation"], caption=ad["text"], **kw)
else:
msg = await bot.send_message(user.id, ad["text"], **kw) # не отключайте превью ссылок
if ad.get("delete_after"):
asyncio.get_running_loop().call_later(
ad["delete_after"], lambda: asyncio.ensure_future(quiet_delete(bot, user.id, msg.message_id)))
except Exception:
pass
async def quiet_delete(bot: Bot, chat_id: int, message_id: int) -> None:
try:
await bot.delete_message(chat_id, message_id)
except Exception:
passГотовый код: Node.js, Telegraf
// HiViews без токена: бот сам отправляет рекламу, оплата — за подтверждённые показы и переходы. Node.js 18+, Telegraf.
// Отправляйте пост как есть: по скрытой ссылке в тексте Telegram подтверждает нам отправку.
const HIVIEWS_KEY = "YOUR_API_KEY";
async function showAd(ctx, start = false) {
// При /start вызывайте showAd(ctx, true), после выдачи результата — showAd(ctx, false).
try {
const u = ctx.from;
const res = await fetch("https://hiviews.net/api/partner/ad", {
method: "POST",
headers: { Authorization: HIVIEWS_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ UserId: u.id, UserFirstName: u.first_name, Username: u.username,
Language: u.language_code, StartPlace: start }),
signal: AbortSignal.timeout(5000),
});
const { ad } = await res.json();
if (!ad) return; // сейчас рекламы для этого человека нет
const extra = { parse_mode: "HTML", reply_markup: ad.reply_markup };
let msg;
if (ad.photo) msg = await ctx.telegram.sendPhoto(u.id, ad.photo, { caption: ad.text, ...extra });
else if (ad.video) msg = await ctx.telegram.sendVideo(u.id, ad.video, { caption: ad.text, ...extra });
else if (ad.animation) msg = await ctx.telegram.sendAnimation(u.id, ad.animation, { caption: ad.text, ...extra });
else msg = await ctx.telegram.sendMessage(u.id, ad.text, extra); // превью ссылок не отключайте
if (ad.delete_after) {
setTimeout(() => ctx.telegram.deleteMessage(u.id, msg.message_id).catch(() => {}), ad.delete_after * 1000);
}
} catch (e) { /* реклама никогда не должна ломать бота */ }
}
// Пример: bot.start(async (ctx) => { await showAd(ctx, true); /* ваше приветствие */ });Готовый код: PHP
<?php
// HiViews без токена: бот сам отправляет рекламу, оплата — за подтверждённые показы и переходы.
// Отправляйте пост как есть: по скрытой ссылке в тексте Telegram подтверждает нам отправку.
const HIVIEWS_KEY = 'YOUR_API_KEY';
/** $user — массив from из апдейта Telegram. При /start: $start = true, после выдачи результата: false.
* Возвращает [message_id, delete_after] — если delete_after не null, удалите сообщение через столько секунд. */
function hiviews_show_ad(string $botToken, array $user, bool $start = false): ?array
{
$ch = curl_init('https://hiviews.net/api/partner/ad');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5,
CURLOPT_HTTPHEADER => ['Authorization: ' . HIVIEWS_KEY, 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'UserId' => $user['id'], 'UserFirstName' => $user['first_name'] ?? '',
'Username' => $user['username'] ?? null, 'Language' => $user['language_code'] ?? null,
'StartPlace' => $start,
]),
]);
$ad = json_decode((string) curl_exec($ch), true)['ad'] ?? null;
curl_close($ch);
if (!$ad) {
return null; // сейчас рекламы для этого человека нет
}
$params = ['chat_id' => $user['id'], 'parse_mode' => 'HTML', 'reply_markup' => json_encode($ad['reply_markup'])];
if (!empty($ad['photo'])) {
$method = 'sendPhoto'; $params += ['photo' => $ad['photo'], 'caption' => $ad['text']];
} elseif (!empty($ad['video'])) {
$method = 'sendVideo'; $params += ['video' => $ad['video'], 'caption' => $ad['text']];
} elseif (!empty($ad['animation'])) {
$method = 'sendAnimation'; $params += ['animation' => $ad['animation'], 'caption' => $ad['text']];
} else {
$method = 'sendMessage'; $params += ['text' => $ad['text']]; // превью ссылок не отключайте
}
$ch = curl_init('https://api.telegram.org/bot' . $botToken . '/' . $method);
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10,
CURLOPT_POSTFIELDS => $params]);
$sent = json_decode((string) curl_exec($ch), true);
curl_close($ch);
return [$sent['result']['message_id'] ?? null, $ad['delete_after'] ?? null];
}
// Пример: hiviews_show_ad($botToken, $update['message']['from'], true); // в обработчике /startСоветы
- Вызывайте API первой строкой обработчика
/startи дожидайтесь ответа (await). Успешный ответ приходит примерно через 2 секунды — это окно на прочтение рекламы; после него отправляйте своё приветствие. - Ставьте таймаут 5 секунд. При ошибке сети не повторяйте запрос — просто продолжайте работу бота.
- Ответ
400 No posts found for this userприходит сразу — обрабатывайте его молча и показывайте приветствие. - Логируйте остальные ошибки:
403требует действия в веб-кабинете, ошибка токена — в @HiViewsBot. - Храните API-ключ на сервере, в переменных окружения.
Доход и выплаты
- $4,80 за 1000 приветственных и $2,40 за 1000 обычных показов.
- $0,04 за переход — с рекламы, оплаченной за клики. Она идёт в бот, только если при его CTR это выгоднее показов. Интеграция та же: никаких изменений в API.
- Доход становится доступен к выводу через 7 дней.
- Вывод в USDT (TRC20) от $50, комиссия $3 — заявка в веб-кабинете, подтверждение в Telegram-боте.