1 sdcrmp7jdhash5ksl35kcw
Эта статья о том, как создать 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, на Talanto.work сейчас есть варианты для junior, middle, senior…
Рынок Python-вакансий большой, но удобным его назвать сложно. Формально вакансий много, однако в реальном поиске…
Срезы в Python — это больше, чем a[2:7]. В статье — быстрый разбор полезных приёмов:…
В этой статье мы рассмотрим возведение в степень в Python с помощью различных методов, от…
Дубликаты в списке Python — частая проблема. В статье показано, как быстро убрать повторы, в…
Услуга виртуального хостинга на SpaceWeb позволяет арендовать часть сервера (shared-сервера) и разместить на нём свой…