diff --git a/src/entries.rs b/src/entries.rs index fa429fb..43a9b6c 100644 --- a/src/entries.rs +++ b/src/entries.rs @@ -138,7 +138,23 @@ pub fn delete_entry(data_dir: &Path, short_id: &str) -> Result { } #[cfg(any(feature = "telegram", test))] -/// Find an entry file by short ID prefix and update its status. +/// Append a reply to an entry's body, prefixed with ">> " on each line. +pub fn append_reply(dir: &Path, id: &str, reply: &str) -> Result { + let mut entry = find_entry(dir, id)?; + let quoted: String = reply + .lines() + .map(|line| format!(">> {line}")) + .collect::>() + .join("\n"); + entry.body.push_str("\n\n"); + entry.body.push_str("ed); + let path = dir.join(format!("{}.txt", entry.id)); + std::fs::write(&path, entry.to_file_contents()).map_err(|e| e.to_string())?; + Ok(entry.meta.name.clone()) +} + +#[cfg(any(feature = "telegram", test))] +/// Find an entry file by ID and update its status. pub fn set_status(dir: &Path, short_id: &str, status: Status) -> Result { let mut entry = find_entry(dir, short_id)?; entry.meta.status = status; @@ -356,4 +372,24 @@ Hello!"#; assert!(delete_entry(dir.path(), "nonexistent").is_err()); } + #[test] + fn test_append_reply() { + let dir = tempfile::tempdir().unwrap(); + let contents = "+++\nname = \"alice\"\ndate = \"2026-04-10\"\nstatus = \"approved\"\n+++\nDid you drink water today?"; + std::fs::write(dir.path().join("ab12.txt"), contents).unwrap(); + + let name = append_reply(dir.path(), "ab12", "Not enough! Thanks for\nthe note.").unwrap(); + assert_eq!(name, "alice"); + + let entry = find_entry(dir.path(), "ab12").unwrap(); + assert!(entry.body.contains("Did you drink water today?")); + assert!(entry.body.contains(">> Not enough! Thanks for")); + assert!(entry.body.contains(">> the note.")); + } + + #[test] + fn test_append_reply_not_found() { + let dir = tempfile::tempdir().unwrap(); + assert!(append_reply(dir.path(), "nonexistent", "hello").is_err()); + } } diff --git a/src/telegram.rs b/src/telegram.rs index 4a41e1f..3df1fb3 100644 --- a/src/telegram.rs +++ b/src/telegram.rs @@ -141,6 +141,28 @@ pub async fn bot_task(bot: Bot, chat_id: ChatId, data_dir: PathBuf) { bot.send_message(msg.chat.id, e).await?; } } + } else if let Some(rest) = text.strip_prefix("/reply_") { + let (id, reply) = match rest.split_once('\n') { + Some((id, reply)) => (id.trim(), reply), + None => { + bot.send_message(msg.chat.id, "Usage: /reply_ID\\nYour reply text") + .await?; + return respond(()); + } + }; + if reply.trim().is_empty() { + bot.send_message(msg.chat.id, "Reply text is empty.").await?; + return respond(()); + } + match entries::append_reply(&entries_dir, id, reply) { + Ok(name) => { + bot.send_message(msg.chat.id, format!("Reply added to {name}'s entry.")) + .await?; + } + Err(e) => { + bot.send_message(msg.chat.id, e).await?; + } + } } else if let Some(id) = text.strip_prefix("/delete_") { match entries::delete_entry(&data_dir, id) { Ok(name) => {