aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2024-04-30 15:10:01 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2024-04-30 15:10:01 +0100
commit12fc3effaa7562ed260a0d091ab78f8d556bad62 (patch)
tree43b1e0f1d7a530080c05bc59148540d10d7375f3
parent7c3cca402360132f73883c75b226c11b9b9ecb41 (diff)
downloadsentrum-12fc3effaa7562ed260a0d091ab78f8d556bad62.tar.gz
sentrum-12fc3effaa7562ed260a0d091ab78f8d556bad62.tar.bz2
sentrum-12fc3effaa7562ed260a0d091ab78f8d556bad62.zip
Improve default ntfy configuration
-rw-r--r--README.md29
-rw-r--r--src/actions/ntfy.rs85
2 files changed, 96 insertions, 18 deletions
diff --git a/README.md b/README.md
index cff420e..7955571 100644
--- a/README.md
+++ b/README.md
@@ -136,31 +136,38 @@ accounts for some reason).
This is the best straightforward way to get push notifications on a smartphone.
1. Install the android/iOS app following the relevant links in https://ntfy.sh
-2. If you don't run your own ntfy self-hosted server, create an account at
- ntfy.sh
-3. Open the app, give it the needed permissions and configure your account
- credentials
-4. Click on the `+` button and create a "topic", preferably named `sentrum`
- since that's what will be used by default.
+2. Open the app, give it the needed permissions
Then you just need to add the relevant configuration:
```toml
[[actions]]
type = "ntfy"
-# Credentials (required if you use a public server like the default one)
-credentials.username = "<YOUR USERNAME HERE>"
-credentials.password = "<YOUR PASSWORD HERE>"
+#
+# EVERYTHING BELOW IS OPTIONAL
+#
+# Credentials (optional, relevant for self-hosted instances or paid reserved topics)
+#credentials.username = "<YOUR USERNAME HERE>"
+#credentials.password = "<YOUR PASSWORD HERE>"
# ntfy server (optional)
#url = "https://ntfy.sh"
-# notification channel name (optional)
-#topic = "sentrum"
+# notification channel name (optional, defaults to random string for security)
+#topic = "<RANDOM TOPIC NAME>"
# Proxy used to connect (optional, defaults to None)
#proxy = "socks5://127.0.0.1:9050"
# Priority ("max", "high", "default", "low", "min") (optional)
#priority = "default"
```
+If you don't set a `topic = `, `sentrum` will auto-generate one for you randomly
+(since topic names are kind of like a password for the public default ntfy.sh
+server). When you later run `sentrum`, it will print out the topic name it's
+using.
+
+Open the ntfy app, click on the `+` button, create a "topic" and set the same
+equal to the one should be the `sentrum` logs.
+
+
### nostr
Get notified by a nostr [NIP04 encrypted
diff --git a/src/actions/ntfy.rs b/src/actions/ntfy.rs
index badee70..98b630a 100644
--- a/src/actions/ntfy.rs
+++ b/src/actions/ntfy.rs
@@ -1,15 +1,76 @@
-use super::Action;
-use crate::message::MessageConfig;
-use crate::message::MessageFormat;
-use crate::message::MessageParams;
+use std::fs::File;
+use std::io::BufReader;
+use std::io::Write;
+use std::path::PathBuf;
+
+use anyhow::Context;
use anyhow::Result;
use async_trait::async_trait;
+use log::info;
use ntfy::Auth;
use ntfy::Dispatcher;
use ntfy::Payload;
use ntfy::Priority;
use ntfy::Url;
+use rand::distributions::Alphanumeric;
+use rand::thread_rng;
+use rand::Rng;
use serde::Deserialize;
+use serde::Serialize;
+use serde_json::from_reader;
+use serde_json::to_string;
+
+use super::Action;
+use crate::message::MessageConfig;
+use crate::message::MessageFormat;
+use crate::message::MessageParams;
+
+#[derive(Debug, Clone, Deserialize, Serialize)]
+struct NtfyData {
+ topic: String,
+}
+
+fn get_random_topic() -> String {
+ thread_rng()
+ .sample_iter(&Alphanumeric)
+ .take(16)
+ .map(char::from)
+ .collect()
+}
+
+impl Default for NtfyData {
+ fn default() -> Self {
+ NtfyData {
+ topic: get_random_topic(),
+ }
+ }
+}
+
+fn get_ntfy_data_filepath() -> PathBuf {
+ dirs::cache_dir()
+ .unwrap_or(PathBuf::from("cache"))
+ .join(env!("CARGO_PKG_NAME"))
+ .join("ntfy.json")
+}
+
+fn get_ntfy_topic() -> Result<String> {
+ let path = get_ntfy_data_filepath();
+ Ok(match File::open(&path) {
+ Ok(file) => {
+ let reader = BufReader::new(file);
+ from_reader(reader)
+ .with_context(|| format!("cannot read ntfy data from '{}'", path.display()))
+ }
+ Err(_) => {
+ let ntfy_data = NtfyData::default();
+ let mut file = File::create(&path)?;
+ file.write_all(to_string(&ntfy_data)?.as_bytes())
+ .with_context(|| format!("could not write ntfy data to '{}'", path.display()))?;
+ Ok(ntfy_data)
+ }
+ }?
+ .topic)
+}
#[derive(Deserialize, Debug)]
#[serde(remote = "Priority")]
@@ -49,8 +110,8 @@ impl NtfyConfig {
self.url.as_deref().unwrap_or("https://ntfy.sh")
}
- pub fn topic(&self) -> &str {
- self.topic.as_deref().unwrap_or(env!("CARGO_PKG_NAME"))
+ pub fn topic(&self) -> Option<&str> {
+ self.topic.as_deref()
}
}
@@ -71,7 +132,17 @@ impl<'a> NtfyAction<'a> {
dispatcher_builder = dispatcher_builder.proxy(proxy);
}
- let mut payload = Payload::new(ntfy_config.topic())
+ let topic = ntfy_config
+ .topic()
+ .unwrap_or(&get_ntfy_topic()?)
+ .to_string();
+ info!(
+ "[ntfy] using topic '{}', connect to {}/{}",
+ topic,
+ ntfy_config.url(),
+ topic
+ );
+ let mut payload = Payload::new(&topic)
.markdown(match message_config.format() {
MessageFormat::Plain => false,
MessageFormat::Markdown => true,