Skip to content

Commit 11eea8d

Browse files
committed
Add retry logic for received messages
1 parent a768657 commit 11eea8d

File tree

3 files changed

+63
-11
lines changed

3 files changed

+63
-11
lines changed

android/app/src/main/java/com/httpsms/Constants.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@ package com.httpsms
33
class Constants {
44
companion object {
55
const val KEY_MESSAGE_ID = "KEY_MESSAGE_ID"
6+
const val KEY_MESSAGE_FROM = "KEY_MESSAGE_FROM"
7+
const val KEY_MESSAGE_TO = "KEY_MESSAGE_TO"
8+
const val KEY_MESSAGE_SIM = "KEY_MESSAGE_SIM"
9+
const val KEY_MESSAGE_CONTENT = "KEY_MESSAGE_CONTENT"
10+
const val KEY_MESSAGE_TIMESTAMP = "KEY_MESSAGE_TIMESTAMP"
611
const val KEY_HEARTBEAT_ID = "KEY_HEARTBEAT_ID"
712

813
const val SIM1 = "SIM1"
914
const val SIM2 = "SIM2"
15+
16+
const val TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'000000'ZZZZZ"
1017
}
1118
}

android/app/src/main/java/com/httpsms/HttpSmsApiService.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,13 @@ class HttpSmsApiService(private val apiKey: String, private val baseURL: URI) {
7171
sendEvent(messageId, "FAILED", timestamp, reason)
7272
}
7373

74-
fun receive(sim: String, from: String, to: String, content: String, timestamp: ZonedDateTime) {
75-
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'000000'ZZZZZ")
76-
val timestampString = formatter.format(timestamp).replace("+", "Z")
77-
78-
74+
fun receive(sim: String, from: String, to: String, content: String, timestamp: String): Boolean {
7975
val body = """
8076
{
8177
"content": "${StringEscapeUtils.escapeJson(content)}",
8278
"sim": "$sim",
8379
"from": "$from",
84-
"timestamp": "$timestampString",
80+
"timestamp": "$timestamp",
8581
"to": "$to"
8682
}
8783
""".trimIndent()
@@ -97,12 +93,13 @@ class HttpSmsApiService(private val apiKey: String, private val baseURL: URI) {
9793
if (!response.isSuccessful) {
9894
Timber.e("error response [${response.body?.string()}] with code [${response.code}] while receiving message [${body}]")
9995
response.close()
100-
return
96+
return false
10197
}
10298

10399
val message = ResponseMessage.fromJson(response.body!!.string())
104100
response.close()
105101
Timber.i("received message stored successfully for message with ID [${message?.data?.id}]" )
102+
return true;
106103
}
107104

108105
fun storeHeartbeat(phoneNumber: String, charging: Boolean) {

android/app/src/main/java/com/httpsms/ReceivedReceiver.kt

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,20 @@ import android.content.BroadcastReceiver
44
import android.content.Context
55
import android.content.Intent
66
import android.provider.Telephony
7+
import androidx.work.BackoffPolicy
8+
import androidx.work.Constraints
9+
import androidx.work.Data
10+
import androidx.work.NetworkType
11+
import androidx.work.OneTimeWorkRequest
12+
import androidx.work.WorkManager
13+
import androidx.work.Worker
14+
import androidx.work.WorkerParameters
15+
import androidx.work.workDataOf
716
import timber.log.Timber
817
import java.time.ZoneOffset
918
import java.time.ZonedDateTime
19+
import java.time.format.DateTimeFormatter
20+
import java.util.concurrent.TimeUnit
1021

1122
class ReceivedReceiver: BroadcastReceiver()
1223
{
@@ -58,9 +69,46 @@ class ReceivedReceiver: BroadcastReceiver()
5869
return
5970
}
6071

61-
Thread {
62-
Timber.i("[${sim}] forwarding received message from [${from}]")
63-
HttpSmsApiService.create(context).receive(sim, from, to, content, timestamp)
64-
}.start()
72+
val constraints = Constraints.Builder()
73+
.setRequiredNetworkType(NetworkType.CONNECTED)
74+
.build()
75+
76+
val inputData: Data = workDataOf(
77+
Constants.KEY_MESSAGE_FROM to from,
78+
Constants.KEY_MESSAGE_TO to to,
79+
Constants.KEY_MESSAGE_SIM to sim,
80+
Constants.KEY_MESSAGE_CONTENT to content,
81+
Constants.KEY_MESSAGE_TIMESTAMP to DateTimeFormatter.ofPattern(Constants.TIMESTAMP_PATTERN).format(timestamp).replace("+", "Z")
82+
)
83+
84+
val work = OneTimeWorkRequest
85+
.Builder(ReceivedSmsWorker::class.java)
86+
.setConstraints(constraints)
87+
.setInputData(inputData)
88+
.build()
89+
90+
WorkManager
91+
.getInstance(context)
92+
.enqueue(work)
93+
94+
Timber.d("work enqueued with ID [${work.id}] for received message from [${from}] to [${to}]")
95+
}
96+
97+
internal class ReceivedSmsWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
98+
override fun doWork(): Result {
99+
Timber.i("[${this.inputData.getString(Constants.KEY_MESSAGE_SIM)}] forwarding received message from [${this.inputData.getString(Constants.KEY_MESSAGE_FROM)}] to [${this.inputData.getString(Constants.KEY_MESSAGE_TO)}]")
100+
101+
if (HttpSmsApiService.create(applicationContext).receive(
102+
this.inputData.getString(Constants.KEY_MESSAGE_SIM)!!,
103+
this.inputData.getString(Constants.KEY_MESSAGE_FROM)!!,
104+
this.inputData.getString(Constants.KEY_MESSAGE_TO)!!,
105+
this.inputData.getString(Constants.KEY_MESSAGE_CONTENT)!!,
106+
this.inputData.getString(Constants.KEY_MESSAGE_TIMESTAMP)!!,
107+
)) {
108+
return Result.success()
109+
}
110+
111+
return Result.retry()
112+
}
65113
}
66114
}

0 commit comments

Comments
 (0)