В этой статье я расскажу о том, как не будучи кодером, писал себе бота для телеграмма. Для начала - немного предыстории. Собственно, она довольно короткая.
Моя позиция следующая: В мессенджеры надо писать буковки!
Лично мне очень не нравятся голосовые сообщения и люди, которые их постоянно используют. Для меня - это просто не удобно, не всегда есть наушники, для того чтоб прослушать присланное сообщение (слушать, через динамики, то, что тебе прислали в личку - вообще не приемлемо), не всегда бывает его вообще слышно (например в транспорте, или на улице)... Это долго, в конце-то концов. Гораздо проще и быстрее прочитать присланные буковы, чем слушать все эти *эээээ*, *мммм*, *чмчавк* и шум на фоне.
Каждое присланное мне голосовое сообщение напрягало меня все больше и больше. И вот, наконец, я не выдержал и решил написать себе бота, который будет всю эту неприятность переводить.
В качестве языка программирования был выбран питон, т.к. на нем я хоть что-то могу написать, а в качестве площадки для бота - телеграмм, т.к. api телеграмма для ботов имеет довольно низкий порог вхождения.
Ну что ж, для начала следует определиться с используемыми библиотеками и импортировать их:
Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import telebot
import requests
import speech_recognition as sr
import subprocess
import datetime
Со стандартными "os", "requests", "subprocess" и "datetime" все понятно.
telebot - это пакет, который предоставляет чистый интерфейс Python для
Ссылка скрыта от гостей
.Библиотека Speech Recognition — это, инструмент для передачи речевых API от компаний (google, microsoft, и др.), который в отличие от остальных имеет возможность работы офлайн. Именно Speech Recognition и будет использоваться для распознавания речи.
Еще будет использоваться ffmpeg. Как гласит описание с википедии - это набор свободных библиотек с открытым исходным кодом, которые позволяют записывать, конвертировать и передавать цифровые аудио- и видеозаписи в различных форматах. А устанавливается это чудо простым
sudo apt-get install ffmpeg
Теперь создадим пару нужных переменных:
Python:
logfile = str(datetime.date.today()) + '.log' # формируем имя лог-файла
token = 'ваш_токен' # Обратите внимание, что хранить токены в коде - не хорошо, здесь эта строка только для примера
bot = telebot.TeleBot(token)
Но, прежде, чем что-там преобразовывать, надо это что-то получить. Надо набросать функцию для получения голосовух. Она будет принимать только голосовые сообщения, на другие она реагировать не будет.
Я постарался закомментировать вообще все, что можно в этой функции, вместо того, чтобы прерываясь, постоянно разбирать каждую строчку кода.
Python:
@bot.message_handler(content_types=['voice'])
def get_audio_messages(message):
# Основная функция, принимает голосовуху от пользователя
try:
print("Started recognition...")
# Ниже пытаемся вычленить имя файла, да и вообще берем данные с мессаги
file_info = bot.get_file(message.voice.file_id)
path = file_info.file_path # Вот тут-то и полный путь до файла (например: voice/file_2.oga)
fname = os.path.basename(path) # Преобразуем путь в имя файла (например: file_2.oga)
doc = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(token, file_info.file_path)) # Получаем и сохраняем присланную голосвуху (Ага, админ может в любой момент отключить удаление айдио файлов и слушать все, что ты там говоришь. А представь, что такую бяку подселят в огромный чат и она будет просто логировать все сообщения [анонимность в телеграмме, ахахаха])
with open(fname+'.oga', 'wb') as f:
f.write(doc.content) # вот именно тут и сохраняется сама аудио-мессага
process = subprocess.run(['ffmpeg', '-i', fname+'.oga', fname+'.wav'])# здесь используется страшное ПО ffmpeg, для конвертации .oga в .vaw
result = audio_to_text(fname+'.wav') # Вызов функции для перевода аудио в текст
bot.send_message(message.from_user.id, format(result)) # Отправляем пользователю, приславшему файл, его текст
except sr.UnknownValueError as e:
# Ошибка возникает, если сообщение не удалось разобрать. В таком случае отсылается ответ пользователю и заносим запись в лог ошибок
bot.send_message(message.from_user.id, "Прошу прощения, но я не разобрал сообщение, или оно поустое...")
with open(logfile, 'a', encoding='utf-8') as f:
f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) + ':Message is empty.\n')
except Exception as e:
# В случае возникновения любой другой ошибки, отправляется соответствующее сообщение пользователю и заносится запись в лог ошибок
bot.send_message(message.from_user.id, "Что-то пошло через жопу, но наши смелые инженеры уже трудятся над решением... \nДа ладно, никто эту ошибку исправлять не будет, она просто потеряется в логах.")
with open(logfile, 'a', encoding='utf-8') as f:
f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) +':' + str(e) + '\n')
finally:
# В любом случае удаляем временные файлы с аудио сообщением
os.remove(fname+'.wav')
os.remove(fname+'.oga')
bot.polling(none_stop=True, interval=0)# Очень не культурно стучимся к телеге и проверяем наличие сообщений
Ну и сама функция конвертации аудио в текст:
Python:
def audio_to_text(dest_name: str):
# Функция для перевода аудио, в формате ".vaw" в текст
r = sr.Recognizer() # такое вообще надо комментить?
# тут мы читаем наш .vaw файл
message = sr.AudioFile(dest_name)
with message as source:
audio = r.record(source)
result = r.recognize_google(audio, language="ru_RU") # используя возможности библиотеки распознаем текст, так же тут можно изменять язык распознавания
return result
Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import telebot
import requests
import speech_recognition as sr
import subprocess
import datetime
logfile = str(datetime.date.today()) + '.log'
token = 'ваш_токен'
bot = telebot.TeleBot(token)
def audio_to_text(dest_name: str):
# Функция для перевода аудио , в формате ".vaw" в текст
r = sr.Recognizer() # такое вообще надо комментить?
# тут мы читаем наш .vaw файл
message = sr.AudioFile(dest_name)
with message as source:
audio = r.record(source)
result = r.recognize_google(audio, language="ru_RU") # здесь можно изменять язык распознавания
return result
@bot.message_handler(content_types=['voice'])
def get_audio_messages(message):
# Основная функция, принимает голосовуху от пользователя
try:
print("Started recognition...")
# Ниже пытаемся вычленить имя файла, да и вообще берем данные с мессаги
file_info = bot.get_file(message.voice.file_id)
path = file_info.file_path # Вот тут-то и полный путь до файла (например: voice/file_2.oga)
fname = os.path.basename(path) # Преобразуем путь в имя файла (например: file_2.oga)
doc = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(token, file_info.file_path))# Получаем и сохраняем присланную голосвуху (Ага, админ может в любой момент отключить удаление айдио файлов и слушать все, что ты там говоришь. А представь, что такую бяку подселят в огромный чат и она будет просто логировать все сообщения [анонимность в телеграмме, ахахаха])
with open(fname+'.oga', 'wb') as f:
f.write(doc.content) # вот именно тут и сохраняется сама аудио-мессага
process = subprocess.run(['ffmpeg', '-i', fname+'.oga', fname+'.wav'])# здесь используется страшное ПО ffmpeg, для конвертации .oga в .vaw
result = audio_to_text(fname+'.wav') # Вызов функции для перевода аудио в текст, а заодно передаем имена файлов, для их последующего удаления
bot.send_message(message.from_user.id, format(result))
except sr.UnknownValueError as e:
bot.send_message(message.from_user.id, "Прошу прощения, но я не разобрал сообщение, или оно поустое...")
with open(logfile, 'a', encoding='utf-8') as f:
f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) + ':Message is empty.\n')
except Exception as e:
bot.send_message(message.from_user.id, "Что-то пошло через жопу, но наши смелые инженеры уже трудятся над решением... \nДа ладно, никто эту ошибку исправлять не будет, она просто потеряется в логах.")
with open(logfile, 'a', encoding='utf-8') as f:
f.write(str(datetime.datetime.today().strftime("%H:%M:%S")) + ':' + str(message.from_user.id) + ':' + str(message.from_user.first_name) + '_' + str(message.from_user.last_name) + ':' + str(message.from_user.username) +':'+ str(message.from_user.language_code) +':' + str(e) + '\n')
finally:
os.remove(fname+'.wav')
os.remove(fname+'.oga')
bot.polling(none_stop=True, interval=0)# Очень не культурно стучимся телеге и проверяем наличие сообщений
Работает вся эта адская машина следующим образом:
- Пользователь посылает/пересылает голосовое сообщение боту
- Бот шаманит
- Бот посылает пользователю переведенное сообщение
P.S. Бот работает с довольно высокой точностью, переводя даже длинные сообщения, зацензуривая при этом не приличные слова. Так же бот работает, как на линухе, так и на винде.
Собственно, вот и все... Лично меня результат вполне устраивает. А как вам? Пишите, что можно улучшить, или поменять, с радостью все выслушаю и учту. И еще раз напоминаю, что с питоном я работаю на уровне "набросать говноскрипт, лишь бы работал", так что не кидайте сильно камнями, если что не так)
Ну и разумеется, спасибо, что дочитали эту статью до конца.
Последнее редактирование модератором: