Skip to content

Webhook Mapping and Retry Strategy

KrugarValdes edited this page Jan 19, 2026 · 1 revision

Webhook Mapping and Retry Strategy

This guide describes how the SMS Router maps incoming SMS data into webhook payloads and how the retry subsystem guarantees delivery with logging and callbacks.

Overview

  • Per-SIM configuration defines webhook URL, bearer token, service type, and (for Telegram) chat ID.
  • SmsDataDtoMapper transforms domain models into service-specific DTOs before they reach the HTTP layer.
  • SmsApiService applies a bounded retry policy (3 attempts, 60-second cap) with exponential-ish delays and real-time callbacks.
  • SmsLogsRepository captures each delivery attempt so the UI reflects IN_PROGRESS, DELIVERED, or ERROR states with retry counts.

System Diagram

webhook-flow.svg

Webhook Type Mapping

Webhook Type Payload Structure Required Fields
MATTERMOST { "text": "message" } text
TELEGRAM { "chat_id": "id", "text": "message" } chat_id, text

Mapping rules:

  • SmsDataDtoMapper inspects the SIM configuration and builds the correct DTO.
  • Telegram mapping fails fast if chatId is missing; errors bubble to the use case so the UI can warn operators.
  • Additional webhook types can extend the mapper contract by providing a new DTO and update logic.

Webhook Configuration

Each SIM card stores its configuration in SharedPreferences:

Setting Description
webhookUrl Destination HTTP endpoint
secretKey Bearer token inserted into Authorization header
webhookType Enum controlling DTO selection
chatId Telegram-only chat identifier

Retry Strategy

retry-flow.svg

Parameter Value Notes
Max Attempts 3 Initial + two retries
Global Timeout 60 seconds Stops retries once exceeded
Retry Tracking In-memory map keyed by SMS ID Resets when process restarts

Retry timing:

  1. Attempt #1 (initial send)
  2. Attempt #2 after ~5 seconds delay
  3. Attempt #3 after ~15 seconds delay (cumulative ~20s)
  4. If still failing but within timeout, final attempt occurs ~40s after start

Callbacks & Logging

  • SmsApiService emits onRetry(smsId, attempt) so the Messages UI can show live status updates.
  • Every attempt updates the log entry with the latest retryCount, HTTP status code, and optional error message.
  • Final success sets status to DELIVERED; exhausting attempts sets status to ERROR with diagnostics.

HTTP Request Configuration

Property Value
Method POST
Content-Type application/json
Authorization Bearer <secretKey>
Body Mapper-produced DTO

Error Handling

  • Retry stops early if the accumulated elapsed time crosses 60 seconds.
  • Errors include HTTP status, exception message, and retry counts; these help operators debug via the Messages screen or Logcat.
  • Authentication mistakes (invalid bearer token) surface immediately, allowing configuration fixes without waiting for timeout.

Development Guidelines

  • Adding webhook types: extend WebhookType, create DTO, update mapper, add configuration fields, and write mapper tests.
  • Changing retry policy: adjust the constants inside SmsApiService; keep UI aware of maximum attempts for messaging.
  • Testing: use mocked Ktor clients to simulate HTTP codes/timeouts, and verify that logs, callbacks, and mapper outputs behave as expected.

Troubleshooting

Symptom Likely Cause Action
Delivery failures Missing/invalid webhook URL Update SIM configuration
Authentication errors Wrong secretKey Re-enter correct token
Telegram failures chatId missing Provide valid chat ID
Retry counters never increment Callback not registered or mapper threw Check use case wiring and logs

Clone this wiki locally