Обработчики URI¶
CactusLib позволяет создавать специальные ссылки вида tg://cactus/..., которые могут выполнять действия внутри приложения. Это мощный инструмент для создания кастомных взаимодействий.
Существует два типа URI и, соответственно, два декоратора для них.
1. @uri: Глобальные URI¶
Эти ссылки обрабатываются глобально, когда пользователь пытается их открыть (например, при клике в описании профиля).
Декоратор:
@uri("my_action")Формат ссылки:
tg://cactus/{plugin_id}/my_action?arg1=value1Функция-обработчик: Принимает аргументы, указанные в URI, как именованные параметры.
Пример: URI, который показывает уведомление
class MyPlugin(CactusUtils.Plugin):
@uri("notify")
def _on_notify_uri(self, text: str, user: str = "Anonymous"):
# Показываем системное уведомление (bulletin)
self.utils.show_info(f"Уведомление от {user}: {text}")
@command(doc="Генерирует ссылку для уведомления")
def make_link(self, cmd: CactusUtils.Command):
# Создаем URI с помощью утилиты
link = self.utils.Uri.create(self, "notify", text="Hello from URI!", user="Admin")
# link будет "tg://cactus/my_plugin_id/notify?text=Hello+from+URI%21&user=Admin"
self.answer(cmd.params, f"Нажмите на эту ссылку: {link}")
Если пользователь перейдет по сгенерированной ссылке, на экране появится уведомление Уведомление от Admin: Hello from URI!.
2. @message_uri: URI внутри сообщений¶
Это особый тип URI, который работает только внутри сообщений Telegram. Вместо открытия ссылки, он вызывает вашу функцию, передавая ей контекст сообщения. Это похоже на инлайн-кнопки, но в виде обычных текстовых ссылок.
Декоратор:
@message_uri("my_message_action")Формат ссылки:
tg://cactusX/{plugin_id}/my_message_action?arg1=value1(Обратите внимание наcactusX)Функция-обработчик: Первым аргументом принимает объект
CactusUtils.UriCallback, а затем именованные параметры из URI.
Объект CactusUtils.UriCallback¶
cb.message: MessageObject: Объект сообщения, в котором нажали на ссылку.cb.cell: ChatMessageCell: UI-элемент сообщения.cb.edit(text, **kwargs): Редактирует сообщение. АльтернативаCactusUtils.edit_message(cb.message, text, fragment=get_last_fragment(), **kwargs)cb.edit_markup(markup=None): Редактирует Inline-клавиатуру или удаляет её вовсе.cb.delete(): Удаляет сообщение.
Пример: интерактивная ссылка в сообщении¶
class MyPlugin(CactusUtils.Plugin):
@command(doc="Создает сообщение со счетчиком-ссылкой")
def link_counter(self, cmd: CactusUtils.Command):
count = self.get("link_count", 0)
# Создаем ссылку, которая будет вызывать `update_count`
link = self.utils.MessageUri.create(self, "update_count", amount=1)
cmd.answer(f"Счетчик: {count}\n\n<a href='{link}'>Нажми, чтобы увеличить</a>")
return HookResult(strategy=HookStrategy.CANCEL)
@message_uri("update_count")
def _on_update_count(self, cb: CactusUtils.UriCallback, amount: str):
# amount приходит как строка, конвертируем в int
new_count = self.get("link_count", 0) + int(amount)
self.set("link_count", new_count)
# Генерируем новую ссылку
new_link = self.utils.MessageUri.create(self, "update_count", amount=1)
# Редактируем исходное сообщение
cb.edit(f"Счетчик: {new_count}\n\n<a href='{new_link}'>Нажми, чтобы увеличить</a>")
Как это работает:
Пользователь пишет
.link_counter.Плагин отправляет сообщение со ссылкой, ведущей на
tg://cactusX/....При нажатии на ссылку Exteragram не открывает ее, а вызывает метод
_on_update_count.Метод обновляет счетчик и редактирует исходное сообщение, подставляя новое значение и новую ссылку. Создается эффект интерактивного сообщения.