Python library for Pulse messenger bots. Like aiogram but for Pulse.
Project description
pulsemsg 🤖
Python-библиотека для создания ботов в мессенджере Pulse.
Аналог aiogram, адаптированный под Pulse Bot API.
Установка
pip install pulsemsg
# или из исходников:
pip install -e .
Требования: Python 3.10+, aiohttp
Быстрый старт
1. Создай бота через @botfather в Pulse
Напиши боту @botfather:
/newbot
Следуй инструкциям — получишь токен.
2. Напиши бота
from pulsemsg import Bot, Dispatcher, F, Command, run_polling
from pulsemsg.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
bot = Bot(token="123:ABCDEF...", base_url="https://your-pulse-server.com")
dp = Dispatcher()
@dp.message(Command("start"))
async def cmd_start(msg: Message):
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton("👋 Привет!", callback_data="hello")],
[InlineKeyboardButton("🔗 Сайт", url="https://example.com")],
])
await msg.answer("Выбери действие:", reply_markup=kb)
@dp.callback_query(F.data == "hello")
async def on_hello(cb: CallbackQuery):
await cb.answer("Привет! 👋")
await cb.message.edit_text("✅ Кнопка нажата!")
@dp.message()
async def echo(msg: Message):
await msg.reply(f"🔁 {msg.text}")
if __name__ == "__main__":
run_polling(dp, bot)
Структура библиотеки
pulsemsg/
├── __init__.py — публичное API
├── bot.py — HTTP-клиент Bot
├── dispatcher.py — Dispatcher (polling / webhook)
├── router.py — Router (регистрация хэндлеров)
├── filters.py — F, Command, Text, StateFilter
├── fsm.py — StatesGroup, State, FSMContext
└── types.py — Message, CallbackQuery, InlineKeyboardMarkup, ...
Клавиатуры
InlineKeyboardMarkup
Кнопки появляются прямо под сообщением.
from pulsemsg.types import InlineKeyboardMarkup, InlineKeyboardButton
# Стиль 1 — через конструктор
kb = InlineKeyboardMarkup(inline_keyboard=[
[
InlineKeyboardButton("✅ Да", callback_data="yes"),
InlineKeyboardButton("❌ Нет", callback_data="no"),
],
[InlineKeyboardButton("🔗 Ссылка", url="https://example.com")],
])
# Стиль 2 — через .add()
kb = InlineKeyboardMarkup()
kb.add(InlineKeyboardButton("Кнопка 1", callback_data="btn1"))
kb.add(InlineKeyboardButton("Кнопка 2", callback_data="btn2"))
await msg.answer("Выбери:", reply_markup=kb)
ReplyKeyboardMarkup
Клавиатура под полем ввода.
from pulsemsg.types import ReplyKeyboardMarkup, KeyboardButton
kb = ReplyKeyboardMarkup(resize_keyboard=True)
kb.add(KeyboardButton("📋 Меню"))
kb.add(KeyboardButton("⚙️ Настройки"), KeyboardButton("❓ Помощь"))
await msg.answer("Используй кнопки:", reply_markup=kb)
Фильтры (F)
from pulsemsg import F, Command, Text, StateFilter
# Точное совпадение текста
@dp.message(F.text == "Привет")
# Начинается с...
@dp.message(F.text.startswith("/"))
# По callback_data
@dp.callback_query(F.data == "btn_yes")
@dp.callback_query(F.data.startswith("page:"))
# Команда
@dp.message(Command("start"))
@dp.message(Command("help", "h")) # несколько команд
# Комбинированные фильтры
@dp.message(F.text.startswith("/") & ~F.text.contains("spam"))
# Состояние FSM
@dp.message(StateFilter(MyForm.waiting_name))
FSM (конечный автомат)
from pulsemsg import StatesGroup, State, FSMContext, StateFilter
class OrderForm(StatesGroup):
product = State()
quantity = State()
address = State()
@dp.message(Command("order"))
async def start_order(msg: Message, state: FSMContext):
await state.set_state(OrderForm.product)
await msg.answer("Что хочешь заказать?")
@dp.message(StateFilter(OrderForm.product))
async def got_product(msg: Message, state: FSMContext):
await state.update_data(product=msg.text)
await state.set_state(OrderForm.quantity)
await msg.answer("Сколько штук?")
@dp.message(StateFilter(OrderForm.quantity))
async def got_quantity(msg: Message, state: FSMContext):
await state.update_data(quantity=msg.text)
data = await state.get_data()
await state.clear()
await msg.answer(
f"✅ Заказ оформлен!\n"
f"Товар: {data['product']}\n"
f"Кол-во: {data['quantity']}"
)
Router (модульность)
# admin.py
from pulsemsg import Router, Command, F
admin_router = Router()
@admin_router.message(Command("ban"))
async def ban_user(msg):
await msg.answer("Заблокировал!")
# main.py
from pulsemsg import Dispatcher
from admin import admin_router
dp = Dispatcher()
dp.include_router(admin_router)
Bot API (прямые вызовы)
bot = Bot(token="...", base_url="...")
# Получить информацию о боте
me = await bot.get_me()
# Отправить сообщение
msg = await bot.send_message(chat_id="@username", text="Привет!")
# Редактировать
await bot.edit_message_text(message_id=msg.message_id, text="Изменено")
# Удалить
await bot.delete_message(chat_id, message_id)
# Показать "печатает..."
await bot.send_chat_action(chat_id, action="typing")
# Ответить на кнопку
await bot.answer_callback_query(cb_id, text="OK", show_alert=False)
# Webhook
await bot.set_webhook("https://my-server.com/webhook")
await bot.delete_webhook() # Вернуться к polling
Webhook (FastAPI)
from fastapi import FastAPI, Request
from pulsemsg import Bot, Dispatcher
app = FastAPI()
bot = Bot(token="...", base_url="...")
dp = Dispatcher()
@app.on_event("startup")
async def startup():
await bot.set_webhook("https://my-server.com/webhook/TOKEN")
@app.post("/webhook/{token}")
async def webhook(request: Request, token: str):
if token != bot.token:
return {"error": "Forbidden"}
data = await request.json()
await dp.process_webhook_update(data, bot)
return {"ok": True}
Интеграция с сервером Pulse
Серверная часть (добавить в Pulse)
- Скопировать файлы из
server-patch/в папкуserver/ - Следовать инструкциям в
server-patch/PATCH_INSTRUCTIONS.js
Клиентская часть (React)
Добавить InlineKeyboard.jsx в client/src/components/ и использовать в ChatWindow.jsx:
import InlineKeyboard from './InlineKeyboard';
// В рендере сообщения:
{msg.replyMarkup?.inline_keyboard && (
<InlineKeyboard
keyboard={msg.replyMarkup.inline_keyboard}
messageId={msg._id}
chatId={chatId}
botUserId={msg.sender?._id}
socket={socket}
/>
)}
Примеры
| Файл | Описание |
|---|---|
examples/echo_bot.py |
Эхо-бот с inline-кнопками |
examples/fsm_form_bot.py |
Пошаговая форма регистрации |
Лицензия
MIT © Pulse Team
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pulsemsg-1.0.1.tar.gz.
File metadata
- Download URL: pulsemsg-1.0.1.tar.gz
- Upload date:
- Size: 18.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76494b2dbfa2bcc4ec0b533b4b3b007cf24f588020908f41f4843cd54cf9509c
|
|
| MD5 |
5d1ae97e871835419319336341870d7f
|
|
| BLAKE2b-256 |
c9775a0bd0d3e272e4441969e92d518368b94081c27f6a5541ab58b042091074
|
File details
Details for the file pulsemsg-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pulsemsg-1.0.1-py3-none-any.whl
- Upload date:
- Size: 19.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15d9bb17a285cf8be5f0946a0122f7cc8411e773801d6a5096c2c595bc30185a
|
|
| MD5 |
d7216bbd72abdc6ea262044da3517731
|
|
| BLAKE2b-256 |
0eece3bbdaefa9cd564955845a2dc5e9d8f6d4f61edc6f12b447beeea6fae1ef
|