Skip to content

Commit 16f205e

Browse files
Robclaude
andcommitted
fix(telegram): post stale/missed as new messages instead of editing bubble
Previously TelegramStaleCheckWork edited the existing bubble in-place for stale and missed transitions. This meant the last valid reading was overwritten and chat history gave no indication of when or how many gaps occurred. Now stale and missed alerts are posted as new Telegram messages (sendMessage). The original bubble retains the last reading, and each stale/missed event appears as a distinct, timestamped message in the chat timeline — making it easy to glance back and see if and when readings were interrupted. The messageId guard is kept so alerts only fire when an active session exists. State (lastSentAtMs, lastMessageId) is left intact on success so readings resuming after the refresh window naturally start a fresh bubble. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a1f77b0 commit 16f205e

1 file changed

Lines changed: 10 additions & 11 deletions

File tree

Common/src/main/java/tk/glucodata/TelegramStaleCheckWork.kt

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ import java.util.concurrent.ConcurrentHashMap
1616
*
1717
* The producer ([OutboundApi.sendTelegram]) calls [schedule] right after a
1818
* successful send. We queue a single [Runnable] per destination in a static
19-
* [Handler]; when it fires, we call the Telegram editMessageText endpoint to
20-
* rewrite the existing bubble to "⚠️ Stale." (at the stale threshold) or
21-
* "⚪ Missed reading." (at the missed threshold). The edit is best-effort:
22-
* if the bubble was deleted, the API returns an error and we give up.
19+
* [Handler]; when it fires, we post a **new** Telegram message ("⚠️ Stale" at
20+
* the stale threshold, "⚪ Missed reading" at the missed threshold) rather than
21+
* editing the bubble. This preserves the last valid reading in the bubble and
22+
* leaves stale/missed events as distinct, timestamped messages in the chat
23+
* history for easy retrospective review.
2324
*
2425
* Limitation: this is in-process only. If the app process is killed between
2526
* sends, the stale check is lost until the next CGM reading arrives and
@@ -82,7 +83,7 @@ object TelegramStaleCheckWork {
8283
if (messageId <= 0L) continue
8384

8485
val text = renderStaleText(status, now)
85-
val result = postEdit(destination, recipient, messageId, text)
86+
val result = postSend(destination, recipient, text)
8687
when (result) {
8788
true -> {
8889
OutboundApiSettings.recordStaleAt(context, destinationId, recipient, now)
@@ -122,25 +123,23 @@ object TelegramStaleCheckWork {
122123
}
123124

124125
/**
126+
* Posts a new stale/missed message to the chat (does not edit the existing bubble).
125127
* Returns true on 2xx, false on a definitive API rejection (4xx),
126128
* null on transient network failure (caller should leave state intact).
127129
*/
128-
private fun postEdit(
130+
private fun postSend(
129131
destination: OutboundApiSettings.Destination,
130132
recipient: String,
131-
messageId: Long,
132133
text: String
133134
): Boolean? {
134-
val editUrl = destination.resolvedUrl()
135-
.replace(Regex("/sendMessage$"), "/editMessageText")
135+
val sendUrl = destination.resolvedUrl()
136136
val body = JSONObject()
137137
.put("chat_id", recipient)
138-
.put("message_id", messageId)
139138
.put("text", text)
140139
.toString()
141140
.toByteArray(Charsets.UTF_8)
142141
return try {
143-
val connection = (URL(editUrl).openConnection() as HttpURLConnection).apply {
142+
val connection = (URL(sendUrl).openConnection() as HttpURLConnection).apply {
144143
requestMethod = "POST"
145144
connectTimeout = 20_000
146145
readTimeout = 30_000

0 commit comments

Comments
 (0)