Conectarse con el backend
Integración de la interfaz de usuario con los puntos finales del backend
En el módulo anterior construimos la interfaz de usuario y una pequeña máquina de estados de interfaz de usuario (VerifyUiState). Ahora conectaremos esa UI a nuestro backend.
La idea principal es que la aplicación para Android nunca llamará a Vonage directamente. Solo llamará a tu backend:
-
POST /verificationpara iniciar el proceso de verificación -
POST /check-codepara validar un código (código SMS por ahora) -
POST /nextpara forzar el uso del canal alternativo (SMS) de forma inmediata (y así no tener que esperar unos 20 segundos)
Empecemos por la aplicación.
Iniciar verificación (POST /verification)
Cuando el usuario pulsa Iniciar la verificación:
-
La aplicación envía el número de teléfono a
/verification -
El backend devuelve:
request_id(siempre)check_url(opcional; se utiliza más adelante para la autenticación silenciosa)
-
En esta sección, omitiremos la autenticación silenciosa y solicitaremos inmediatamente el retorno a SMS llamando a
/next -
La interfaz de usuario pasa a la pantalla SMS (
EnterSms(requestId))
private suspend fun startVerification(phone: String): Pair<String, String?> = withContext(Dispatchers.IO) {
val client = OkHttpClient()
val json = Gson().toJson(mapOf("phone" to phone))
val requestBody = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$BACKEND_URL/verification")
.post(requestBody)
.build()
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
val errorBody = response.body?.string() ?: "Unknown error"
throw IOException("Start verification failed: HTTP ${response.code} - $errorBody")
}
val body = response.body?.string() ?: throw IOException("Empty response body")
val jsonBody = Gson().fromJson(body, JsonObject::class.java)
val requestId = jsonBody.get("request_id")?.asString ?: throw IOException("Missing request_id")
val checkUrl = jsonBody.get("check_url")?.asString // may be null
Pair(requestId, checkUrl)
}
Enviar código SMS (POST /check-code)
Cuando el usuario pulsa Enviar código:
- La aplicación envía
{ request_id, code }a/check-code - El backend responde con
{ verified: true/false } - La interfaz de usuario muestra «operación correcta» o «código no válido»
private suspend fun submitCode(requestId: String, code: String): CheckCodeResponse = withContext(Dispatchers.IO) {
val client = OkHttpClient()
val json = Gson().toJson(mapOf("request_id" to requestId, "code" to code))
val requestBody = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$BACKEND_URL/check-code")
.post(requestBody)
.build()
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
val errorBody = response.body?.string() ?: "Unknown error"
throw IOException("Check code failed: HTTP ${response.code} - $errorBody")
}
val body = response.body?.string() ?: throw IOException("Empty response body")
val jsonBody = Gson().fromJson(body, JsonObject::class.java)
CheckCodeResponse(
verified = jsonBody.get("verified")?.asBoolean ?: false,
status = jsonBody.get("status")?.asString
)
}
Forzar el plan alternativo rápidamente (POST /next)
Llamando a /next es opcional desde el punto de vista de la "corrección" (Vonage puede retroceder automáticamente), pero es muy útil para UX:
Si ya sabemos que no vamos a completar la autenticación silenciosa (o aún no la estamos implementando), llamar a /next evita la espera del tiempo de espera de la Autenticación Silenciosa.
private suspend fun requestNextWorkflow(requestId: String): Unit = withContext(Dispatchers.IO) {
val client = OkHttpClient()
val json = Gson().toJson(mapOf("requestId" to requestId))
val requestBody = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$BACKEND_URL/next")
.post(requestBody)
.build()
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
val errorBody = response.body?.string() ?: "Unknown error"
throw IOException("Next workflow failed: HTTP ${response.code} - $errorBody")
}
}
Primeros pasos con la autenticación silenciosa
La autenticación silenciosa lleva bastante tiempo entenderla. Este tutorial te muestra cómo crear una integración desde cero con Node.js y Kotlin.