Draft query via Shortcuts

I have an action that adds an journal-like entry to a specific journal draft, no matter from where I trigger the action. I identify this draft in the script via a queryByTitle (the line is const journal = Draft.queryByTitle("Journal culinaire " + currentYear)[0]). I know that this is a bit quick and dirty, but it works fine for me, as long as I trigger the action from within the Drafts App. Now I wanted to do this via Apple Shortcuts, and here, the draft is not correctly found. The action triggers, and it works correct, but instead of adding the text into the correct line in my journal draft, the text is added to a new draft. Am I missing something? Any hints? Or is this just a Shortcuts bug?

If you share the link o your shortcut we can take a look, but without the Shortcut we are just t guessing what you ar doing and why it isn’t working.

There is a very good chance you have just built your shortcut incorrectly and it need a tweak or two.

Hi, thanks for your reply. My shortcut has only one step: the “Run action on Draft” template. As “action”, I set the action, for the “draft” I tried different settings (i.e. left empty, the draft I actually want to be addressed, and a random other draft) with always the same result.

I suspect it is something about the way the action is written, because context is a bit different when triggered from Shortcuts. We kind of need to see the whole picture to sort that out, if you could also share the script you are running in the Drafts’ action as well.

Is this journal entry have some text? Is it just a timestamp or something? It does not look like you are passing any text into Drafts with that shortcut.

Sure, I can share the whole script. The journal draft has text, one line per day beginning with the date. Basically, the script checks whether I run it from the journal draft or from somewhere else and then either takes the current date line for further entry or, if run from the journal draft itself, it takes the line where the cursor is located. Sorry, this might be a little confusing – probably this is is actually the problem. Here comes the script:

var journalEntry = "";
let inJournal = false;
let currentLine = "";

const currentDate = new Date();
	
const day = String(currentDate.getDate()).padStart(2, '0');
const month = String(currentDate.getMonth() + 1).padStart(2, '0');
const formattedDate = `${day}.${month}.`;

const currentYear = `${currentDate.getFullYear()}`;

const journal = Draft.queryByTitle("Journal culinaire " + currentYear)[0];

function showMenu() {
	let menu = Prompt.create();
	menu.title = "kulinarischer Tagebucheintrag";
	menu.message = "Was gab's denn?";
	menu.addTextField('entry', 'Es gab:', '');
	menu.addButton("OK", 0, true);
	menu.addButton("Rezept gekocht", 1, false, true);
	menu.addButton("es gab Reste", 2, false);
	menu.addButton("heute nicht gekocht", 3, false);
	menu.show();

	if (menu.buttonPressed == 0) {
		journalEntry = menu.fieldValues["entry"];
		editor.setSelectedText(journalEntry);

	} else if (menu.buttonPressed == 2) {
		journalEntry = "(Reste)"
		editor.setSelectedText(journalEntry);

	} else if (menu.buttonPressed == 3) {
		journalEntry = "(nichts)"
		editor.setSelectedText(journalEntry);

	} else if (menu.buttonPressed == 1) {

		let text = editor.getText();
		let pos = editor.getSelectedRange()[0];
		let before = text.slice(pos-14, pos);
		let regex = /(\. - )|\w\./g;
		let rezept = draft;

		let workspace = Workspace.find("Rezepte");
		let d = app.selectDraft(workspace);
		if(d) {
			rezept = d;
			d.isFlagged = false;
			d.update();
			if (regex.test(before)) {
		      editor.setSelectedText(`${d.displayTitle}`);   
		   } else {
		   	editor.setSelectedText('; ' + `${d.displayTitle}`);
			}
		}

		let ratePromt = Prompt.create();
		ratePromt.title = "Wie hat's geschmeckt?"
		ratePromt.message = "Soll das Rezept aufbewahrt oder verworfen werden?"
		ratePromt.addButton("hat gut geschmeckt!", 8)
		ratePromt.addButton("das koche ich nie wieder!", 9)

		if (rezept.hasTag("neuesrezept")) {
			if (ratePromt.show()) {
				if (ratePromt.buttonPressed == 8) {
					rezept.removeTag("neuesrezept");
					rezept.update();
					app.displaySuccessMessage(rezept.displayTitle + ": hat gut geschmeckt!")
				} else if (ratePromt.buttonPressed == 9) {
					rezept.removeTag("neuesrezept");
					rezept.removeTag("rezept")
					rezept.addTag("verworfenesrezept");
					rezept.update();
					app.displaySuccessMessage(rezept.displayTitle + ": koche ich nie wieder!")
				}
			}
		}
	} else { 
		context.cancel();
	}
}


if (draft.displayTitle == "Journal culinaire " + currentYear) {
	let inJournal = true;
	var [lStart, lEnd] = editor.getSelectedLineRange();
	currentLine = editor.getTextInRange(lStart, lEnd);
	showMenu();
} else {
	editor.load(journal);

	let text = journal.content; 
	const lines = text.split('\n'); 

	let targetLineIndex = -1;
	for (let i = 0; i < lines.length; i++) {
	    if (lines[i].substring(3).startsWith(formattedDate)) {
	        targetLineIndex = i;
	    	currentLine = lines[i];
	        break;
	    }
	}

	if (targetLineIndex !== -1) {
	    const cursorPosition = lines[targetLineIndex].length + 1;
	    editor.setSelectedRange(lines.slice(0, targetLineIndex).join('\n').length + cursorPosition, 0);
	    showMenu();
	} else {
	    app.displayWarningMessage("Das aktuelle Datum wurde nicht gefunden.");
	}
}

Thanks to your earlier response, I now suppose that checking “where” the action is triggered might fail if triggered via Shortcuts. Perhaps I should just write another, similar action without this if-statement and use this one for Shortcuts?

Logically speaking, your script relies on two global variables: the draft and the editor. It’s not a good idea to mix and match using these two objects. One manipulates the actual draft object. One manipulates the text loaded in the editor.

When you run an action from the action list in drafts, the draft is set to the draft that is currently loaded in the editor - so it can kind of seem like they are the same thing, but they are not.

When you run an action from Shortcuts using “Run Action on Draft”, the draft object points to the draft you selected – but that does not necessarily mean that draft is loaded in the editor.

If you want to be able to call the script from outside draft, you should stick to manipulating the draft object and it’s content property, then call update() to save those changes – then, optionally load that draft in the editor when you are done.

Does that clarify?

Thank you for your extensive response. Best app + best community! That helps, I will revise my script and I think I can now see why it isn’t working yet.

1 Like