**Версия документа:** 1.1

**Репозиторий:** haskimail_rocketmail

---

## Содержание

 1. О чём это руководство

 2. Что входит в репозиторий

 3. Что нужно подготовить до начала работы

 4. Установка Python-окружения

 5. Самый быстрый способ проверить API (скрипт send_haskimail.py)

 6. Интеграция с Django

 7. Интеграция с Flask

 8. Какой способ выбрать

 9. Частые ошибки и их решение

10. Полезные ссылки

---

## 1. О чём это руководство

Haskimail — сервис отправки транзакционных и массовых писем через HTTP API или SMTP. В репозитории **haskimail_rocketmail** лежит готовый код для двух сценариев:

* **Django** — кастомный почтовый backend `anymail_haskimail`, который подключается к стандартному механизму Django (`send_mail`, формы, задачи Celery и т.д.).

* **Flask** — в репозитории нет отдельного Flask-модуля; письма отправляются прямым HTTP-запросом к API Haskimail (так же, как в скрипте `send_haskimail.py`).

Официальная документация API: <https://haskimail.ru/developer>

Личный кабинет: <https://lk.haskimail.ru>

---

## 2. Что входит в репозиторий

Ниже перечислены файлы, с которыми вы будете работать чаще всего.

**anymail_haskimail/backend.py**

Кастомный класс `EmailBackend` для Django. Принимает письма от `django.core.mail` и отправляет их в Haskimail по HTTP.

**anymail_haskimail/init**.py

Метаданные пакета (версия).

**send_haskimail.py**

Автономный скрипт: одна отправка через официальный endpoint `POST https://api.haskimail.ru/email`. Не требует Django и Flask. Удобен для первой проверки ключа и адреса отправителя.

**send_test_email.py**

Тест Django-backend без полноценного проекта: скрипт сам вызывает `django.setup()` и отправляет тестовое письмо.

**requirements.txt**

Список зависимостей: `django`, `requests` и др.

---

## 3. Что нужно подготовить до начала работы

### 3.1. Серверный API-ключ (Server Token)

Это не пароль от личного кабинета. Нужен именно **токен сервера** (Server API key), который привязан к вашему почтовому серверу/каналу в Haskimail.

**Где взять:**

1. Войдите в <https://lk.haskimail.ru>

2. Откройте настройки нужного сервера или канала.

3. Скопируйте Server Token / API-ключ сервера.

4. Сохраните его в надёжном месте (переменная окружения, менеджер секретов). Не публикуйте ключ в Git.

**Важно:** для HTTP API используется заголовок `X-Haskimail-Server-Token` и значение ключа **без** префикса `Bearer`.

### 3.2. Подтверждённый адрес отправителя

Перед отправкой писем адрес в поле **From** (отправитель) должен быть подтверждён в Haskimail.

**Где проверить:** раздел «Домены и отправители» в личном кабинете — <https://lk.haskimail.ru>

Примеры корректного формата:

* `support@yourdomain.com`

* `Магазин <support@yourdomain.com>`

Если домен или отправитель не подтверждён, API может принять запрос, но письмо не будет доставлено или вернётся ошибка.

### 3.3. Программное окружение

* Python 3.10 или новее (рекомендуется 3.11+).

* Установленный `pip`.

* Доступ в интернет до `api.haskimail.ru`.

Проверка версии Python:

```
python --version
```

---

## 4. Установка Python-окружения

Все команды ниже выполняются из каталога репозитория **haskimail_rocketmail** (там, где лежат `send_haskimail.py` и папка `anymail_haskimail`).

### Шаг 4.1. Клонирование (если ещё не сделано)

```
git clone https://gitlab.com/dashamail-projects/haskimail_rocketmail.git

cd haskimail_rocketmail
```

### Шаг 4.2. Виртуальное окружение

```
python -m venv .venv
```

### Шаг 4.3. Активация окружения

**Windows (PowerShell):**

```
.venv\Scripts\Activate.ps1
```

**Windows (cmd):**

