| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- package com.example.modifier.http.api
- import android.util.Log
- import com.example.modifier.baseTag
- import com.example.modifier.http.isTimeoutException
- import com.example.modifier.http.ktorClient
- import com.example.modifier.http.request.RcsNumberRequest
- import com.example.modifier.http.response.RcsNumberResponse
- import io.ktor.client.call.body
- import io.ktor.client.plugins.resources.get
- import io.ktor.client.plugins.resources.post
- import io.ktor.client.plugins.resources.put
- import io.ktor.client.plugins.retry
- import io.ktor.client.plugins.timeout
- import io.ktor.client.request.setBody
- import io.ktor.http.ContentType
- import io.ktor.http.contentType
- import io.ktor.resources.Resource
- import kotlinx.coroutines.CoroutineScope
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.coroutineScope
- import kotlinx.coroutines.delay
- import kotlinx.coroutines.launch
- import kotlinx.coroutines.withTimeoutOrNull
- import kotlin.coroutines.cancellation.CancellationException
- import kotlin.coroutines.coroutineContext
- import kotlin.time.Duration.Companion.seconds
- @Resource("api/rcs-number")
- class RcsNumberApi() {
- @Resource("{id}")
- class Id(val parent: RcsNumberApi = RcsNumberApi(), val id: Int) {
- @Resource("delete")
- class Delete(val parent: Id)
- @Resource("otpState")
- class OtpState(val parent: Id)
- @Resource("configured")
- class Configured(val parent: Id)
- @Resource("wasted")
- class Wasted(val parent: Id)
- @Resource("stockFlag/{flag}")
- class UpdateStockFlag(val parent: Id, val flag: Int)
- }
- companion object {
- private const val TAG = "$baseTag/RcsNumberApi"
- suspend fun getRcsNumber(
- deviceId: String,
- taskId: Int? = null,
- pinCountry: String?,
- store: Boolean? = false
- ): RcsNumberResponse {
- val req = RcsNumberRequest(
- deviceId = deviceId,
- taskId = taskId,
- country = pinCountry,
- store = store
- )
- val response = ktorClient.put(RcsNumberApi()) {
- contentType(ContentType.Application.Json)
- setBody(req)
- timeout {
- requestTimeoutMillis = 60 * 1000
- socketTimeoutMillis = 60 * 1000
- }
- retry {
- maxRetries = 3600
- retryOnExceptionIf { _, cause ->
- when {
- cause.isTimeoutException() -> true
- cause is CancellationException -> false
- else -> true
- }
- }
- retryIf { _, response ->
- response.status.value.let {
- when (it) {
- 425, 429, 502, 503, 504 -> true
- else -> false
- }
- }
- }
- delayMillis { 1000 }
- }
- }
- return response.body<RcsNumberResponse>()
- }
- fun notifyOtpState(id: Int) {
- CoroutineScope(Dispatchers.IO).launch {
- runCatching {
- ktorClient.post(Id.OtpState(Id(RcsNumberApi(), id)))
- }.onFailure { e ->
- Log.e(TAG, "Send OtpState Error: ${e.message}", e)
- }
- }
- }
- fun notifyConfigured(id: Int) {
- CoroutineScope(Dispatchers.IO).launch {
- runCatching {
- ktorClient.post(Id.Configured(Id(RcsNumberApi(), id)))
- }.onFailure { e ->
- Log.e(TAG, "Send Configured Error: ${e.message}", e)
- }
- }
- }
- suspend fun notifyWasted(id: Int) {
- CoroutineScope(coroutineContext).launch {
- runCatching {
- ktorClient.post(Id.Wasted(Id(RcsNumberApi(), id)))
- }.onFailure { e ->
- Log.e(TAG, "Send Wasted Error: ${e.message}", e)
- }
- }
- }
- suspend fun waitForOtp(id: Int): String? {
- return withTimeoutOrNull(60.seconds) {
- while (true) {
- runCatching {
- val rcsNumber =
- ktorClient.get(Id(id = id))
- .body<RcsNumberResponse>()
- Log.i(TAG, "wait for otp response: $rcsNumber")
- if (rcsNumber.status == RcsNumberResponse.STATUS_SUCCESS) {
- val match = Regex("Your Messenger verification code is G-(\\d{6})")
- .find(rcsNumber.message!!)
- if (match != null) {
- val otp = match.groupValues[1]
- Log.i(TAG, "OTP: $otp")
- return@withTimeoutOrNull otp
- }
- } else if (rcsNumber.status == RcsNumberResponse.STATUS_EXPIRED) {
- return@withTimeoutOrNull null
- }
- }.onFailure { e ->
- Log.e(TAG, "wait for otp Error: ${e.stackTrace}")
- }
- delay(2.seconds)
- }
- null
- }
- }
- suspend fun updateStockFlag(id: Int, flag: Int) {
- try {
- ktorClient.put(Id.UpdateStockFlag(Id(RcsNumberApi(), id), flag))
- } catch (e: Exception) {
- Log.e(TAG, "Update Stock Flag Error: ${e.message}", e)
- }
- }
- }
- }
|