Repository: favonia/cloudflare-ddns
Pull request #605 (2023-10-15 04:49:51)

fix(monitor): revise support of Uptime Kuma
1. Fix the typo "Ok".
2. Document that the user should change the "Heartbeat Interval".
3. Always use the message "OK" instead of trying to send more information.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/605?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) Report
> Merging [#605](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/605?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) (f75e5c5) into [main](https://app.codecov.io/gh/favonia/cloudflare-ddns/commit/fb2e872a93f3c95b58dde116e7fc9e6fa8d5964c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) (fb2e872) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##             main     #605   +/-   ##
=======================================
  Coverage   88.30%   88.30%           
=======================================
  Files          45       45           
  Lines        2300     2300           
=======================================
  Hits         2031     2031           
  Misses        259      259           
  Partials       10       10           
```

| [Flag](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/605/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/605/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | `88.30% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Files](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/605?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | Coverage Δ | |
|---|---|---|
| [internal/monitor/updatekuma.go](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/605?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia#diff-aW50ZXJuYWwvbW9uaXRvci91cGRhdGVrdW1hLmdv) | `95.29% <100.00%> (ø)` | |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia)


Patch:
diff --git a/README.markdown b/README.markdown
index 6383727..c54a6bf 100644
--- a/README.markdown
+++ b/README.markdown
@@ -329,17 +329,15 @@ _(Click to expand the following items.)_
 <details>
 <summary>👁️ Logging, Healthchecks, and Uptime Kuma</summary>
 
-| Name                           | Valid Values                                                                                                                                                      | Meaning                                                                            | Required? | Default Value |
-| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------- | ------------- |
-| `QUIET`                        | Boolean values, such as `true`, `false`, `0` and `1`. See [strconv.ParseBool](https://pkg.go.dev/strconv#ParseBool)                                               | Whether the updater should reduce the logging                                      | No        | `false`       |
-| `EMOJI`                        | Boolean values, such as `true`, `false`, `0` and `1`. See [strconv.ParseBool](https://pkg.go.dev/strconv#ParseBool)                                               | Whether the updater should use emojis in the logging                               | No        | `true`        |
-| `HEALTHCHECKS`                 | [Healthchecks ping URLs](https://healthchecks.io/docs/), such as `https://hc-ping.com/<uuid>` or `https://hc-ping.com/<project-ping-key>/<name-slug>` (see below) | If set, the updater will ping the URL when it successfully updates IP addresses    | No        | (unset)       |
-| 🧪 `UPTIMEKUMA` (experimental) | 🧪 Uptime Kuma’s Push URLs, such as `https://<host>/push/<id>`. For convenience, you can directly copy the ‘Push URL’ from the Uptime Kuma configuration page.    | 🧪 If set, the updater will ping the URL when it successfully updates IP addresses | No        | (unset)       |
+| Name                           | Valid Values                                                                                                                                                      | Meaning                                                                                                                                                                                            | Required? | Default Value |
+| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------------- |
+| `QUIET`                        | Boolean values, such as `true`, `false`, `0` and `1`. See [strconv.ParseBool](https://pkg.go.dev/strconv#ParseBool)                                               | Whether the updater should reduce the logging                                                                                                                                                      | No        | `false`       |
+| `EMOJI`                        | Boolean values, such as `true`, `false`, `0` and `1`. See [strconv.ParseBool](https://pkg.go.dev/strconv#ParseBool)                                               | Whether the updater should use emojis in the logging                                                                                                                                               | No        | `true`        |
+| `HEALTHCHECKS`                 | [Healthchecks ping URLs](https://healthchecks.io/docs/), such as `https://hc-ping.com/<uuid>` or `https://hc-ping.com/<project-ping-key>/<name-slug>` (see below) | If set, the updater will ping the URL when it successfully updates IP addresses                                                                                                                    | No        | (unset)       |
+| 🧪 `UPTIMEKUMA` (experimental) | 🧪 Uptime Kuma’s Push URLs, such as `https://<host>/push/<id>`. For convenience, you can directly copy the ‘Push URL’ from the Uptime Kuma configuration page.    | 🧪 If set, the updater will ping the URL when it successfully updates IP addresses. ⚠️ Remember to change the “Heartbeat Interval” to match your DNS updating schedule specified in `UPDATE_CRON`. | No        | (unset)       |
 
 > 🩺 For `HEALTHCHECKS`, the updater can work with any server following the [same notification protocol](https://healthchecks.io/docs/http_api/), including but not limited to self-hosted instances of [Healthchecks](https://github.com/healthchecks/healthchecks). Both UUID and Slug URLs are supported, and the updater works regardless whether the POST-only mode is enabled.
 
-> 🩺 For `UPTIMEKUMA` (Uptime Kuma), it seems the service can only display the first success message. This means the detailed information of follow-up operations will not be shown in Uptime Kuma. If you find this confusing, or if you have suggestions about how to work around this limitation, please [open a GitHub issue.](https://github.com/favonia/cloudflare-ddns/issues/new) Thank you!
-
 </details>
 
 ### 🔂 Restarting the Container
diff --git a/internal/monitor/updatekuma.go b/internal/monitor/updatekuma.go
index 08fb39f..de1edba 100644
--- a/internal/monitor/updatekuma.go
+++ b/internal/monitor/updatekuma.go
@@ -73,7 +73,7 @@ func NewUptimeKuma(ppfmt pp.PP, rawURL string) (Monitor, bool) {
 		for k, vs := range q {
 			switch {
 			case k == "status" && slices.Equal(vs, []string{"up"}): // status=up
-			case k == "msg" && slices.Equal(vs, []string{"Ok"}): // msg=Ok
+			case k == "msg" && slices.Equal(vs, []string{"OK"}): // msg=OK
 			case k == "ping" && slices.Equal(vs, []string{""}): // ping=
 
 			default: // problematic case
@@ -148,9 +148,11 @@ func (h *UptimeKuma) ping(ctx context.Context, ppfmt pp.PP, param UptimeKumaRequ
 	return true
 }
 
-// Success pings the server with status=up.
-func (h *UptimeKuma) Success(ctx context.Context, ppfmt pp.PP, message string) bool {
-	return h.ping(ctx, ppfmt, UptimeKumaRequest{Status: "up", Msg: message, Ping: ""})
+// Success pings the server with status=up. Messages are ignored and "OK" is used instead.
+// The reason is that Uptime Kuma seems to show only the first success message
+// and it could be misleading if an outdated message stays in the UI.
+func (h *UptimeKuma) Success(ctx context.Context, ppfmt pp.PP, _message string) bool {
+	return h.ping(ctx, ppfmt, UptimeKumaRequest{Status: "up", Msg: "OK", Ping: ""})
 }
 
 // Start does nothing.
@@ -168,10 +170,10 @@ func (h *UptimeKuma) Log(ctx context.Context, ppfmt pp.PP, message string) bool
 	return true
 }
 
-// ExitStatus does nothing.
+// ExitStatus with non-zero triggers [Failure]. Otherwise, it does nothing.
 func (h *UptimeKuma) ExitStatus(ctx context.Context, ppfmt pp.PP, code int, message string) bool {
 	if code != 0 {
-		return h.ping(ctx, ppfmt, UptimeKumaRequest{Status: "down", Msg: message, Ping: ""})
+		return h.Failure(ctx, ppfmt, message)
 	}
 	return true
 }


Test patch:
diff --git a/internal/monitor/updatekuma_test.go b/internal/monitor/updatekuma_test.go
index 9f74713..299ab78 100644
--- a/internal/monitor/updatekuma_test.go
+++ b/internal/monitor/updatekuma_test.go
@@ -29,7 +29,7 @@ func TestNewUptimeKuma(t *testing.T) {
 		prepareMockPP func(*mocks.MockPP)
 	}{
 		"bare": {"https://user:pass@host/path", true, nil},
-		"full": {"https://user:pass@host/path?status=up&msg=Ok&ping=", true, nil},
+		"full": {"https://user:pass@host/path?status=up&msg=OK&ping=", true, nil},
 		"unexpected": {
 			"https://user:pass@host/path?random=", true,
 			func(m *mocks.MockPP) {
@@ -37,7 +37,7 @@ func TestNewUptimeKuma(t *testing.T) {
 			},
 		},
 		"ill-formed-query": {
-			"https://user:pass@host/path?status=up;msg=Ok;ping=", false,
+			"https://user:pass@host/path?status=up;msg=OK;ping=", false,
 			func(m *mocks.MockPP) {
 				m.EXPECT().Errorf(pp.EmojiUserError, "The Uptime Kuma URL (redacted) does not look like a valid URL")
 			},
@@ -113,7 +113,7 @@ func TestUptimeKumaEndPoints(t *testing.T) {
 			func(ppfmt pp.PP, m monitor.Monitor) bool {
 				return m.Success(context.Background(), ppfmt, "hello")
 			},
-			"/", "up", "hello", "",
+			"/", "up", "OK", "",
 			[]action{ActionOk},
 			ActionAbort, true,
 			true,
@@ -128,7 +128,7 @@ func TestUptimeKumaEndPoints(t *testing.T) {
 			func(ppfmt pp.PP, m monitor.Monitor) bool {
 				return m.Success(context.Background(), ppfmt, "aloha")
 			},
-			"/", "up", "aloha", "",
+			"/", "up", "OK", "",
 			[]action{ActionNotOk},
 			ActionAbort, false,
 			false,
@@ -143,7 +143,7 @@ func TestUptimeKumaEndPoints(t *testing.T) {
 			func(ppfmt pp.PP, m monitor.Monitor) bool {
 				return m.Success(context.Background(), ppfmt, "aloha")
 			},
-			"/", "up", "aloha", "",
+			"/", "up", "OK", "",
 			[]action{ActionGarbage},
 			ActionAbort, false,
 			false,
@@ -158,7 +158,7 @@ func TestUptimeKumaEndPoints(t *testing.T) {
 			func(ppfmt pp.PP, m monitor.Monitor) bool {
 				return m.Success(context.Background(), ppfmt, "stop now")
 			},
-			"/", "up", "stop now", "",
+			"/", "up", "OK", "",
 			nil, ActionAbort, false,
 			false,
 			func(m *mocks.MockPP) {