banner

Бот-диетолог под слив на нутру своими руками: часть 1

trafficcardinal написал 29.08.2022
15 мин
1
1434
Содержание
Нутра, и в особенности похудалки с гейнерами («набиралки»), — всегда актуальная тема. Однако и конкуренция в нише велика. Охватить свободную часть аудитории можно с помощью чат-ботов. Да-да — чат-боты можно использовать даже в нутре.

Речь пойдет о боте-диетологе. Мы уже создавали чат-бота под дейтинг, гороскопного бота и бота с меню под беттинг. В сегодняшнем материале мы сделаем бота-диетолога, который будет рассчитывать калории, белки, жиры и углеводы. Также он будет составлять индивидуальный план питания. А еще, как бы «между прочим», время от времени предлагать соответствующие офферы.

*Спойлер: в конце материала находится исходный код бота.

Как создать бота-диетолога своими руками?

Прежде чем приступить непосредственно к созданию бота, рекомендуем изучить общие принципы их работы. Если вы уже знакомы с этим — перейдет к тому, что будет представлять собой бот:

  1. Пользователь дает согласие на отказ от претензий (формальность, но важная — бот все таки не заменит врача).
  2. Указывает свой пол, рост, вес, возраст и образ жизни.
  3. Выбирает, для какой цели ему нужно составить диету (набор массы, похудение, поддержание веса).
  4. Бот анализирует всю эту инфу, записывает в базу данных.
  5. На основе анализа биологических данных и указанной цели рассчитывается калорийность суточного рациона для поддержания веса.
  6. Выводится несколько планов индивидуальных питания на выбор (будет в части 2).
  7. Время от времени выводятся офферы по нутре — похудалки или набиралки соответственно (будет в части 2).
Будет ли бот пользоваться спросом? Крайне вероятно, так как аналогичные услуги реальных диетологов стоят вполне дорого. Тут уже дело за вашей раскруткой. Само создание бота не займет много времени — фактически вы просто скопируете код и нажмете RUN.

Важные моменты

Также стоит обратить отдельное внимание на пункт отказа от претензий. Де-юре даже без этого пункта ничего страшного не произойдет — если только вы не будете выдавать бота за реального диетолога. Но на всякий случай рекомендуем выделить пару минут и все же сделать что-то подобное.

Пример возможного извещения о политике отказа от претензий
Пример возможного извещения о политике отказа от претензий
Пример возможного извещения о политике отказа от претензий

Для расчетов будет использоваться формула Миффлина-Сан Жеора во второй (доработанной) итерации. Ее создатели — американские диетологи Марк Миффлин и Сатико Сан-Жеор. Над формулой работала целая команда ведущих диетологов США, среди которых также были Йонг Ко, Лиза Хилл, Барбара Дж. Скотт и Сандра Доерти — так что о качестве расчетов можете не переживать. Формула получилась настолько близкой к реальности, что «вытеснила» из практики диетологов формулу Харриса-Бенедикта и формулу ВОЗ в 2005 году.

Толкование формулы Миффлина-Сан Жеора
Толкование формулы Миффлина-Сан Жеора
Толкование формулы Миффлина-Сан Жеора

Тем не менее, сама формула — все же лишь ориентир. Рассчитать в абсолюте реальную потребность в нутриентах для каждого конкретного человека нереально — слишком много индивидуальных переменных, влияющих на итоговое уравнение. А потому в соглашении об отказе от претензий обязательно уточните два момента:
  • Бот — не врач.
  • В случае возникновения недомоганий — отмените диету и обратитесь в медицинское учреждение.
Итак, когда все формальности соблюден, перейдем к созданию бота.

Создаем бота-диетолога с нуля

Как мы уже уточняли выше — статья будет состоять из двух частей. В первой мы будем опрашивать пользователя, записывать указанную им инфу, рассчитывать нормы калорий и процентного соотношения БЖУ в рационе, исходя из целей диеты.

Демонстрация расчета калорийности рациона и нормы БЖУ
Демонстрация расчета калорийности рациона и нормы БЖУ
Демонстрация расчета калорийности рациона и нормы БЖУ

Во второй части же мы будем формировать план питания и «подсовывать» офферы по нутре. Хотя никто не запрещает вам начать лить трафик уже после первой же статьи — упростив бота-диетолога до бота-калькулятора калорий и БЖУ. Итак, погнали:

Первым делом настраиваем сервак, регистрируем бота в Telegram и получаем токен доступа. Делается это так:

1. Регаемся и заходим в личный кабинет сервиса pythonanywhere.
2. Открывает Bash-консоль, дожидаемся завершения автоматической настройки.
Главное меню интерфейса хостинга pythonanywhere
Главное меню интерфейса хостинга pythonanywhere
Главное меню интерфейса хостинга pythonanywhere

3. Импортируем модуль pyTelegramBotAPI — он нужен, чтобы бот мог «взаимодействовать» с Telegram через протокол API. Для этого вводим в консоль:

pip3.9 install --user pyTelegramBotAPI

