Skip to content

SMS Router Client Application

KrugarValdes edited this page Jan 19, 2026 · 1 revision

SMS Router Client Application

Purpose and Scope

This document covers the overall architecture, structure, and configuration of the Effective Office SMS Router client application. This is an Android application that serves as a message forwarding service, intercepting incoming SMS messages and forwarding them to configured webhooks (Mattermost, Telegram) with per-SIM configuration, delivery logging, and retry mechanisms.

Technology Stack

Component Technology / Library Notes
Language / Runtime Kotlin, JVM 17 Android application development
UI Framework Jetpack Compose Modern declarative UI for settings and message screens
Dependency Injection Koin Service locator–based dependency injection
Networking Ktor Client HTTP client for webhook requests
Database Room Local storage for SMS delivery logs
State Management ViewModel + LiveData Reactive state management
Build Tooling Gradle 8.x Project build configuration

Application Architecture

Overall Structure

The SMS Router follows a clean architecture pattern with clear separation of concerns between data, domain, and presentation layers.

overall-structure.svg

Component Architecture

component-architecture.svg

Data Flow and Processing

Source Processing Path Purpose
SMS Receiver BroadcastReceiver → ForwardSmsUseCase → SmsApiService Intercept and forward SMS messages
Settings UI SettingsViewModel → SettingsRepository → SharedPreferences Persist per-SIM configuration
Delivery Logs SmsLogsRepository → Room Database → Messages UI Track forwarding status and history

The application processes SMS messages through a pipeline that includes interception, transformation, forwarding with retry logic, and persistent logging of delivery status.

UI Flow and Navigation

  • MainActivity: Entry point that initializes Koin dependency injection and hosts the Compose UI
  • Settings Screen: Allows configuration of per-SIM webhook URLs, secret keys, webhook types, and Telegram chat IDs
  • Messages Screen: Displays delivery logs and forwarding status with real-time updates
  • Permission Management:: Runtime permission requests for SMS-related permissions

Module Organization

Build Configuration

Key Android configuration extracted from app/build.gradle.kts:

android {  
    namespace = "band.effective.office.smsrouter"  
    compileSdk = 34  
    defaultConfig {  
        applicationId = "band.effective.office.smsrouter"  
        minSdk = 24  
        targetSdk = 33  
        versionCode = 3  
        versionName = "1.0.0"  
    }  
    buildFeatures {   
        compose = true   
        buildConfig = true  
    }  
}  

Dependency Structure

Module Category Modules Dependencies
Application app Core modules, shared module
Core data, domain, presentation External libraries, Room, Ktor

Main Application Structure

components-and-interactions.svg

Key Components

The application is organized around several key components:

  • SmsReceiver: Stack navigation between Welcome, Menu, and Autoplay surfaces
  • ForwardSmsUseCase: Creation and destruction of child components using Decompose
  • SmsApiServiceImpl: Performs HTTP requests to webhooks with retry logic and timeout handling
  • SettingsViewModel: Manages UI state for per-SIM configuration
  • SmsLogsRepository: Persists and retrieves delivery logs from Room database

Settings Management

manage-settings.svg

The settings system uses SharedPreferences for per-SIM configuration:

class SettingsViewModel(  
    private val settingsRepository: SettingsRepository,  
    private val simcardProvider: SimCardProvider,  
) : ViewModel() {  
    // Handle intents from the UI  
    fun sendIntent(intent: Intent) {  
        when (intent) {  
            is Intent.UpdateWebhookUrl -> updateWebhookUrl(intent.simId, intent.url)  
            is Intent.UpdateSecretKey -> updateSecretKey(intent.simId, intent.key)  
            is Intent.UpdateWebhookType -> updateWebhookType(intent.simId, intent.webhookType)  
            is Intent.UpdateChatId -> updateChatId(intent.simId, intent.chatId)  
            is Intent.SaveSettings -> saveSettings()  
        }  
    }  
}

Configuration and Secrets

The application uses runtime configuration for webhook settings:

Configuration Storage Purpose
Webhook URLs SharedPreferences Target endpoints for SMS forwarding
Secret Keys SharedPreferences Authentication for webhook requests
Webhook Types SharedPreferences Mattermost vs Telegram payload format
Telegram Chat IDs SharedPreferences Target chat for Telegram messages

Webhook requests include Authorization: Bearer header and format-specific payloads:

  • Mattermost: { "text": "" }
  • Telegram: { "chat_id": "", "text": "" }

Clone this wiki locally