```
.venv\Scripts\activate.bat
```

**Linux / macOS:**

```
source .venv/bin/activate
```

После активации в начале строки терминала появится префикс `(.venv)`.

### Шаг 4.4. Установка зависимостей

```
pip install --upgrade pip

pip install -r requirements.txt
```

Для работы с Flask дополнительно:

```
pip install flask
```

---

## 5. Самый быстрый способ проверить API (скрипт send_haskimail.py)

Рекомендуется выполнить этот шаг **до** подключения Django или Flask. Так вы убедитесь, что токен и адрес отправителя настроены правильно.

### 5.1. Что делает скрипт

* Отправляет один POST-запрос на `https://api.haskimail.ru/email`

* Передаёт заголовок `X-Haskimail-Server-Token`

* В теле JSON указывает поля `From`, `To`, `Subject`, `TextBody` и при необходимости `HtmlBody`

### 5.2. Запуск на Windows (PowerShell)

```
cd haskimail_rocketmail

.venv\Scripts\Activate.ps1

$env:HASKIMAIL_API_KEY = "вставьте_ваш_серверный_токен"

python send_haskimail.py --from "Магазин <support@yourdomain.com>" --to recipient@example.com --subject "Тест HaskiMail" --text "Текст письма"
```

С HTML-версией:

```
python send_haskimail.py --from "Магазин <support@yourdomain.com>" --to recipient@example.com --subject "Тест" --text "Текст" --html "<p><strong>HTML</strong></p>"
```

Токен можно передать и аргументом (без переменной окружения):

```
python send_haskimail.py --token "вставьте_токен" --from "support@yourdomain.com" --to recipient@example.com
```

### 5.3. Запуск на Linux / macOS

```
cd haskimail_rocketmail

source .venv/bin/activate

export HASKIMAIL_API_KEY="вставьте_ваш_серверный_токен"

python send_haskimail.py \

  --from "Магазин <support@yourdomain.com>" \

  --to recipient@example.com \

  --subject "Тест HaskiMail" \

  --text "Текст письма"
```

### 5.4. Как понять, что всё прошло успешно

В консоли должно появиться:

* строка `HTTP 200` (или другой код 2xx);

* JSON-ответ от API (если сервер его возвращает).

При ошибке авторизации часто видно `HTTP 401` и сообщение о невалидном серверном ключе — см. раздел 9.

### 5.5. Параметры командной строки send_haskimail.py

* `--token` — серверный токен (если не задан, берётся из `HASKIMAIL_API_KEY`)

* `--api-base` — хост API, по умолчанию `https://api.haskimail.ru`

* `--from` — отправитель (обязательный)

* `--to` — получатель (обязательный)

* `--subject` — тема письма

* `--text` — текстовая часть

* `--html` — HTML-часть (необязательно)

---

## 6. Интеграция с Django

### 6.1. Общая схема

1. Вы подключаете backend в `settings.py`.

2. Django при вызове `send_mail()` или `message.send()` передаёт письмо в `anymail_haskimail.backend.EmailBackend`.

3. Backend формирует HTTP-запрос к HaskiMail.

### 6.2. Подключение в существующем Django-проекте

