Однажды после очередного код-ревью (Кириллу привет) у меня жутко заболела голова.

Аптечка! У меня дома должна быть аптечка?!

После 10 минут поисков аптечки я обнаружил, что в ней лежит 2 пакетика травы, 75 таблеток мескалина, 5 листов марок мощнейшей кислоты, полсолонки кокаина и гора возбудителей початая ампула изопропилового спирта, засохший листочек подорожника и пачка разнокалиберных таблеток с непонятными названиями.

Асептолин, Риталин, Екокс…что из этого избавит от головной боли, а что является жаропонижающим?! Боль усиливалась…

После еще 5 минут гугления я понял, что мне нужен Баралгин и он, о чудо, есть в моей аптечке…правда его срок годности истёк.

Сквозь завесу боли в голову пришла запоздалая идея: "А вот бы у меня было приложение для учета лекарств в домашней аптечке (cпойлер - теперь такой сервис есть). И чтобы оно напоминало об истечении срока годности…и чтобы можно было оперативно получить информацию о лекарстве…и чтобы просроченное лекарство можно было бы сразу же заказать в аптеке."

Закинувшись просроченными таблетками, я попытался сформулировать основные требования к будущему сервису…


Требования

  1. Сервис должен отображать список лекарств с разбиением на просроченные и непросроченные.

  2. Для каждого лекарства должна отображаться ключевая информация - назначение, противопоказания, побочные эффекты и т.п.

  3. Добавление лекарства должно осуществляеться за минимальное количество шагов: вводим название лекарства (после начала ввода система предлагает варианты препаратов из БД) и месяц/год истечения срока годности - остальная информация (рекомендации к применению, противопоказания, побочки) подгружается из БД;

  4. Пользователь должен иметь возможность в один клик/тап перейти в интернет аптеку для заказа просроченного лекарства в онлайн-аптеке;

  5. Сервис должен периодически проверять, истёк ли срок годности лекарств и, если таки истёк, уведомлять об этом пользователя.

Предполагается, что сервис будет реализован в виде связки telegram бота и web-приложения. Телеграм есть/будет у каждого, т.о. не надо будет заморачиваться ни с доставкой приложения пользователям, ни с публикацией приложения под разные платформы в разных сторах (Telegram постепенно превращается в SuperApp?).

Техническая реализация подобного сервиса довольно тривиальна...

...но где нам взять данные о лекарственных препаратах?


Получаем данные о лекарственных препаратах

В ряде стран эти данные можно получить через бесплатные сервисы. Например OpenFDA в США или NHS APIs в Британии. 

В России же с этим несколько сложнее…

Есть такой замечательный справочник лекарственных препаратов - VIDAL. В нём представлена информация о более чем 25 тысячах лекарств.

Есть все необходимые данные - показания к применению, противопоказания, побочные эффекты и т.п. 

Более того, информация проверена врачом-экспертом, а для ряда лекарств есть ссылки оформление заказа в онлайн-аптеках.

Одна беда - доступ к API\БД стоит денег, да и компания работает только с юр лицами.

Как же нам получить эти данные?

Вариант со взломом сервера сайта отпал сразу после того, как я бегло пролистал УК РФ - 272 статья - это не шутка. Остался только один вариант - соSCRAPYть необходимую информацию.

Изучив вопрос с технической и правовой стороны, а также получив одобрение на использование материалов сайта от компании владельца VIDAL (социальная инженерия вежливость творит чудеса), я приступил к работе.

Извлекать данные с сайта мы будем в три этапа при помощи библиотеки Scrapy.

Три этапа == три CrawlSpider'a == три набора правил парсинга и извлечения информации с web-страницы.

  • Паук №1 - на главной странице сайта получаем ссылки на списки лекарственных препаратов, сгруппированных по первой букве названия лекарства;

  • Павук №2 - для каждой ссылки, полученной на предыдущем шаге, мы скрейпим ссылки на лекарственные препараты;

  • Паук №3 - извлекаем ключевую информацию со страницы лекарственного препарата.

Как итог мы получим ключевую информацию о более чем 25 тысячах лекарственных препаратах: 

  • Фармакологическая группа;

  • Показания к применению;

  • Противопоказания к применению;

  • Побочные эффекты;

  • Особые указания.