Серверная консоль сервиса pythonanywhere для работы с python
Серверная консоль сервиса pythonanywhere для работы с python
Серверная консоль сервиса pythonanywhere для работы с python

*3.9 — самая актуальная версия Python на момент публикации статьи. Однако спустя время версия может смениться — указывайте актуальную. Также удостоверьтесь, что и сервер, и API Telegram ее поддерживают.

4. Пишем официальному боту Telegram @BotFather — следуем инструкции, которую он пришлет. В целом там нужно будет лишь задать имя бота. Например, NameOfBot_bot.

Окончание _bot обязательно, иначе бот не будет работать. Также имя должно соответствовать правилам Telegram. После всех шагов @BotFather пришлет вам токен — сохраните его.

Выдача токена в @BotFather
Выдача токена в @BotFather
Выдача токена в @BotFather

5. Запускаем блокнот или любой текстовый редактор, вписываем туда:

import telebot
import time
from telebot import types
bot = telebot.TeleBot('ТОКЕН СЮДА')

@bot.message_handler(commands=['start'])
def start(message):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Принять")
btn2 = types.KeyboardButton("Отказаться")
markup.add(btn1, btn2)
policy = open('policy.txt', 'r').read()
bot.send_message(message.chat.id, text="Привет, {0.first_name}! \n".format(message.from_user)+policy, reply_markup=markup, parse_mode="Markdown")

user_id = str(message.from_user.id)
t=0
file = open('log.txt')
for num_line, line in enumerate(file):
if user_id in line:
t=1
my_file = open('users/'+user_id+'.txt', 'w')
my_file.write("0" + '\n')
my_file.close()
break
file.close()

if(t == 0):

file = open('log.txt', 'a')
file.write(user_id + '\n')
file.close()

my_file = open('users/'+user_id+'.txt', 'w')
my_file.write("0" + '\n')
my_file.close()

@bot.message_handler(content_types=['text'])
def func(message):
time.sleep(3)
user_id = str(message.from_user.id)
my_file = open('users/'+user_id+'.txt', 'r')
num_lines = sum(1 for line in my_file)
print(num_lines)
my_file.close()

text=message.text

if(message.text == "Изменить профиль"):
my_file = open('users/'+user_id+'.txt', 'w')
my_file.write("0" + '\n')
my_file.close()
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Принять")
btn2 = types.KeyboardButton("Отказаться")
markup.add(btn1, btn2)
policy = open('policy.txt', 'r').read()
bot.send_message(message.chat.id, text="Привет, {0.first_name}! \n".format(message.from_user)+policy, reply_markup=markup, parse_mode="Markdown")


if(message.text == "Отказаться"):
my_file = open('users/'+user_id+'.txt', 'w')
my_file.write("0" + '\n')
my_file.close()
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Принять")
btn2 = types.KeyboardButton("Отказаться")
markup.add(btn1, btn2)
policy = open('policy.txt', 'r').read()
bot.send_message(message.chat.id, text="Привет, {0.first_name}! \n".format(message.from_user)+policy, reply_markup=markup, parse_mode="Markdown")