Откройте файл [**settings.py**](http://settings.py) вашего проекта и добавьте:

```
EMAIL_BACKEND = "anymail_haskimail.backend.EmailBackend"

ANYMAIL = {

    "HASKIMAIL_API_KEY": "ваш-серверный-токен",

    "HASKIMAIL_API_URL": "https://api.haskimail.ru/v1/messages/send",

}
```

**Рекомендация для продакшена** — хранить ключ в переменных окружения:

```
import os

EMAIL_BACKEND = "anymail_haskimail.backend.EmailBackend"

ANYMAIL = {

    "HASKIMAIL_API_KEY": os.environ["HASKIMAIL_API_KEY"],

    "HASKIMAIL_API_URL": os.getenv(

        "HASKIMAIL_API_URL",

        "https://api.haskimail.ru/v1/messages/send",

    ),

}
```

В файле `.env` на сервере (пример):

```
HASKIMAIL_API_KEY=ваш-токен-без-пробелов-и-кавычек

HASKIMAIL_API_URL=https://api.haskimail.ru/v1/messages/send
```

### 6.3. Как сделать, чтобы Python находил пакет anymail_haskimail

Вариант А — скопировать папку `anymail_haskimail` в корень вашего Django-проекта (рядом с `manage.py`).

Вариант Б — добавить путь к репозиторию в `PYTHONPATH` перед запуском:

**Windows:**

```
$env:PYTHONPATH = "C:\путь\к\haskimail_rocketmail"
```

**Linux / macOS:**

```
export PYTHONPATH="/путь/к/haskimail_rocketmail"
```

Вариант В — запускать команды из каталога `haskimail_rocketmail`, если проект небольшой и лежит там же.

### 6.4. Пример отправки простого письма

```
from django.core.mail import send_mail

send_mail(

    subject="Тема письма",

    message="Текст письма",

    from_email="support@yourdomain.com",

    recipient_list=["recipient@example.com"],

    fail_silently=False,

)
```

### 6.5. Пример письма с HTML

```
from django.core.mail import EmailMultiAlternatives

msg = EmailMultiAlternatives(

    subject="Заказ оформлен",

    body="Краткий текст для клиентов без HTML.",

    from_email="Магазин <support@yourdomain.com>",

    to=["customer@example.com"],

)

msg.attach_alternative("<h1>Спасибо за заказ</h1><p>Детали заказа...</p>", "text/html")

msg.send()
```

### 6.6. Тест Django-backend без своего проекта (send_test_email.py)

Если у вас ещё нет `manage.py`, можно проверить backend отдельным скриптом:

```
python send_test_email.py ^

  --to recipient@example.com ^

  --api-key ваш-серверный-токен ^

  --from-email "Магазин <support@yourdomain.com>"
```

На Linux / macOS символ переноса `^` замените на `\` в конце строки или напишите команду в одну строку.

При успехе в консоли:

```
Email request sent successfully.
```

### 6.7. Отправка из Django shell

Если проект уже настроен:

```
python manage.py shell
```

В интерактивной консоли:

```
from django.core.mail import send_mail

send_mail("Тест", "Текст", "support@yourdomain.com", ["recipient@example.com"])
```

---

## 7. Интеграция с Flask

Backend `anymail_haskimail` **не работает** с Flask напрямую, потому что завязан на `django.conf.settings` и `django.core.mail`.

Для Flask используйте тот же HTTP API, что и в `send_haskimail.py`: библиотека `requests`, заголовок `X-Haskimail-Server-Token`, endpoint `/email`.

### 7.1. Установка

```
pip install flask requests
```

### 7.2. Пример файла app_flask.py

Создайте в удобном каталоге файл **app_flask.py** со следующим содержимым:

```
import os

import requests

from flask import Flask, jsonify, request

app = Flask(__name__)

HASKIMAIL_TOKEN = os.environ["HASKIMAIL_API_KEY"]

HASKIMAIL_URL = "https://api.haskimail.ru/email"

def send_via_haskimail(*, from_addr: str, to: str, subject: str, text: str, html: str = "") -> dict:

    headers = {

        "Accept": "application/json",

        "Content-Type": "application/json",

        "X-Haskimail-Server-Token": HASKIMAIL_TOKEN.strip(),

    }

    body = {

        "From": from_addr,

        "To": to,

        "Subject": subject,

        "TextBody": text or "(empty)",

    }

    if html:

        body["HtmlBody"] = html

    resp = requests.post(HASKIMAIL_URL, headers=headers, json=body, timeout=60)

    resp.raise_for_status()

    return resp.json() if resp.content else {"status": "ok"}

@app.post("/send-test")

def send_test():

    data = request.get_json(force=True)

    result = send_via_haskimail(

        from_addr=data["from"],

        to=data["to"],

        subject=data.get("subject", "Test"),

        text=data.get("text", "Hello from Flask"),

        html=data.get("html", ""),

    )

    return jsonify(result)

if __name__ == "__main__":

    app.run(debug=True, port=5000)
```

### 7.3. Запуск сервера Flask

**Windows:**

```
$env:HASKIMAIL_API_KEY = "ваш-серверный-токен"

python app_flask.py
```

**Linux / macOS:**

```
export HASKIMAIL_API_KEY="ваш-серверный-токен"

python app_flask.py
```

Сервер будет доступен по адресу: <http://127.0.0.1:5000>

### 7.4. Проверка отправки через curl

```
curl -X POST http://127.0.0.1:5000/send-test ^

  -H "Content-Type: application/json" ^

  -d "{\"from\":\"Магазин <support@yourdomain.com>\",\"to\":\"recipient@example.com\",\"subject\":\"Тест\",\"text\":\"Привет\"}"
```

На Linux / macOS уберите символ `^` и экранирование кавычек подставьте по правилам вашей оболочки.

### 7.5. Встраивание в свой код Flask (без HTTP-роута)

Функцию `send_via_haskimail` можно вызывать из любого view или фоновой задачи:

```
send_via_haskimail(

    from_addr="support@yourdomain.com",

    to="customer@example.com",

    subject="Уведомление",

    text="Текст уведомления",

)
```

---

## 8. Какой способ выбрать

**send_haskimail.py**

Используйте для первой проверки ключа, отладки, cron-задач и разовых скриптов. Не требует Django и Flask.

**Django + anymail_haskimail**

Используйте, если проект уже на Django: формы, админка, сигналы, Celery с `send_mail`.

**send_test_email.py**

Используйте, чтобы проверить только Django-backend, когда полного проекта ещё нет.

**Flask + requests**

Используйте для приложений на Flask; логика совпадает с `send_haskimail.py`, но встроена в веб-приложение.

**Разница endpoint’ов:** скрипт `send_haskimail.py` ходит на `/email` с заголовком `X-Haskimail-Server-Token` (как официальный PHP-клиент). Django-backend в репозитории настроен на `/v1/messages/send`. Если при работе с Django получаете 401, сначала убедитесь, что `send_haskimail.py` с тем же токеном работает; затем сверьте настройки `ANYMAIL` и документацию API.

---

## 9. Частые ошибки и их решение

### Ошибка: HTTP 401, «Серверный API-ключ в вашем запросе невалидный»

**Возможные причины:**

* скопирован не Server Token, а другой ключ;

* в `.env` лишние пробелы, кавычки или перенос строки;

* для endpoint `/email` нужен заголовок `X-Haskimail-Server-Token`, а не `Authorization: Bearer`;

* токен от другого сервера/канала.

**Что сделать:**

1. Проверьте отправку через `send_haskimail.py` с тем же токеном.

2. Пересоздайте или скопируйте токен заново из личного кабинета.

3. Убедитесь, что в переменной окружения нет кавычек: `HASKIMAIL_API_KEY=abc123`, а не `HASKIMAIL_API_KEY="abc123"`.

### Ошибка: ModuleNotFoundError: No module named 'anymail_haskimail'

**Что сделать:** запускайте Python из каталога `haskimail_rocketmail` или добавьте этот каталог в `PYTHONPATH` (см. п. 6.3).

### Письмо «отправилось», но не пришло получателю

**Что проверить:**

* адрес в `From` подтверждён в Haskimail;

* письмо не попало в спам;

* домен отправителя настроен (SPF/DKIM по инструкции Haskimail).

### Ошибка при активации venv в Windows

Если PowerShell блокирует скрипты, выполните один раз от администратора:

```
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```

Либо используйте cmd и `activate.bat`.

### Django: письмо не уходит, ошибок нет

Проверьте `EMAIL_BACKEND` в активном `settings.py` (тот модуль, который реально загружает `DJANGO_SETTINGS_MODULE`). Включите `fail_silently=False` в `send_mail`.