Telegram bot python как написать определенному пользователю
Перейти к содержимому

Telegram bot python как написать определенному пользователю

  • автор:

 

Пишем диалоговые Telegram-боты на Питоне

Думаю, всем здесь в той или иной мере известен мессенджер Telegram. Создатель заявляет, что это самый безопасный мессенджер с убойным алгоритмом шифрования собственной разработки, но нас, разработчиков, конечно же, куда сильнее интересует другое. Боты!

Тема эта, конечно, не раз поднималась на Хабре: ботов писали на Python с tornado, Node.js, Ruby со специальным гемом, Ruby on Rails, C#, C# с WCF и даже PHP; ботов писали для RSS-каналов, мониторинга сайтов, удалённого включения компьютера и, вероятно, для многого, многого другого.

И всё же я возьму на себя смелость изъездить эту тему ещё раз и вдобавок к этому показать немного магии Питона. Мы будем писать фреймворк™ для удобного написания нетривиальных диалоговых ботов на основе пакета python-telegram-bot.

Как зачать бота?

На этот вопрос лучше всего отвечает официальная документация. Выглядит процесс примерно так:

Просто, не правда ли? (Будьте благоразумны и не занимайте хорошие никнеймы без убедительной причины!)

Самый простой бот

Сперва глянем в туториал нашего базового пакета, чтобы понять, с чего начинается простенький бот. Следующий код

создаёт бота, который сухо отвечает «Здравствуйте.» при нажатии на кнопку Start (или ручном вводе команды /start ) и многозначительно молчит при любых последующих действиях с вашей стороны.

Соответственно, если мы захотим повесить обработчики любых текстовых сообщений или любых команд, нам нужно будет написать

(За дальнейшими подробностями с чистой совестью отсылаю к документации python-telegram-bot.)

Нагруженные этим теоретическим минимумом, мы можем наконец подумать, как нам писать своего нетривиального бота. Для начала давайте вернёмся к постановке задачи. Под диалоговым ботом я подразумеваю бота, который главным образом ведёт обычный текстовый диалог с пользователем — с вопросами, ответами, нелинейным сюжетом, разочаровывающими концовками и всем в таком духе (играли в «Бесконечное лето»?) Напротив, не попадают в сферу наших текущих интересов боты, разным образом расширяющие функционал Telegram (вроде бота для лайков); соответственно, мы опустим добавление всяких плюшек вроде инлайнового режима, игр, обновления элементов управления на лету и всего такого прочего.

Проблема сложных диалоговых ботов в том, что нетривиальный диалог требует хранения состояния. Работа асинхронных диалогов требует постоянных прерываний на ожидание сообщения от пользователя; состояние нужно сохранять, потом восстанавливать, прыгать к коду, ответственному за обработку очередного сообщения, и так далее; в общем, организация кода становится проблемой довольно угнетающей. Прервать, продолжить… ничего не напоминает? Что ж, посмотрим, как обозначенную проблему можно изящнейше обойти с помощью магии yield .

50 оттенков yield

Что мы знаем про yield ? Ну, все мы знаем, что это такая штука, чтобы писать генераторы, то есть этакие ленивые и потенциально бесконечные списки:

Теперь объект f — это такая волшебная коробка; стоит сунуть в неё руку написать next(f) , и мы получим очередное число Фибоначчи, но стоит перевернуть её написать list(f) , как мы уйдём в бесконечный цикл, который, скорее всего, закончится трагической смертью системы от нехватки оперативной памяти.

Мы знаем, что генераторы — это быстро, удобно и очень в стиле Python. У нас есть модуль itertools , предлагающий генераторы на любой вкус и цвет. Но у нас есть кое-что ещё.

Куда менее известными навыками слова yield являются способности… возвращать значения и бросать исключения! Да-да, если мы напишем:

То вычисление чисел Фибоначчи оборвётся самым трагическим образом — исключением в строчке с yield .

В свою очередь вызов f.send(something) заставит конструкцию yield вернуть значение, а потом сразу вернёт next(f) . Достаточно приравнять yield переменную, чтобы переданное значение поймать:

Но и это ещё не всё. Начиная с Python 3.3, генераторы умеют делегировать выполнение друг другу с помощью конструкции yield from : вместо

она позволяет нам писать

Но было бы преуменьшением сказать, что yield from позволяет нам лишь сэкономить строки кода на циклах. Дело в том, что она также заботится о send и throw — при вызове они будут взаимодействовать не с функцией concatenate , а с одним из двух генераторов, которым она передаёт управление. (Если это окажутся не генераторы… ну упс.)

А ещё yield from тоже умеет возвращать значение: для этого функциям-генераторам вернули право на нетривиальный (то есть возвращающий что-то, а не просто заканчивающий выполнение) return :

К чему я всё это? Ах да. Эти фокусы, вместе взятые, позволят нам легко и естественно писать наших диалоговых ботов.

 

