forked from shihaam/thijooree
implement viewing contacts
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
package sh.sar.basedbank.api.mib
|
||||
|
||||
import android.util.Log
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.json.JSONObject
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class MibContactsClient {
|
||||
|
||||
private val TAG = "MibContactsClient"
|
||||
private val BASE_WV_URL = "https://faisamobilex-wv.mib.com.mv"
|
||||
|
||||
private val client = OkHttpClient.Builder()
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
private fun cookieHeader(session: MibSession) =
|
||||
"mbmodel=IOS-1.0; xxid=${session.xxid}; IBSID=${session.xxid}; " +
|
||||
"mbnonce=${session.nonceGenerator}; time-tracker=597"
|
||||
|
||||
private fun Request.Builder.withSessionHeaders(session: MibSession): Request.Builder = this
|
||||
.header("Cookie", cookieHeader(session))
|
||||
.header(
|
||||
"User-Agent",
|
||||
"Mozilla/5.0 (Linux; Android 14; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.70 Mobile Safari/537.36"
|
||||
)
|
||||
.header("X-Requested-With", "XMLHttpRequest")
|
||||
.header("Accept", "*/*")
|
||||
.header("Origin", BASE_WV_URL)
|
||||
.header("Referer", "$BASE_WV_URL/beneficiary?dashurl=1")
|
||||
|
||||
fun fetchCategories(session: MibSession): List<MibBeneficiaryCategory> {
|
||||
val request = Request.Builder()
|
||||
.url("$BASE_WV_URL/ajaxBeneficiary/getCategories")
|
||||
.post(FormBody.Builder().build())
|
||||
.withSessionHeaders(session)
|
||||
.build()
|
||||
|
||||
return client.newCall(request).execute().use { response ->
|
||||
Log.d(TAG, "getCategories: HTTP ${response.code}")
|
||||
if (!response.isSuccessful) return emptyList()
|
||||
parseCategories(response.body?.string() ?: return emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseCategories(json: String): List<MibBeneficiaryCategory> {
|
||||
return try {
|
||||
val arr = JSONObject(json).getJSONArray("data")
|
||||
(0 until arr.length()).map { i ->
|
||||
val o = arr.getJSONObject(i)
|
||||
MibBeneficiaryCategory(
|
||||
id = o.getString("id"),
|
||||
categoryName = o.getString("categoryName"),
|
||||
numBenef = o.optString("numBenef", "0").toIntOrNull() ?: 0
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "parseCategories error: $e")
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchContacts(session: MibSession): List<MibBeneficiary> {
|
||||
val all = mutableListOf<MibBeneficiary>()
|
||||
var page = 1
|
||||
val pageSize = 100
|
||||
while (true) {
|
||||
val start = (page - 1) * pageSize + 1
|
||||
val end = page * pageSize
|
||||
val body = FormBody.Builder()
|
||||
.add("page", page.toString())
|
||||
.add("search", "")
|
||||
.add("searchCategoryId", "0")
|
||||
.add("benefType", "A")
|
||||
.add("sortBenef", "name")
|
||||
.add("sortDir", "asc")
|
||||
.add("start", start.toString())
|
||||
.add("end", end.toString())
|
||||
.add("includeCount", "1")
|
||||
.build()
|
||||
|
||||
val request = Request.Builder()
|
||||
.url("$BASE_WV_URL/ajaxBeneficiary/main")
|
||||
.post(body)
|
||||
.withSessionHeaders(session)
|
||||
.build()
|
||||
|
||||
val (contacts, totalCount) = client.newCall(request).execute().use { response ->
|
||||
Log.d(TAG, "fetchContacts page $page: HTTP ${response.code}")
|
||||
if (!response.isSuccessful) return all
|
||||
parseContacts(response.body?.string() ?: return all)
|
||||
}
|
||||
all.addAll(contacts)
|
||||
if (all.size >= totalCount || contacts.isEmpty()) break
|
||||
page++
|
||||
}
|
||||
Log.d(TAG, "fetchContacts: loaded ${all.size} contacts")
|
||||
return all
|
||||
}
|
||||
|
||||
private fun parseContacts(json: String): Pair<List<MibBeneficiary>, Int> {
|
||||
return try {
|
||||
val obj = JSONObject(json)
|
||||
val totalCount = obj.optString("total_count", "0").toIntOrNull() ?: 0
|
||||
val arr = obj.getJSONArray("data")
|
||||
val contacts = (0 until arr.length()).map { i ->
|
||||
val o = arr.getJSONObject(i)
|
||||
val hash = o.optString("customerImgHash")
|
||||
MibBeneficiary(
|
||||
benefNo = o.optString("benefNo"),
|
||||
benefName = o.optString("benefName"),
|
||||
benefNickName = o.optString("benefNickName")
|
||||
.ifBlank { o.optString("benefName") },
|
||||
benefAccount = o.optString("benefAccount"),
|
||||
benefType = o.optString("benefType"),
|
||||
bankColor = o.optString("bankColor", "#888888"),
|
||||
benefBankName = o.optString("benefBankName"),
|
||||
bankCode = o.optString("bankCode"),
|
||||
benefStatus = o.optString("benefStatus"),
|
||||
transferCyDesc = o.optString("transferCyDesc", "MVR"),
|
||||
customerImgHash = hash.takeIf { it.isNotBlank() && it != "null" },
|
||||
benefCategoryId = o.optString("benefCategoryID", "0")
|
||||
)
|
||||
}
|
||||
Pair(contacts, totalCount)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "parseContacts error: $e")
|
||||
Pair(emptyList(), 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchProfileImageBase64(session: MibSession, imageHash: String): String? {
|
||||
val body = FormBody.Builder()
|
||||
.add("imageHash", imageHash)
|
||||
.build()
|
||||
val request = Request.Builder()
|
||||
.url("$BASE_WV_URL/ajaxBeneficiary/getProfileImage")
|
||||
.post(body)
|
||||
.withSessionHeaders(session)
|
||||
.build()
|
||||
|
||||
return client.newCall(request).execute().use { response ->
|
||||
if (!response.isSuccessful) return null
|
||||
try {
|
||||
val json = response.body?.string() ?: return null
|
||||
JSONObject(json).optString("profileImage").takeIf { it.isNotBlank() }
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,27 @@ data class MibAccount(
|
||||
val statusDesc: String
|
||||
)
|
||||
|
||||
data class MibBeneficiaryCategory(
|
||||
val id: String,
|
||||
val categoryName: String,
|
||||
val numBenef: Int
|
||||
)
|
||||
|
||||
data class MibBeneficiary(
|
||||
val benefNo: String,
|
||||
val benefName: String,
|
||||
val benefNickName: String,
|
||||
val benefAccount: String,
|
||||
val benefType: String, // L=Local, I=Internal(MIB), S=Swift
|
||||
val bankColor: String,
|
||||
val benefBankName: String,
|
||||
val bankCode: String,
|
||||
val benefStatus: String,
|
||||
val transferCyDesc: String,
|
||||
val customerImgHash: String?,
|
||||
val benefCategoryId: String // "0" = uncategorized
|
||||
)
|
||||
|
||||
data class MibFinanceDeal(
|
||||
val dealNo: String,
|
||||
val productDesc: String,
|
||||
|
||||
Reference in New Issue
Block a user