samotpravil
v0.1.0
Published
Официальный клиент API «Сам Отправил»: отправка, статус, стоп-листы, домены, разбор вебхуков.
Maintainers
Readme
samotpravil (Node)
Официальный клиент API «Сам Отправил» для Node (#21207). Версия 0.1.0, лицензия MIT.
Спецификация: spec.samotpravil.ru/openapi.yaml.
Ключ в заголовке Authorization без префикса.
Для проверки нужны аккаунт и верифицированный домен отправителя (#21204):
бесплатного ключа песочницы нет. Ключ — в SAMOTPRAVIL_API_KEY.
Установка
npm install samotpravilИз монорепо: npm install ./samotpravil-node.
Отправка и статус
import { Samotpravil } from "samotpravil";
const client = new Samotpravil({
apiKey: process.env.SAMOTPRAVIL_API_KEY,
// httpErrors: true, // для v1: настоящие HTTP-коды (?http_errors=1)
});
const sent = await client.send({
email_from: "News <[email protected]>",
email_to: "[email protected]",
subject: "Тема",
message_text: "<p>HTML</p>",
x_track_id: `demo-${Date.now()}`,
});
const status = await client.issueStatus({ messageId: sent.message_id });При 429 / 450, reason лимита или status: throttling клиент ждёт
(retry_after_seconds, иначе экспоненциальная пауза) и повторяет запрос.
Ответ с HTTP 200 и status: error тоже считается отказом.
Пакетная отправка
import { Samotpravil, LIMITS } from "samotpravil";
const client = new Samotpravil({ apiKey: process.env.SAMOTPRAVIL_API_KEY });
const { packIds } = await client.sendPackages({
email_from: "[email protected]",
name_from: "News",
subject: "Привет {{ name }}",
message_text: "<p>Здравствуйте, {{ name }}!</p>",
users: [
{ emailto: "[email protected]", name: "Аня" },
{ emailto: "[email protected]", name: "Боря" },
],
chunkSize: LIMITS.emailsPerPackage, // 100 — ориентир для новой рассылки
// delayMs: Math.ceil(LIMITS.packageWindowMs / LIMITS.packagesPer5Min), // ~7.5 с
});Один пакет без нарезки: client.sendPackage({ …, users }).
Стоп-листы, домены, отчёты
await client.checkAuth();
await client.searchStopList("[email protected]");
await client.addStopList({ email: "[email protected]", domain: "example.com" });
await client.removeStopList({ email: "[email protected]", mailFrom: "[email protected]" });
await client.listStopListUnsubscribes({ limit: 50 });
await client.listStopListFbl();
await client.listStopListFailed({ cursorNext: "1" });
await client.listSenderDomains();
await client.verifySenderDomain("example.com");
await client.addSenderDomain("example.com");
await client.removeSenderDomain("example.com");
await client.reportNonDelivery({ dateFrom: "2026-01-01", dateTo: "2026-01-31", limit: 50 });Вебхуки
Повторов нет, порядок не гарантирован. Две схемы тела: messages (единичная отправка) и xml_messages (пакет). parseWebhook отдаёт один список событий.
import { parseWebhook } from "samotpravil";
app.post("/hook", (req, res) => {
const { events } = parseWebhook(req.body);
for (const event of events) {
// event.email, status, messageId / packId, reason, ttlDate, clickLink
}
res.status(200).end();
});Что ещё не в скелете
- генерация клиента из OpenAPI;
- транспорт Django — это пакет Python;
- публикация в npm (
private: true).
Внутренний рабочий клиент на Python: host_certifier/app/services/samotpravil/.
