unixgram (Python)
Библиотека для написания ботов Unixgram. Без зависимостей — только стандартная библиотека.
Форма API повторяет pyTelegramBotAPI, а формат запросов — Bot API Telegram, поэтому пример,
написанный под Telegram, переносится сюда сменой одного импорта.
Установка
pip install unixgram-py
Пакет называется unixgram-py, а импортируется как unixgram — имя unixgram на PyPI занято
чужим проектом. Зависимостей нет: весь клиент — это urllib из стандартной библиотеки. Бот
поднимается на любом сервере, где есть Python 3.9+.
Первый бот
Токен выдаётся в приложении: бургер-меню → Мои боты → Создать. Показывается он один раз.
from unixgram import Bot, InlineKeyboardMarkup, InlineKeyboardButton
bot = Bot("123456789:F7hK…")
@bot.message_handler(commands=["start"])
def start(message):
kb = InlineKeyboardMarkup()
kb.row(InlineKeyboardButton("Нажми", callback_data="ping"))
bot.send_message(message.chat.id, "Привет!", reply_markup=kb)
@bot.callback_query_handler(func=lambda q: q.data == "ping")
def on_ping(query):
bot.answer_callback_query(query.id, "Понг!", show_alert=True)
bot.polling()
Больше примеров — в examples/.
Обработчики
Проверяются в порядке объявления, срабатывает первый подошедший. Поэтому общий обработчик («на любое сообщение») ставят последним — иначе он перехватит команды.
@bot.message_handler(commands=["help", "start"]) # /help или /start
@bot.message_handler(content_types=["photo"]) # только картинки
@bot.message_handler(regexp=r"\d{4}") # текст по регулярке
@bot.message_handler(func=lambda m: m.body == "Меню") # произвольное условие
@bot.message_handler() # всё остальное
Кнопки
| Класс | Где рисуется | Что приходит боту |
|---|---|---|
InlineKeyboardMarkup |
под сообщением | callback_query с data |
ReplyKeyboardMarkup |
вместо системной клавиатуры | обычное сообщение с текстом клавиши |
ReplyKeyboardRemove |
— | снимает клавиатуру |
ForceReply |
— | открывает поле ввода в режиме ответа |
У inline-кнопки ровно одно действие: callback_data, url, web_app, copy_text или
switch_inline_query_current_chat. Это проверяется при сборке — не в момент отправки.
web_app открывает страницу внутри чата и передаёт ей подписанные данные о том, кто её открыл.
На каждое нажатие нужно ответить answer_callback_query, даже пустым текстом: до ответа кнопка
у человека остаётся в состоянии ожидания.
Методы
Сообщения: send_message (с parse_mode), reply_to, send_photo, send_video, send_voice,
send_document, send_sticker, send_video_note, send_animation, send_media_group,
send_location, send_venue, send_poll, send_dice, send_chat_action, forward_message,
copy_message, edit_message_text, edit_message_caption, edit_message_reply_markup,
delete_message.
Бот: get_me, get_updates, answer_callback_query, set_my_commands, set_my_description,
set_my_short_description, set_webhook, delete_webhook.
Группы: get_chat, get_chat_member, get_chat_administrators, ban_chat_member,
promote_chat_member, set_chat_title, set_chat_photo, leave_chat.
Звёзды: send_invoice, answer_pre_checkout_query, refund_star_payment.
Файл передаётся ссылкой (send_photo(chat_id, "https://…/pic.jpg")) или сам —
send_photo(chat_id, InputFile("chart.png")), InputFile(pdf_bytes, name="счёт.pdf").
Непрозрачного file_id, как в Telegram, здесь нет: в ответе всегда стоит адрес.
Обработчики
@bot.message_handler(commands=["start"]) # сообщение
@bot.edited_message_handler() # человек поправил своё сообщение
@bot.callback_query_handler() # нажали кнопку
@bot.pre_checkout_query_handler() # вопрос перед списанием звёзд
@bot.my_chat_member_handler() # бота добавили в беседу или выгнали
Оплата звёздами
@bot.message_handler(commands=["buy"])
def buy(message):
bot.send_invoice(message.chat.id, "Подписка", "Месяц доступа", payload="sub-1", amount_stars=120)
@bot.pre_checkout_query_handler()
def checkout(query):
# ⚠️ Ответить нужно за десять секунд: человек смотрит на крутилку, без ответа платёж отменится.
bot.answer_pre_checkout_query(query.id, ok=True)
Звёзды получает ВЛАДЕЛЕЦ бота: у самого бота кошелька нет. Возврат — refund_star_payment.
Опрос и вебхук
bot.polling() — long-poll: сервер держит запрос до 25 секунд и отвечает сразу, как только
появляется обновление. Обрыв сети переживается с нарастающей паузой; отказ сервера (неверный токен)
останавливает бота с исключением — это ошибка, которую нужно увидеть, а не пережить.
Вебхук — альтернатива, а не дополнение: пока он задан, getUpdates отвечает отказом.
bot.set_webhook("https://example.com/hook", secret_token="…")
Unixgram шлёт POST с телом {"update_id": …, "message": {…}} и заголовком
X-Unixgram-Bot-Api-Secret-Token. Проверяйте его — иначе адрес вебхука сам по себе становится
способом слать боту что угодно.
Чем отличается от Bot API Telegram
chat_idличного чата равен идентификатору собеседника, как в Telegram; принимается также@ник. Идентификаторы — целые числа (у групп отрицательные), как и там.file_id— это адрес файла, а не непрозрачный идентификатор;getFileза ненадобностью нет.ban_chat_memberисключает из группы, но не банит: списка забаненных в Unixgram нет.- Права администратора одни на всех:
promote_chat_memberдаёт роль целиком. - Платежи только в звёздах, платёжных провайдеров нет. Инлайн-режима нет.
Другой адрес сервера
bot = Bot(token, base_url="http://localhost:3000")
Можно не этой библиотекой
Bot API Unixgram совместим с готовыми библиотеками для Telegram — бот переносится заменой адреса сервера. Для aiogram:
from aiogram import Bot
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer
URL = "https://unixgram.com"
session = AiohttpSession(
api=TelegramAPIServer(base=f"{URL}/api/bot/{{token}}/{{method}}", file=f"{URL}/api/bot/file/{{path}}")
)
bot = Bot(token="<токен>", session=session)
Рабочий пример — docs/bots/examples/aiogram_bot.py: тот же мини-бот, что и examples/mini_bot.py,
но без единой строки из unixgram (и лежит он вне этой библиотеки — aiogram к ней отношения не имеет). Эта библиотека остаётся ради одного: ноль зависимостей.
Metadata
Release files for unixgram-py 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| unixgram_py-1.0.0.tar.gz | 27.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unixgram_py-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.4 kB
Release files / unixgram_py-1.0.0.tar.gz
| Download URL | unixgram_py-1.0.0.tar.gz |
|---|---|
| Size | 27.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
03c5b5801cea0ecbe5bb08ff81cc6f4e68d0d19ca6d36366a3c9c5e50deb390c
|
|
BLAKE2b-256 checksum How to use checksums |
1431d3c61b47c671a5efb5cf0293ef13a09420e0cd2147115c6abcf620f49500
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.0
|
Release files / unixgram_py-1.0.0-py3-none-any.whl
| Download URL | unixgram_py-1.0.0-py3-none-any.whl |
|---|---|
| Size | 21.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c8510766462376e63b38aaf9d0729dd17f17fea12e830f1d9d07d398d03d5a0d
|
|
BLAKE2b-256 checksum How to use checksums |
a85d1f8923e90ca9b505c5e275ae79dd852968221e553568947e3144839cbde2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.0
|
Security for unixgram-py 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.