Сергей

Сергей

Обновлено Nov 5, 2026

В этом руководстве — как отправлять письма через Haskimail из приложений на Django и Flask. Есть два способа:

  • SMTP — самый простой для Django: используется встроенный почтовый механизм, код почти не меняется.
  • HTTP API — даёт больше возможностей: каналы, теги, метаданные, шаблоны, пакетная отправка. Подходит и для Django, и для Flask.

Для Python есть и официальная библиотека (pip install haskimail), но в примерах ниже используется только requests, чтобы было видно, что именно отправляется в API.

Что нужно подготовить

  1. Подтверждённый адрес отправителя или домен. Адрес в поле «От кого» должен быть подтверждён в разделе «Домены и отправители». Пока аккаунт на модерации, письма можно отправлять только на адреса подтверждённых доменов.
  2. Данные для подключения:
    • для SMTP — SMTP-реквизиты канала (логин и пароль) из настроек канала отправки;
    • для API — серверный API-ключ: SMTP-серверы → ваш сервер → API-ключи.
  3. Python 3.10 или новее.

Храните ключи и пароли в переменных окружения или менеджере секретов, а не в коде и не в репозитории.

Django через SMTP

В settings.py:

import os

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.haskimail.ru"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ["HASKIMAIL_SMTP_LOGIN"]
EMAIL_HOST_PASSWORD = os.environ["HASKIMAIL_SMTP_PASSWORD"]
DEFAULT_FROM_EMAIL = "Магазин <support@example.ru>"

Если хотите использовать порт 465, замените EMAIL_PORT = 465 и EMAIL_USE_TLS = True на EMAIL_USE_SSL = True.

Теперь письма отправляются обычными средствами Django:

from django.core.mail import send_mail

send_mail(
    subject="Заказ оформлен",
    message="Спасибо за заказ!",
    from_email=None,  # будет использован DEFAULT_FROM_EMAIL
    recipient_list=["customer@example.com"],
    fail_silently=False,
)

Письмо с HTML-версией:

from django.core.mail import EmailMultiAlternatives

msg = EmailMultiAlternatives(
    subject="Заказ оформлен",
    body="Спасибо за заказ! Детали — в личном кабинете.",
    to=["customer@example.com"],
)
msg.attach_alternative("<h1>Спасибо за заказ</h1>", "text/html")
msg.send()

Письма уходят через канал, чьи SMTP-реквизиты вы указали. Для транзакционных писем и рассылок используйте разные каналы.

Отправка через HTTP API (Django и Flask)

Функция для отправки одного письма:

import os
import requests

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

def send_via_haskimail(*, from_addr, to, subject, text, html=None, stream=None):
    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "X-Haskimail-Server-Token": os.environ["HASKIMAIL_SERVER_TOKEN"],
    }
    body = {"From": from_addr, "To": to, "Subject": subject, "TextBody": text}
    if html:
        body["HtmlBody"] = html
    if stream:
        body["MessageStream"] = stream  # ID канала; без него — транзакционный канал

    resp = requests.post(HASKIMAIL_URL, headers=headers, json=body, timeout=30)
    data = resp.json()
    if resp.status_code != 200 or data.get("ErrorCode") != 0:
        raise RuntimeError(f"Haskimail: {data.get('ErrorCode')} {data.get('Message')}")
    return data["MessageID"]

Функция возвращает MessageID письма — сохраните его, чтобы связывать письмо с событиями доставки, открытий и кликов. Если письмо не принято, API отвечает HTTP 422 с кодом ошибки — что означают коды, рассказываем в статье «Ответ API при отправке письма и коды ошибок».

Вызывайте функцию из view, фоновой задачи (Celery, RQ) или скрипта:

send_via_haskimail(
    from_addr="Магазин <support@example.ru>",
    to="customer@example.com",
    subject="Заказ оформлен",
    text="Спасибо за заказ!",
    html="<p>Спасибо за заказ!</p>",
)

Пример для Flask

from flask import Flask

app = Flask(__name__)

@app.post("/orders/<int:order_id>/confirm")
def confirm_order(order_id):
    # ... ваша логика оформления заказа ...
    send_via_haskimail(
        from_addr="Магазин <support@example.ru>",
        to="customer@example.com",
        subject=f"Заказ №{order_id} оформлен",
        text=f"Спасибо! Ваш заказ №{order_id} принят.",
    )
    return {"status": "ok"}

Важно: не создавайте в приложении публичный адрес, который отправляет письма на любой адрес из запроса. Через такой адрес кто угодно сможет рассылать спам от вашего имени. Отправляйте письма только в ответ на конкретные действия пользователя, а в рабочей среде не запускайте Flask с debug=True.

Проверка без реальной отправки

Чтобы проверить код без отправки писем, передайте вместо серверного ключа тестовый — HASKIMAIL_API_TEST. API проверит запрос и вернёт ответ в обычном формате, но письмо никуда не уйдёт. Чтобы проверить отправку целиком, используйте сервер «Песочница».

Частые ошибки

ErrorCode 10 «Неверный API-ключ»

  • Используется не серверный ключ, а ключ аккаунта или ключ другого сервера.
  • В переменной окружения лишние пробелы, кавычки или перенос строки.
  • Ключ передан в заголовке Authorization: Bearer — нужен X-Haskimail-Server-Token.

SMTP: ошибка авторизации

  • Проверьте, что указаны SMTP-реквизиты канала, а не API-ключ.
  • Проверьте, что для сервера включена отправка по SMTP.

SMTP: не удаётся подключиться

Письмо отправлено, но не дошло

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