if(num_lines == 1 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Мужской")
btn2 = types.KeyboardButton("Женский")
markup.add(btn1, btn2)
bot.send_message(message.chat.id, text="Выберите ваш пол", reply_markup=markup)

if(num_lines == 2 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
markup = types.ReplyKeyboardRemove()
bot.send_message(message.chat.id, text="Выберите ваш возраст (только цифру)", reply_markup=markup)

if(num_lines == 3 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
bot.send_message(message.chat.id, text="Выберите ваш рост в сантиметрах (только цифру)")

if(num_lines == 4 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
bot.send_message(message.chat.id, text="Выберите ваш вес в киллограмах (только цифру)")

if(num_lines == 5 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Малоактивный")
btn2 = types.KeyboardButton("Среднеактивный")
btn3 = types.KeyboardButton("Активный")
btn4 = types.KeyboardButton("Очень активный")
btn5 = types.KeyboardButton("Ежедневные тренировки")
btn6 = types.KeyboardButton("До двух тренировок в день")
btn7 = types.KeyboardButton("Очень активные и тяжелые физические нагрузки ежедневно")
markup.add(btn1, btn2, btn3, btn4, btn5, btn6, btn7)
bot.send_message(message.chat.id, text="Укажите ваш образ жизни", reply_markup=markup)

if(num_lines == 6 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Экстримальное похудение")
btn2 = types.KeyboardButton("Безопасное похудение")
btn3 = types.KeyboardButton("Поддержание веса")
btn4 = types.KeyboardButton("Набор мышечной массы")
btn5 = types.KeyboardButton("Сушка ")
markup.add(btn1, btn2, btn3, btn4, btn5)
bot.send_message(message.chat.id, text="Выберите цель диеты", reply_markup=markup)

if(num_lines == 7 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Расчитать каллорийность и норму БЖУ")
markup.add(btn1)
bot.send_message(message.chat.id, text="Погнали?", reply_markup=markup)

if(num_lines == 8 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
f = open('users/'+user_id+'.txt', 'r')
fd = f.readlines()
if("Мужской" in fd[2]):
pol=5
elif("Женский" in fd[2]):
pol=-161
if("Малоактивный" in fd[6]):
fizo=1.2
elif("Среднеактивный" in fd[6]):
fizo=1.37
elif("Активный" in fd[6]):
fizo=1.45
elif("Очень активный" in fd[6]):
fizo=1.55
elif("Ежедневные тренировки" in fd[6]):
fizo=1.65
elif("До двух тренировок в день" in fd[6]):
fizo=1.725
elif("Очень активные и тяжелые физические нагрузки ежедневно" in fd[6]):
fizo=1.9
vozrast=int(fd[3])
rost=int(fd[4])
ves=int(fd[5])
summ=int(((9.99*ves+6.25*rost-4.92*vozrast+pol)*fizo))
if("Экстримальное похудение" in fd[7]):
probel=0.35
projir=0.35
prougl=0.3
ksum=0.7
elif("Безопасное похудение" in fd[7]):
probel=0.3
projir=0.3
prougl=0.4
ksum=0.8
elif("Поддержание веса" in fd[7]):
probel=0.25
projir=0.25
prougl=0.5
ksum=1
elif("Набор мышечной массы" in fd[7]):
probel=0.3
projir=0.25
prougl=0.5
ksum=1.2
elif("Сушка" in fd[7]):
probel=0.35
projir=0.25
prougl=0.40
ksum=1.1
summa=int(summ*ksum)
bel=int((probel*summa)/4)
jir=int((projir*summa)/9)
ugl=int((prougl*summa)/4)
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Выбрать диету")
btn2 = types.KeyboardButton("Изменить профиль")
markup.add(btn1, btn2)
bot.send_message(message.chat.id, text="Ваша дневная норма:\n"+str(summa)+" ккал.\n"+str(bel)+" грамм белка.\n"+str(jir)+" грамм жиров.\n"+str(ugl)+" грамм углеводов.", reply_markup=markup)
my_file.close()

if(num_lines > 0 and num_lines <= 9 and message.text != "Изменить профиль" and message.text != "Выбрать диету" and message.text != "Отказаться"):
my_file = open('users/'+user_id+'.txt', 'a')
my_file.write(text + '\n')
my_file.close()

if(num_lines == 9 and message.text == "Выбрать диету"):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
bot.send_message(message.chat.id, text="Пример меню", reply_markup=markup)
num_lines=None

bot.polling(none_stop=True)

Жмем ctrl+F, ищем строку bot = telebot.TeleBot('ТОКЕН СЮДА') #задаем токен — копируем в нее токен от @BotFather .

Сохраняем скрипт как «bot.py».

6. Загружаем скрипт на сервак.

Добавление python-скрипта на сервер
Добавление python-скрипта на сервер
Добавление python-скрипта на сервер

7. Создаем лог-файл — log.txt


8. Создаем папку для хранения данных пользователей — users


9. Создаем файл с политикой отказа от претензий — policy.txt


10. Задаем политику отказа от претензий в файле policy.txt — для выделения текста жирным или курсивом используйте комбинации *текст* и _текст_ соответственно. Не забываем сохранить файл.


11. Инициируем бота, нажатием Run.

Инициация обработки скрипта
Инициация обработки скрипта
Инициация обработки скрипта

12. Тестим результат работы.

Подтверждение отказа от претензий и выбор пола
Подтверждение отказа от претензий и выбор пола
Подтверждение отказа от претензий и выбор пола

Выбор возраста, роста, веса и образа жизни
Выбор возраста, роста, веса и образа жизни
Выбор возраста, роста, веса и образа жизни

Указание цели диеты, расчет калорийности, нормы БЖУ и изменение профиля для перепрохождения теста
Указание цели диеты, расчет калорийности, нормы БЖУ и изменение профиля для перепрохождения теста
Указание цели диеты, расчет калорийности, нормы БЖУ и изменение профиля для перепрохождения теста

 Прохождение теста с другими исходными данными и демонстрация отклика кнопки «Выбрать диету»
Прохождение теста с другими исходными данными и демонстрация отклика кнопки «Выбрать диету»
Прохождение теста с другими исходными данными и демонстрация отклика кнопки «Выбрать диету»

Подводя итоги

Как видите, создать бота-диетолога для Telegram под слив на нутру не так сложно, как кажется. И для этого вовсе не обязательно платить разработчикам либо использовать сторонние сервисы.

Впрочем, самое интересное будет во второй части, где мы научим бота не просто считать калории и нутриенты, но еще и формировать индивидуальный план питания. А после мы научим делать так, чтобы он время от времени «подсовывал» пользователю офферы для похудения или набора массы, исходя из его интересов.


telegram-icon-small
telegram-icon-big

TrafficCardinal в телеграме

Только полезный контент и бесплатные плюшки.

2-3 раза в день