Giter VIP home page Giter VIP logo

notification_service's Introduction

Сервис уведомлений

Cервис управления рассылками API администрирования, отправки сообщений на внешнее API и получения статистики.

Описание

Спроектирован и разработан сервис, который по заданным правилам запускает рассылку по списку клиентов.

Сущность "рассылка" имеет атрибуты:

  • уникальный id рассылки
  • дата и время запуска рассылки
  • текст сообщения для доставки клиенту
  • фильтр свойств клиентов, на которых должна быть произведена рассылка (код мобильного оператора, тег)
  • дата и время окончания рассылки: если по каким-то причинам не успели разослать все сообщения - никакие сообщения клиентам после этого времени доставляться не должны
  • временной интервал, в котором можно задать промежуток времени, в котором клиентам можно отправлять сообщения с учётом их локального временил

Сущность "клиент" имеет атрибуты:

  • уникальный id клиента
  • номер телефона клиента в формате 7XXXXXXXXXX (X - цифра от 0 до 9)
  • код мобильного оператора
  • тег (произвольная метка)
  • часовой пояс

Сущность "сообщение" имеет атрибуты:

  • уникальный id сообщения
  • дата и время создания (отправки)
  • статус отправки
  • id рассылки, в рамках которой было отправлено сообщение
  • id клиента, которому отправили

Как запустить проект:

Клонировать репозиторий и перейти в него в командной строке:

git clone https://github.com/KaterinaSolovyeva/notification_service.git

cd notifification_service

Создайте файл .env. Шаблон наполнения env-файла можно посмотреть в файле .env.example:

Запустите docker-compose командой docker-compose up -d --build

Создайте миграции:

docker-compose exec web python manage.py makemigrations notifications
docker-compose exec web python manage.py migrate notifications

Создайте суперпользователя Django:

sudo docker-compose exec web python manage.py createsuperuser

Запросы к API:

Добавление нового клиента в справочник со всеми его атрибутами. Код мобильного оператора сохраняется автоматически из номера телефона в базу доступных кодов. Теги сохраняются в базу доступных тегов, если таких ещё в базе нет. У клиента может быть несколько тегов и один код мобильного оператора. Если не указан часовой пояс, по умолчанию - UTC.

POST /api/v1/clients/
пример запроса:
{
    "telephone": "79111234567",
    "tag": ["urgent", "simple"],
    "timezone": "Asia/Singapore"
}
ответ:
{
    "id": 1,
    "telephone": "79111234567",
    "mobile_code": 911,
    "tag": [
        {
            "name": "simple"
        },
        {
            "name": "urgent"
        }
    ],
    "timezone": "Asia/Singapore"
}

Обновление данных атрибутов клиента.

PUT /api/v1/clients/{client_id}/
пример запроса:
{
    "telephone": "79111234567",
    "tag": ["urgent"],
    "timezone": "Asia/Singapore"
}
ответ:
{
    "id": 1,
    "telephone": "79111234567",
    "mobile_code": 911,
    "tag": [
        {
            "name": "urgent"
        }
    ],
    "timezone": "Asia/Singapore"
}

Удаление клиента из справочника.

DELETE /api/v1/clients/{client_id}/

Добавление новой рассылки со всеми её атрибутами. Если уведомление ещё активно, то с помощью celery вызывается задача отправки сообщений с временем начала выполнения - время запуска рассылки. Не отправляет клиенту сообщение, если его локальное время не входит в указанный интервал. Ждет подходящего времени с учетом часового пояса клиента.

POST /api/v1/notifications/
пример запроса:
{
    "date_time_start": "2022-08-22 18:54:17",
    "text": "test",
    "date_time_stop": "2022-08-28 14:27:21",
    "tag": ["urgent"],
    "mobile_code": [911]
}
ответ:
{
    "id": 1,
    "date_time_start": "2022-08-22 18:54:17",
    "text": "test",
    "date_time_stop": "2022-08-28 14:27:21",
    "number_of_messages": {
        "Created, waiting": 0,
        "Sent": 0,
        "Unable to deliver": 0
    }
}

Получение общей статистики по созданным рассылкам и количеству отправленных сообщений по ним с группировкой по статусам. При указании параметров limit и offset выдача работает с пагинацией.

GET /api/v1/notifications/
пример ответа:
{
    "count": 1,
    "previous": null,
    "results": [
        {
            "id": 1,
            "date_time_start": "2022-08-22 18:54:17",
            "text": "test",
            "date_time_stop": "2022-08-28 14:27:21",
            "number_of_messages": {
                "Created, waiting": 1,
                "Sent": 0,
                "Unable to deliver": 0
            }
        }
    ]
}

