Эта статья о том, как создать Telegram-бот для автоматизации нескольких рутинных задач. Если вас интересует только код, то вот ссылка. Он несложный, и его вполне можно понять самостоятельно.
Это совсем не тупо, но мне кажется, надо пояснить. Всю дорогу по ходу учебы мне нужно было отправлять кучу писем, и все они должны были быть определенного формата. К тому же gmail просто бесит, он красный и все такое! При помощи бота я смогу отправлять письма через чат. Я просто пишу в чат, а бот пусть форматирует это и отправляет по мейлу.
Я очень много использую Telegram и часто натыкаюсь там на интересные для меня ссылки или просто на полезную информацию. Хотелось бы, чтобы бот сохранял все то, что я ему пересылаю, в базе данных SQL.
Для API Telegram есть оболочки практически на любом языке программирования. Начиная от Python, PHP и Java и заканчивая Node.js. Мы, разумеется, будем использовать Python. Код данной оболочки находится здесь, можете убедиться сами. Также можно поучаствовать в развитии данного проекта (если сможете, конечно). Оболочки для других языков можно найти здесь.
Создание Telegram-бота это весьма забавный процесс так как, собственно, весь он строится на вашем общении с Telegram-ботом. Зовут этого бота BotFather (Бот-Отец). В приложении Telegram его можно найти по имени и начать с ним беседу.
Для начала беседы наберите /start
.
Вы увидите список команд, при помощи которых можно создавать боты, редактировать их и управлять ними. Так как мы зашли в первый раз, то выбираем /newbot
.
После введения команды /newbot
вам предстоит выбрать имя и ник (username) для вашего бота. Имя — это то, как пользователи будут видеть этого бота в своем контакт-листе. А ник — имя, по которому этот бот можно будет найти в приложении Telegram. Это то же самое как и ник в Twitter, он должен быть уникальным, и чем короче, тем лучше.
Сделав это, вы получите API-ключ для вашего бота. С помощью него Telegram сможет ассоциировать написанный вами код именно с этим конкретным ботом. У каждого бота есть свой API- ключ, и вы не должны им ни с кем делиться. В противном случае ваш бот можно будет взломать и осуществить злодейские планы.
Начнем с того, что импортируем все необходимое.
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, ConversationHandler from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove import logging import sqlite3 from mail import send_mail from sensitive import tok, user_id, name, username
Предназначение библиотек logging
и sqlite3
вполне видно из их названий. Они будут использоваться для логирования и сохранения всего, что нам потребуется. В файле sensitive
содержаться мои учетные данные, а в telegram.ext
хранятся все необходимые обработчики.
Updater
— это класс, в котором используется telegram.ext.Dispatcher. Он предоставляет интерфейс для telegram.Bot, чтобы можно было сосредоточиться исключительно на программировании бота. Его цель — получать обновления от Telegram и доставлять их указанному диспетчеру. Он также запускается в отдельном потоке, поэтому пользователь может взаимодействовать с ботом, например, из командной строки. Диспетчер поддерживает обработчики для различных типов данных: обновления от Telegram, основные текстовые команды и даже произвольные типы. Класс Updater
может быть использован как служба опроса, а для получения обновлений можно использовать вебхук (webhook). Это достигается с помощью классов WebhookServer
и WebhookHandler
.
CommandHandler
— это класс для обработки команд Telegram. Команды — это сообщения Telegram, начинающиеся с /
, за которыми, возможно, следует символ @
, имя бота и / или дополнительный текст.
MessageHandler
— класс для обработки Telegram-сообщений. Они могут содержать текст, различные медиафайлы или обновления статуса.
ConversationHandler
— это класс для ведения диалога с одним пользователем путем управления четырьмя коллекциями других обработчиков. Обратите внимание, что ни сообщения в каналах Telegram, ни групповые взаимодействия с несколькими пользователями не управляются экземплярами данного класса.
Для каждой команды написана отдельная функция. А все остальное — для работы с SQL и строками.
TOKEN = tok # Enable logging logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO) logger = logging.getLogger(__name__) TO, SUBJECT, MESSAGE = range(3) # Define a few command handlers. These usually take the two arguments bot and # update. Error handlers also receive the raised TelegramError object in error. def start(bot, update): """Send a message when the command /start is issued.""" user = update.message.from_user send = f"{user.username} started your bot. \n First name {user.first_name} \n ID:{user.id}" bot.send_message(chat_id=user_id, text=send) update.message.reply_text('Hi!') def help(bot, update): """Send a message when the command /help is issued.""" update.message.reply_text('COMMANDS \n /view_events@eventattendbot \n /add_event@eventattendbot \n ' '/remove_event@eventattendbot \n') def add_event(bot, update): message = update.message.text link = message.split()[1] user = update.message.from_user['username'] with sqlite3.connect("events.db") as con: conn = con.cursor() # conn.execute('''CREATE TABLE EVENT # (ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, # LINK TEXT NOT NULL);''') conn.execute("INSERT INTO EVENT (LINK) VALUES (?)", (link, )); con.commit() update.message.reply_text("@" + str(user) + ' Added An Event Link!') def remove_event(bot, update): message = update.message.text link = message.split()[1] user = update.message.from_user['username'] with sqlite3.connect("events.db") as con: conn = con.cursor() conn.execute("DELETE FROM EVENT WHERE LINK=?", (link,)) con.commit() update.message.reply_text("@" + str(user) + ' Deleted An Event Link!') def view_events(bot, update): with sqlite3.connect("events.db") as conn: cur = conn.cursor() cur.execute("SELECT * FROM EVENT ORDER BY ID DESC") all = cur.fetchall() links = " LINKS \n\n" for a in range(len(all)): link = all[a][1] links += str((a+1)) + ". " + str(link) + "\n\n" links += "\n\n" update.message.reply_text(links) def error(bot, update, error): """Log Errors caused by Updates.""" logger.warning('Update "%s" caused error "%s"', update, error)
Иметь дело с электронной почтой несколько сложнее (на самом деле нет — если вы используете ConversationHandler
). Чтобы полностью понять идею того, как значения из одной функции передаются другую и в ней обрабатываются, прочитайте вот это.
def email(bot, update): id = update.message.from_user.id if id == user_id and update.message.from_user.first_name == name and update.message.from_user.username == username: update.message.reply_text("Give me an email address", reply_markup=ReplyKeyboardMarkup([['arushssdkbva91@gmail.com']], one_time_keyboard=True)) return TO def to(bot, update, user_data): user = update.message.from_user key = f"{user.id} to" value = update.message.text user_data[key] = value logger.info("email request by %s to %s", user.first_name, update.message.text) update.message.reply_text("Now, the Subject for the email", reply_markup=ReplyKeyboardRemove()) return SUBJECT def subject(bot, update, user_data): user = update.message.from_user key = f"{user.id} subject" value = update.message.text user_data[key] = value logger.info("email subject %s", update.message.text) update.message.reply_text("Now, the Body for the email") return MESSAGE def body(bot, update, user_data): user = update.message.from_user logger.info("email body %s", update.message.text) email_to = user_data[f"{user.id} to"] email_subject = user_data[f"{user.id} subject"] send_mail(email_to, email_subject, update.message.text) del user_data[f"{user.id} to"] del user_data[f"{user.id} subject"] update.message.reply_text(f"email sent!") return ConversationHandler.END def cancel(bot, update): update.message.reply_text('Canceled.') return ConversationHandler.END
Как вы могли заметить, функцию send_mail()
я импортировал из модуля mail
. Для отправки почтовых сообщений используется протокол SMTP.
def send_mail(to, subject, body, my=me): smt = smtplib.SMTP('smtp.gmail.com', 587) smt.ehlo() smt.starttls() smt.login(user=my, password=pwd) sub = subject body = body message = "Subject: " + sub + "\n" + body + "\n" smt.sendmail(my, to, message) smt.quit()
Разумеется, для отправки электронной почты через протокол SMTP вы должны иметь имя пользователя и пароль. Вот хорошее пособие на данную тему.
Вообще-то нет. Вам еще осталось все это запустить.
def main(): """Start the bot.""" updater = Updater(TOKEN) dp = updater.dispatcher dp.add_handler(CommandHandler("start", start)) dp.add_handler(CommandHandler("help", help)) dp.add_handler(CommandHandler("add_event", add_event)) dp.add_handler(CommandHandler("view_events", view_events)) dp.add_handler(CommandHandler("remove_event", remove_event)) email_handler = ConversationHandler( entry_points=[CommandHandler('email', email)], states={ TO: [MessageHandler(Filters.text, to, pass_user_data=True)], SUBJECT: [MessageHandler(Filters.text, subject, pass_user_data=True)], MESSAGE: [MessageHandler(Filters.text, body, pass_user_data=True)] }, fallbacks=[CommandHandler('cancel', cancel)] ) dp.add_handler(email_handler) dp.add_error_handler(error) updater.start_polling() updater.idle()
Для размещения кода существует множество способов. Выбор зависит от того, как и насколько много вы будете этот код использовать.
Вот здесь также собраны инструкции по размещению Telegram-ботов.
Python предлагает набор библиотек, удовлетворяющих различные потребности в визуализации, будь то академические исследования, бизнес-аналитика или…
В Python для представления данных в двоичной форме можно использовать байты. Из этой статьи вы…
В этой статье рассказывается о том, что такое Werkzeug и как Flask использует его для…
При работе с датами часто возникает необходимость прибавлять к дате или вычитать из нее различные…
В этом руководстве мы рассмотрим, как добавить социальную аутентификацию с помощью GitHub и Google в…
В этой статье мы рассмотрим, что такое подсказки типов и чем они могут быть полезны.…