czottmann / obsidian-actions-uri

A plugin for Obsidian (https://obsidian.md) that adds additional `x-callback-url` endpoints to the app for common actions — it's a clean, super-charged addition to Obsidian URI.
https://zottmann.dev/obsidian-actions-uri/
MIT License
138 stars 6 forks source link

[ZCO-124] Make `/daily-note/create?silent=false` open note even if it already existed #47

Closed johtso closed 1 year ago

johtso commented 1 year ago

Currently the behaviour is inconsistent and only opens the note if it was newly created. This means that if you want to ensure the note exists and open it, you have to call 2 action URIs (create and then open-current) to make sure it happens.

Does a change in behaviour here seem sensible?

Edit:

Another approach might be to add a flag to the open-current action to create the note if it does not exist. This seems like a common enough pattern that it should be achievable in a single action.

ZCO-124

czottmann commented 1 year ago

@johtso Thanks for the report!

The current behavior is correct because if a current DN exists, trying to create a note without allowing it to be overwritten results in a fail state. It shouldn't be "failed, but...".

Adding a toggle to /daily-note/open-current would make it deviate from its sister route /daily-note/open-most-recent which I don't like.

That being said, how about setting up a new route, /daily-note/create-or-open-current? One optional argument content that would be ignored if the DN already exists.

Basically, there's no fail state (except when the note can't be written due to filesystem issues etc.)

geoelectric commented 1 year ago

@czottmann, I didn’t file the original, but as I just wandered into the GitHub site looking for this functionality, sounds great to me.

I think the one (not particularly compelling) argument towards giving the daily-note/create an “open if exists” option is that the equivalent official route,/new, takes &append to do exactly that. But then they have to document the conflict with &overwrite, etc, and I agree it becomes less cohesive.

Overall, I prefer your approach, but I will say your proposed sometimes-content and templating behavior is a bit on the implicit side. I’m also not sure I think the desire for templating naturally conflicts with the desire to supply content, so that feels arbitrary.

To make it more explicit and consistent, you might consider an explicit flag for templating and always allowing for optional content. I think doing so will also give you something far more useful.

Here’s my suggestion for making that work:

Since templating should be default I’d propose skip-template as the flag. Without that set, if a note does have to be created the template will be invoked.

I’d also propose that content always be appended, whether or not the file is created first or a template is invoked.

So,

Templating enabled and with content for an absent note, it’d create the note, invoke the template, append at bottom, open Obsidian to that note.

Templating enabled and with content for an existing note, no create or template would happen, append at bottom, open to note.

Here’s why I’m suggesting this:

First, it’s fully consistent. With a new note and no template you append to nothing, with no content you append nothing, and otherwise it’s a pipeline with a disable flag for the template.

But more importantly (and what I was looking for, coming in) with that setup I think you’d get a one and done incremental logger you can just hit throughout the day without any additional logic for “this is the first time.”

It will add any content to the bottom each time it is invoked—presumably to a Log section at the end of your template, if you use one. If you haven’t been into your Daily Note yet so Obsidian will have done it for you, it’ll also create the note with the proper template the first time you log something. If you want, you can skip giving it content so when the note opens you can enter it yourself. If you do give it content, you can review it after the note opens.

That’s probably the workflow where most people would want this combined create-or-open action.

Giving it a silent parameter and x-callbacks to skip the final open would be useful for this action too—it would allow incremental logging from a minimal shortcut input without disrupting your current app. Since you don’t really need to handle the callbacks (no failure modes, as you say) that opens up logging from Siri, Alfred, Keyboard Maestro, the share menu, a cron job, etc, with essentially a one-liner hitting the URL to connect them.

Way more importantly, there would be no need to handle possible initialization for each and every one.

So I think I’m really describing a fully parallel “append to note no matter what” route with optional opening more than your original “create or open” with optional appending.

But I also think all this sort of jumps naturally out of the idea the content and templating behavior should be consistent and explicit. Once you suggested those features (which I agree with) I think this is the natural destination. Since going these couple steps further would fully cover a number of very common logging workflows—and opens up automation at every level from manual to fully silent—I think you should consider doing so.

czottmann commented 1 year ago

@geoelectric Whoa, wall of text. 😅 Thanks for your input! At the moment, I'm knee-deep in an adjacent project with higher priority, so I just skimmed it — but I want & need to find some time to really think this through in order to form an actual opinion here.

Give me a few days, please.

geoelectric commented 1 year ago

@czottmann Yeah, sorry about that. The proposal sort of grew out as I thought it through. I did try to divide it up a little for comprehension, at least. By the time I was done maybe it should’ve been markdown headers…

TL;DR:

One route, consistent with your idea with a couple of design tweaks that I think are probably generally beneficial for the API for being more consistent and explicit, and which I would have recommended anyway. Some really nice behavior emerged when I thought through how that’d work.

It would allow interstitial logging (bullet journaling, etc) from anywhere, and opens up dead easy interapp connection (weather of the day, automatic weight logging, etc) by taking away any need to worry about being the first one to log and having to initialize the note.

It’s your ability to fire the template on first note creation (I believe—you mentioned it above) that distinguishes you from every other “append to file” solution I’ve found or cobbled together to do this. If you can do that, it makes this plugin especially well suited for journal logging.

Let me know what you think.

czottmann commented 1 year ago

@geoelectric I had some time to think it through, apologies for the delay. It's a good idea. Here's a sketch for a /daily-note/create-or-append route (I've omitted writing down the description for its /note/create-or-append counterpart).

For consistency, I'd keep the existing /daily-note/create and /note/create routes, but adjust their signature — i.e., I'd add an ignore-template parameter, thus changing their default behaviour.

Let me know what you think.


Finds or creates the current daily note and appends some text to it. If the note needs to be created first, Obsidian will use the template specified in its settings, unless the ignore-template parameter is set.

An existing current daily note will not be overwritten unless the related parameter is explicitly set.

The route /daily-note/create-or-append would look as follows:

Scenarios:

johtso commented 1 year ago

@czottmann this sounds perfect!

jancbeck commented 1 year ago

Not sure if this is helps but I found this issue while googling for my use case where I want to append a text to the bottom of the daily note. If a daily note exists for today then just use that or else create a new one from the template (which has a "Notes:" header at the bottom of it).

I'm using this setup in Apple Shortcuts

Screenshot 2023-03-18 at 18 15 30

Note how I'm calling /dailynote/create first with no content and then call /dailynote/append with the x-callback and x-success. This ensures that a daily note exists to append to. This works on Mac but not on mobile so I'll have to investigate further. But maybe it helps some struggling with the same issue.

edit: works on mobile. Plug-in wasn’t activated for some reason.

czottmann commented 1 year ago

@jancbeck At first I was like "Why would you call obsidian:// as a callback‽" and then I understood. This is a clever idea for chaining!

Obligatory plug: if you're open to trade juggling XCU calls in Shortcuts with way more convenience, check out my app Actions for Obsidian. ;)

czottmann commented 1 year ago

I've released v0.18 which overhauls the "create or overwrite or error" mechanic by adding a new if-exists parameter which supersedes the overwrite parameter. I think it should alleviate a lot of the pain points for the /*/create endpoints.

The/daily-note/create route has a new optional if-exists parameter to specify a strategy for dealing with an existing current daily note. It overrides the default behavior (returning an error) and can be set to skip or overwrite. if-exists=skip will pretend the existing note was just created and return it. if-exists=overwrite will trash the existing note and create a new daily note from scratch.

jancbeck commented 1 year ago

Thanks for adding this!

For others who might need this, I'm posting my shortcut:

Screenshot 2023-06-02 at 10 29 16

I put this as an icon on my home screen for when I want to quickly save a thought to my journal. I also have an automation that asks to run this every evening before winddown.

czottmann commented 1 year ago

Closing this here ticket as the discussed functionality of the /*/create routes has been implemented in 0.18.

I've started a follow-up (#67) for dealing with requested enhancements for the append/prepend-type routes.