Получение статистики по конкретной рассылке.

GET /api/v1/notifications/{notification_id}/
пример ответа:
{
    "id": 1,
    "date_time_start": "2022-08-22 18:54:17",
    "text": "test",
    "date_time_stop": "2022-08-28 14:27:21",
    "number_of_messages": {
        "Created, waiting": 0,
        "Sent": 1,
        "Unable to deliver": 0
    }
}

Получение детальной статистики отправленных сообщений по конкретной рассылке.

GET /api/v1/notifications/{notification_id}/messages/
пример ответа:
{
    "count": 1,
    "previous": null,
    "results": [
        {
            "id": 1,
            "pub_date": "2022-08-23T08:54:36.258537Z",
            "status": "Sent",
            "notification": 1,
            "clients": [
                1
            ]
        },
    ]
}

Обновление атрибутов рассылки. Сообщения отсылаются только тем клиентам, которые их не получали в ходе предыдущей версии рассылки.

PUT /api/v1/notifications/{notification_id}/
пример ответа:
{
    "id": 1,
    "date_time_start": "2022-08-22 18:54:17",
    "text": "new text",
    "date_time_stop": "2022-08-28 14:27:21",
    "number_of_messages": {
        "Created, waiting": 0,
        "Sent": 1,
        "Unable to deliver": 0
    }
}

Удаление рассылки вместе со связанными с ней сообщениями.

DELETE /api/v1/notifications/{notification_id}/

Логика рассылки

  • После создания новой рассылки, если текущее время больше времени начала и меньше времени окончания - из справочника выбираются все клиенты, которые подходят под значения фильтра, указанного в этой рассылке и запускается отправка сообщений для всех этих клиентов.
  • Если создаётся рассылка с временем старта в будущем - отправка стартует автоматически по наступлению этого времени без дополнительных действий со стороны пользователя системы.
  • По ходу отправки сообщений собирается статистика по каждому сообщению для последующего формирования отчётов.
  • Внешний сервис, который принимает отправляемые сообщения, может долго обрабатывать запрос, отвечать некорректными данными, на какое-то время вообще не принимать запросы. Реализвана корректная обработка подобных ошибок. Проблемы с внешним сервисом не влияют на стабильность работы разрабатываемого сервиса рассылок.

API внешнего сервиса отправки

Для интеграции с разрабатываемым проектом существует внешний сервис, который может принимать запросы на отправку сообщений в сторону клиентов. OpenAPI спецификация находится по адресу: https://probe.fbrq.cloud/docs В этом API предполагается аутентификация с использованием JWT. Токен доступа необходимо внести в .env файл.


Также рализовано:

  1. Организовано тестирование написанного кода. Запустить тесты:
docker-compose exec web python manage.py test
  1. Подготовлен docker-compose для запуска всех сервисов проекта одной командой
  2. По адресу /docs/ открывается страница со Swagger UI и в нём отображено описание разработанного API.
  3. Реализован администраторский Web UI для управления рассылками и получения статистики по отправленным сообщениям. Реализован Django admin interface.
  4. Реализован дополнительный сервис, который раз в сутки отправляет статистику по обработанным рассылкам на email. Использован django_celery_beat. Настроена отправка сообщений с Яндекс почты.
  5. Удаленный сервис может быть недоступен, долго отвечать на запросы или выдавать некорректные ответы. Организована обработка ошибок и откладывание запросов при неуспехе для последующей повторной отправки. Задержки в работе внешнего сервиса не оказывают влияние на работу сервиса рассылок.
  6. Реализована дополнительная бизнес-логика: добавить в сущность "рассылка" поле "временной интервал", в котором можно задать промежуток времени, в котором клиентам можно отправлять сообщения с учётом их локального времени. Не отправлять клиенту сообщение, если его локальное время не входит в указанный интервал.
  7. Обеспечено подробное логирование на всех этапах обработки запросов, чтобы при эксплуатации была возможность найти в логах всю информацию по
  • id рассылки - все логи по конкретной рассылке (и запросы на api и внешние запросы на отправку конкретных сообщений)
  • id сообщения - по конкретному сообщению (все запросы и ответы от внешнего сервиса, вся обработка конкретного сообщения)
  • id клиента - любые операции, которые связаны с конкретным клиентом (добавление/редактирование/отправка сообщения/…) Файл с этими логами - statistic.log.

notification_service's People

Contributors

katerinasolovyeva avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.