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
Добавление нового клиента в справочник со всеми его атрибутами. Код мобильного оператора сохраняется автоматически из номера телефона в базу доступных кодов. Теги сохраняются в базу доступных тегов, если таких ещё в базе нет. У клиента может быть несколько тегов и один код мобильного оператора. Если не указан часовой пояс, по умолчанию - 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}/
- После создания новой рассылки, если текущее время больше времени начала и меньше времени окончания - из справочника выбираются все клиенты, которые подходят под значения фильтра, указанного в этой рассылке и запускается отправка сообщений для всех этих клиентов.
- Если создаётся рассылка с временем старта в будущем - отправка стартует автоматически по наступлению этого времени без дополнительных действий со стороны пользователя системы.
- По ходу отправки сообщений собирается статистика по каждому сообщению для последующего формирования отчётов.
- Внешний сервис, который принимает отправляемые сообщения, может долго обрабатывать запрос, отвечать некорректными данными, на какое-то время вообще не принимать запросы. Реализвана корректная обработка подобных ошибок. Проблемы с внешним сервисом не влияют на стабильность работы разрабатываемого сервиса рассылок.
Для интеграции с разрабатываемым проектом существует внешний сервис, который может принимать запросы на отправку сообщений в сторону клиентов. OpenAPI спецификация находится по адресу: https://probe.fbrq.cloud/docs В этом API предполагается аутентификация с использованием JWT. Токен доступа необходимо внести в .env файл.
- Организовано тестирование написанного кода. Запустить тесты:
docker-compose exec web python manage.py test
- Подготовлен docker-compose для запуска всех сервисов проекта одной командой
- По адресу /docs/ открывается страница со Swagger UI и в нём отображено описание разработанного API.
- Реализован администраторский Web UI для управления рассылками и получения статистики по отправленным сообщениям. Реализован Django admin interface.
- Реализован дополнительный сервис, который раз в сутки отправляет статистику по обработанным рассылкам на email. Использован django_celery_beat. Настроена отправка сообщений с Яндекс почты.
- Удаленный сервис может быть недоступен, долго отвечать на запросы или выдавать некорректные ответы. Организована обработка ошибок и откладывание запросов при неуспехе для последующей повторной отправки. Задержки в работе внешнего сервиса не оказывают влияние на работу сервиса рассылок.
- Реализована дополнительная бизнес-логика: добавить в сущность "рассылка" поле "временной интервал", в котором можно задать промежуток времени, в котором клиентам можно отправлять сообщения с учётом их локального времени. Не отправлять клиенту сообщение, если его локальное время не входит в указанный интервал.
- Обеспечено подробное логирование на всех этапах обработки запросов, чтобы при эксплуатации была возможность найти в логах всю информацию по
- id рассылки - все логи по конкретной рассылке (и запросы на api и внешние запросы на отправку конкретных сообщений)
- id сообщения - по конкретному сообщению (все запросы и ответы от внешнего сервиса, вся обработка конкретного сообщения)
- id клиента - любые операции, которые связаны с конкретным клиентом (добавление/редактирование/отправка сообщения/…) Файл с этими логами - statistic.log.