Skip to navigation

Как избежать повторной отправки?

Идемпотентность и учёт состояния.

Ретраи из-за сети или багов могут отправить одно письмо дважды. Ниже — как это предотвратить.

Создание ресурсов: clientId

Для create (ящики, pod, webhook, черновики) передайте clientId: если ресурс уже есть, API вернёт его, а не создаст дубликат.

TypeScript
import { AgentinboxClient } from "agentinbox";
const client = new AgentinboxClient({ apiKey: "am_..." });
const inbox = await client.inboxes.create({
username: "support",
clientId: "support-inbox-v1",
});
const sameInbox = await client.inboxes.create({
username: "support",
clientId: "support-inbox-v1",
});

Отправка писем: не через clientId на send

messages.send без встроенной идемпотентности ключа — логика в приложении.

Метки как состояние

TypeScript
const threads = await client.inboxes.threads.list(inbox.inboxId, {
labels: ["unreplied"],
});
for (const thread of threads.threads) {
const detail = await client.threads.get(thread.threadId);
const lastMessage = detail.messages[detail.messages.length - 1];
await client.inboxes.messages.reply(inbox.inboxId, lastMessage.messageId, {
text: "Thanks for reaching out!",
});
await client.inboxes.messages.update(inbox.inboxId, lastMessage.messageId, {
addLabels: ["replied"],
removeLabels: ["unreplied"],
});
}

Черновики для критичных писем

TypeScript
const draft = await client.inboxes.drafts.create(inbox.inboxId, {
to: ["customer@example.com"],
subject: "Order confirmation",
text: "Your order has been confirmed.",
html: "<p>Your order has been confirmed.</p>",
clientId: "order-123-confirmation",
});
const sent = await client.inboxes.drafts.send(inbox.inboxId, draft.draftId);

После отправки черновик удаляется — повторный send не продублирует письмо.

Практика

  • clientId на всех create из бизнес-логики (order-${id}-...), не случайный UUID
  • Метки против двойной обработки одного сообщения
  • Черновики там, где дубликат недопустим

Подробнее: Идемпотентность.