Клієнти бачать чесний стан очікування або повторного підключення, а прийняті повідомлення не дублюються й не зникають непомітно.
Використовуйте стабільні idempotency keys
Створюйте один idempotency key для кожного наміру клієнта й зберігайте його, доки SDK не повідомить про прийнятий результат. Нативний рушій зберігає точне тіло запиту, час і ключ у довговічному outbox акаунта до завершення операції запису. Не створюйте новий ключ лише через затримку підтвердження.
Вебвіджет сам показує клієнтський стан повторного підключення й очікування. Мобільні headless-клієнти надають resumeSession, refresh і flushOutbox, щоб хост міг показати явний повтор після отримання свіжого токена для того самого акаунта. Наведений код використовує форму TypeScript-обгортки (startSession(message, options) і sendMessage(text, idempotencyKey)). У Dart це ті самі операції з sendMessage(text, idempotencyKey: key). Прямі Swift- та Kotlin-клієнти використовують свої платформні DTO з тим самим правилом стабільного ключа, як показано у відповідних довідниках платформ.
const sessionKey = `order-${orderId}-session-${attemptId}`;
const messageKey = `order-${orderId}-question-${attemptId}`;
// Persist each key with its own user intent until the SDK acknowledges it.
await client.startSession("I need help with my order", {
idempotencyKey: sessionKey,
});
await client.sendMessage("The order number is ORD-42", messageKey);
// Call this only from an explicit "Retry the same message" control after
// connectivity and a fresh token for the same account are available.
async function retryPendingMessage() {
await client.resumeSession();
await client.flushOutbox();
}Розрізняйте очікуваний, відхилений і дубльований результат
Помилка мережі або обмеження частоти можуть залишити прийняття непевним, тому зберігайте початкову мутацію для явного повтору з тим самим ключем. Помилки field-invalid, payload-too-large, message-rejected або idempotency-conflict потребують виправлення хоста чи перевірки й не можуть автоматично повторюватися з іншим ключем.
Результат session-expired вимагає свіжого підписаного токена для того самого акаунта перед повтором. Не викликайте resetSession через тимчасовий збій: reset навмисно очищає довговічну сесію та незавершені мутації.
Показуйте офлайн-стан
- Покажіть мітку очікування або повторного підключення, пов'язану зі станом завантаження SDK, і залишайте composer доступним лише коли хост безпечно може прийняти новий намір.
- Запропонуйте Retry the same message після відновлення з'єднання й автентифікації. Збережіть початковий idempotency key за кнопкою та вимикайте повторне надсилання, поки дія виконується.
- Якщо клієнт свідомо відкидає розмову, викличте resetSession і явно покажіть результат відкидання. Ніколи не очищайте довговічний стан лише через переведення застосунку у фон.