Пишем обёртку

Итак, пусть диалог с каждым пользователем ведётся генератором. yield будет выдавать наружу сообщение, которое надо отправить пользователю, и возвращать внутрь его ответ (как только он появится). Давайте напишем простенький класс, который умеет это делать.

Что ж, осталось сочинить диалог, который мы будем отыгрывать! Давайте поговорим о Питоне.

И это работает! Результат выглядит примерно так:

Добавляем разметку

Боты в Telegram сильны тем, что могут кидаться в своих пользователей HTML- и Markdown-разметкой; эту возможность обойти стороной нам было бы непозволительно. Чтобы понять, как послать сообщение с разметкой, давайте взглянем на описание функции Bot.sendMessage :

Ага! Достаточно передавать аргумент parse_mode=»HTML» или parse_mode=»Markdown» . Можно было бы просто добавить это в наш вызов, но давайте сделаем чуть-чуть погибче: добавим специальные объекты, которые нужно будет yield’ить, чтобы спровоцировать использование разметки:

Теперь отправка сообщений будет выглядеть так:

Для демонстрации давайте модифицируем ask_yes_or_no() :

Добавляем кнопки

Единственное, чего нам не хватает и что могло бы вполне себе пригодиться при написании диалоговых ботов — клавиатура с выбором вариантов ответа. Для создания клавиатуры нам достаточно добавить в Message.options ключ reply_markup ; но давайте постараемся максимально упростить и абстрагировать наш код внутри генераторов. Здесь напрашивается решение попроще. Пусть, например, yield выдаёт не один объект, а сразу несколько; если среди них есть список или список списков со строками, например:

, то мы считаем, что это кнопки клавиатуры, и хотим получить примерно следующий результат:

_send_answer() тогда преобразуется в нечто такое:

В качестве демонстрации поменяем ask_yes_or_no() и discuss_bad_python() :

Заключение

Генераторы в Питоне — мощный инструмент, и использование его в нужных ситуациях позволяет значительно сокращать и упрощать код. Посмотрите, как красиво мы, например, вынесли вопрос «да или нет» в отдельную функцию, притом оставив за ним право проводить дополнительное общение с пользователем. Так же мы могли бы вынести в отдельную функцию и вопрошание имени, и научить его уточнять у пользователя, верно ли мы его поняли, и так далее, и тому подобное. Генераторы сами хранят за нас состояние диалога, и сами умеют продолжать его с требуемого момента. Всё для нас!

Надеюсь, эта статья была кому-то полезной. Как водится, не стесняйтесь сообщать обо всех опечатках, орфографических и грамматических ошибках в личку. Весь код к статье лежит в репозитории на Github (ветка habrahabr-316666 ). На бота ссылку не дам и живым его держать, конечно, ближайшее время не буду, иначе хабраэффект накроет его вместе с моим компьютером. Успехов в создании своих диалоговых ботов ��

Как написать Telegram бота отправляющий сообщения другому пользователю на Python?

Мне надо написать телеграм-бота на python который отправляет сообщения определённому пользователю который запустил бота. Если кто знает как это сделать то напишите пожалуйста, заранее спасибо!

Телеграм бот может написать только тем пользователям, которые сами начали с ним взаимодействовать. В этот момент начала работы с ботом следует запоминать пользователся, регистрировать у себя в БД и запоминать его user_id.

Когда потребуется написать конкретному пользователю, только логике вашего приложения известно какому, то достаёте этот user_id из БД и шлёте ему сообщение.

Если Это что-то вроде анонимного чата через бота, то логически делите пользователей на пары (На чаты), где оба user_id кэшируете в памяти приложения или каком-нибудь redis (для отказоустойчивости и адекватной скорости работы с памятью)

Отправить сообщение пользователю Telegram с помощью Python

Вы когда-нибудь задумывались, как люди автоматизируют Telegram? Возможно, вы знаете, что Telegram имеет большую базу пользователей и поэтому является одной из самых популярных социальных сетей для чтения. Что хорошо в Telegram, так это то, что он предоставляет множество методов API, в отличие от Whatsapp, который ограничивает такие вещи. Итак, в этом посте мы расскажем, как отправлять сообщения пользователю Telegram с помощью Python.

Начиная

  • Откройте приложение Telegram и найдите @BotFather.
  • Нажмите кнопку «Пуск» или отправьте «/ start».
  • Затем отправьте сообщение «/ newbot», чтобы указать имя и имя пользователя.
  • После установки имени и имени пользователя BotFather предоставит вам токен API, который является вашим токеном бота.
  • Войдите в ядро телеграммы: https://my.telegram.org
  • Перейдите в «Инструменты разработки API» и заполните форму.
  • Вы получите параметры api_id и api_hash, необходимые для авторизации пользователя.

Необходимые модули

Для работы скрипта вам понадобится несколько импортированных библиотек Python.

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *