Недавно Boomburum писал о своих лайфхаках в Телеграме. Вместо "Избранного" он использует несколько приватных каналов с самим собой — для разделения на категории. И делаю точно так же.
Это удобно: в Телеграме всегда можно что-то быстро записать или переслать из других чатов. Получается такой простой способ вести повседневные заметки "на бегу".
Но повседневный список задач так вести не получится. Или всё-таки?
Вообще списки todo — это такая полезная штука, которая легко реализуется. Если вы введёте слово "todo" в поиск в Google Play или AppStore, то увидите ооочень много приложений.
Неудивительно, что в Телеграме уже есть боты для ведения этих самых todo. Но вот проблема: в Телеграме нету чекбоксов. Вы в принципе не можете сделать кнопку-галочку рядом с текстом. Ну нельзя так сделать.
Поэтому все выкручиваются, как могут.
Один из юзабельных вариантов, которые я нашёл — ставить галочку при клике на команду.
В некоторых ботах задачи сделаны в виде кнопок.
В принципе — да, таких ботов можно использовать повседневно, на ходу. Хотя переключаться между списками не так удобно, как в приложениях (тут для этого придётся скроллить сообщения вверх-вниз).
Но проблема заключается в том, что это совсем не гибко. Всё, что ты можешь дать задаче — это короткое название. Не получится добавить даты, большое описание или картиночку для красоты.
И вот однажды я подумал: а что, если сделать задачу одним сообщением? А снизу поместить кнопку. Вот так:
Боты могут добавлять сообщения к сообщениям пользователя — если это сообщения в канале. Так работают лайки в каналах: авторы публикуют сообщения, а боты редактируют, добавляя кнопки.
Итак, мы можем совместить идею с личными каналами для заметок и идею бота.
Создаём приватный канал и добавляем туда только бота.
Каждое сообщение в канале — это пункт todo.
Всё, что будет делать бот — это добавлять кнопки, а по нажатию на них изменять сообщения. Полторы строчки кода.
Код
Я привык писать ботов на Telethon, так что у меня получилось что-то такое:
import logging
from telethon import TelegramClient, Button, events
from telethon.errors import ChatAdminRequiredError, MessageIdInvalidError, InlineBotRequiredError
bot = TelegramClient('bot', config.API_ID, config.API_HASH)
logging.basicConfig(level=logging.INFO)
bot.parse_mode = 'html'
@bot.on(events.NewMessage(func=lambda e: e.is_channel))
async def new_channel_message(event: Message):
try:
await bot.edit_message(event.chat, event.id, buttons=Button.inline('✔️ Выполнить', '0_done'))
except (ChatAdminRequiredError, MessageIdInvalidError, InlineBotRequiredError):
# Если бот не админ в чате, или если сообщение невозможно изменить (например, это стикер или сообщение через инлайн-бота)
pass
@bot.on(events.CallbackQuery(pattern='(done|undone)'))
async def done_callback_query(event):
source = (await event.get_message()).text.replace('~~', '')
if event.data == b'done':
text = f'✅ {source}' if source else '✅'
buttons = Button.inline('Выполнено', 'undone')
await event.edit(text, buttons=buttons, parse_mode=parse_mode)
else:
if source.startswith('<del>') and source.endswith('</del>'):
source = source[5:-6]
text = None if not source else source[1:] if source.startswith('✅') else source
buttons = Button.inline('✔️ Выполнить', 'done')
await event.edit(text, buttons=buttons)
if __name__ == '__main__':
bot.start(bot_token=BOT_TOKEN)
bot.run_until_disconnected()
И казалось бы — по сути этот способ вести todo ничем не отличается от других. Но внезапно сам Телеграм открывает нам кучу возможностей:
Задачей в списке может быть всё, что угодно — всё, что позволил Дуров. Можно добавлять картинки и описания. Можно вообще вместо текста оставлять голосовые сообщения. Или стикеры О_о
Создать несколько каналов. Каждый канал может быть отдельным списком. Можно дать им любые названия. А ещё поставить аватарки, чтобы их было легко различать. Можно закреплять каналы в списке чатов или создавать папки с этими каналами.
Добавить участников в канал. В этот "список задач" можно добавлять участников — и это не баг, а фича. А если включите подписи к сообщениям, то будете видеть, кто именно отправил каждое сообщение.
Привязать канал к рабочему чату. Если привязать канал к чату, то все сообщения из него будут пересылаться в этот чат.
Использовать хештеги. Можно структурировать задачи внутри канала и искать их по хештегам.
В итоге: мы написали полторы строчки кода, и за счёт встроенных средств Телеграма получили супергибкие todo-списки. Почти что нативные.
И ведь могут найтись ещё какие-нибудь интересные трюки с этим ботом, до которых я не додумался.
Кстати, можно ещё чуть-чуть дополнить код и сделать проверку на администратора: пусть админы каналов смогут ставить галочки, а подписчики — только читать.
Если что, бота, который у меня получился, вы можете потыкать здесь.