Для некоторых лекарств есть возможность оформления заказа в электронных аптеках, список которых запрашивается каждый раз при загрузке страницы с препаратом. Это обычный rest запрос, для которого необходим только идентификатор лекарства (даже токен не нужен, что как-то странно...), который мы также извлекаем при помощи web скрейпинга.


Разработка сервиса

Код проекта: MedicineBoxBot

Нет, ну серьёзно, не хочется вдаваться в технические подробности - на Хабре уйма статей а-ля Пишем Телеграм бота на aiogram (1..n), в которых подробно описаны все аспекты разработки...давайте лучше посмотрим, что получилось и обсудим сервис в комментариях.

А теперь слайды!
Старт бота и запуск web-приложения.
Старт бота и запуск web-приложения.
Просмотр информации о лекарствах.
Просмотр информации о лекарствах.
Добавление лекарства.
Добавление лекарства.
Просмотр информации о просроченных лекарствах и оформление заказа в электронной аптеке.
Просмотр информации о просроченных лекарствах и оформление заказа в электронной аптеке.
Удаление записей о лекарственных препаратах.
Удаление записей о лекарственных препаратах.
Оформление заказа после получения уведомления от бота об истечении срока годности препарата.
Оформление заказа после получения уведомления от бота об истечении срока годности препарата.
Просмотр списка медикаментов, которые должны присутствовать в каждой аптечке.
Просмотр списка медикаментов, которые должны присутствовать в каждой аптечке.

Видео работы приложения:


Разворачиваем сервис

Мы не готовы платить за хостинг (к росту цен на который нам уже предлагают готовиться), поэтому будем разворачивать сервис на домашнем сервере.

Домашний сервер
Quad core CPU 2.4Gz, 8Gb RAM, WiFi 802.11ac
Quad core CPU 2.4Gz, 8Gb RAM, WiFi 802.11ac

Тратить деньги на домен, статический ip и ssl сертификат тоже жалко (нет, я не жадный, я домовитый), поэтому доменное имя мы получим в сервисе no-ip (инструкция), за обновление привязки динамического ip адреса к домену будет отвечать Dynamic Update Client (DUC) от того-же no-ip. SSL сертификат cгенерируем при помощи let’s encrypt.

Для удобства управления вся наша инфраструктура будет работать внутри docker контейнеров.

docker-compose.yml
---
services:
  rabbitmq:
    image: rabbitmq:3.10.7-management
    container_name: rabbitmq
    hostname: rabbitmq
    restart: always
    env_file:
      - ../secrets/rabbitmq_vault.env
    ports:
      - '15672:15672'
      - '5672:5672'
    volumes:
      - ./rabbitmq:/var/lib/rabbitmq

  noip_duc:
    image: 'ghcr.io/noipcom/noip-duc:latest'
    container_name: noip
    restart: unless-stopped
    env_file:
      - ../secrets/no_ip_vault.env

  nginx_proxy:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    container_name: nginx
    depends_on:
      - webapp
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

  webapp:
    container_name: webapp
    build: ../webapp
    depends_on:
      - rabbitmq
    volumes:
      - ./../db/:/app/db
    ports:
      - '8000:8000'
    environment:
      WEBAPP_PORT: 8000
    env_file:
      - ../secrets/webapp_vault.env

  bot:
    container_name: bot
    build: ../bot
    depends_on:
      - rabbitmq
    volumes:
      - ./../db/:/app/db
    env_file:
      - ../secrets/bot_vault.env

  • rabbitmq — брокер сообщений для обмена данными между web‑приложением и telegram ботом (сообщения об истечении срока годности лекарственного препарата);

  • noip_duc — dynamic update client. Периодически подключается к no-ip и обновляет информацию об ip адресе, за которым закреплено доменное имя;

  • nginx_proxy (Nginx proxy manager) - nginx сервер с удобной web админкой и  возможностью генерировать (и автоматически обновлять) SSL сертификаты;

  • webapp и bot - контейнеры с web-приложением и ботом соответственно.

После подготовки raspberry, установки docker, настройки Nginx Proxy Manager и запуска контейнеров наш сервис готов к работе.

Telegram "Medicine Box Bot"

Если считаете, что сервис будет вам полезен - пользуйтесь на здоровье и советуйте другим.

Если есть предложения по улучшению сервиса или багрепорты - оставляйте комментарии.

Спасибо, что пролистали статью до конца.

Комментарии (15)