fix: ntfy use JSON publish API (raw body was treated as attachment)

ntfy.sh now treats any request body (PUT/POST, text/plain) as a file
attachment, so messages never showed in the app. Switch to ntfy's JSON
publish API: POST / with {topic,title,message}.

version 1.7.1 -> 1.7.2 (code 14 -> 15)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 20:32:26 +08:00
parent 0238b5dd8d
commit 94422fbd76
2 changed files with 15 additions and 11 deletions
@@ -10,11 +10,13 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.IOException
import java.util.concurrent.TimeUnit
/**
* ntfy 推送:POST {server}/{topic},可选 Bearer auth
* ntfy 推送:用 JSON publish APIPOST / with {topic,title,message}
* 注:raw body 会被 ntfy 当附件,必须用 JSON API 或 Message header。
* 对瞬时 IOException 自动重试 3 次(退避 600/1200ms)。
*/
object NtfySender {
@@ -30,13 +32,15 @@ object NtfySender {
title: String, body: String,
): Result<Unit> = withContext(Dispatchers.IO) {
runCatching {
val url = server.trim().removeSuffix("/") + "/" + topic.trim()
val req = Request.Builder().url(url)
.header("Title", title.take(200))
.apply {
if (token.isNotBlank()) header("Authorization", "Bearer $token")
}
.put(body.take(4000).toRequestBody(TEXT_PLAIN))
val payload = JSONObject()
.put("topic", topic.trim())
.put("title", title.take(200))
.put("message", body.take(4000))
.toString()
val req = Request.Builder()
.url(server.trim().removeSuffix("/"))
.apply { if (token.isNotBlank()) header("Authorization", "Bearer $token") }
.post(payload.toRequestBody(JSON))
.build()
doPushWithRetry(req)
}
@@ -68,7 +72,7 @@ object NtfySender {
}
}
private val TEXT_PLAIN = "text/plain; charset=utf-8".toMediaType()
private val JSON = "application/json; charset=utf-8".toMediaType()
private const val MAX_ATTEMPTS = 3
private val BACKOFF_MS = longArrayOf(600L, 1200L)
}