How to process a template on multiple drafts and combine into a single draft

I found this great script that combines all of todays Drafts into a single note.

I would like to tweak this so that each draft is processed through the below template so a timestamp is added based on creation date.

  • [[created|%H:%M]] [[draft]]

Then I need the final note has the drafts listed in ascending order based on creation date.

Preferably this would be done all through scripting rather than calling on another action. Can anyone give me some guidance on how to achieve this? Thanks in advance.

1 Like

According to your description I think this script should do what you expect:


//  Todays Drafts into New Draft

function mergeDraftsToday(p_Separator = "\n")
{
	// Create a new workspace object
	// We are not going to save this, just use it to get today's drafts
	let wsToday = Workspace.create();

	// Build a query date for drafts created today
	let qdStart = new QueryDate();
	qdStart.field = "created";
	qdStart.type = "absolute";
	qdStart.date = Date.today();

	// Assign the query date to the workspace
	wsToday.startDate = qdStart;

	// Get an array of drafts from the inbox for the 'today' workspace
	let adToday = wsToday.query("all");

	// Create an empty array and populate it with the content of today's drafts
	// Each draft's content becomes a separate element in the array
	let astrOutput = [];
   adToday.sort(function(a, b){return a.createdAt > b.createdAt})
	adToday.map(dToday => astrOutput.push(dToday.processTemplate("[[created|%H:%M]] ") + dToday.content))

	// Create a new draft from the array of draft content
	// The drafts are concatenatd using a separator string passed into the function
	let dNew = Draft.create();
	dNew.content = astrOutput.join(p_Separator);
	dNew.update();

	// Load the new draft and activate the editor
	editor.load(dNew);
	editor.activate();
}

// Merge today's drafts into a new draft with two newline characters between each of the drafts' content
mergeDraftsToday("\n\n");

I used @sylumer ‘s script from the action and just changed the following things:

  • the script queries for all Drafts not only Drafts in inbox
  • added a sort function / step for the creation date
  • added the created date / time before the content of the draft - this is done in this line: adToday.map(dToday => astrOutput.push(dToday.processTemplate("[[created|%H:%M]] ") + dToday.content)) - everything inside the „push() brackets will be used as content of the new draft.

Note: the date in front of the content of each draft will remove e.g. markdown header formatting of the line.

This works perfectly @FlohGro. Thank you.

A quick followup. What can I do to to make this newly created note the target of the next action step in a sequence? For example, my action now has this script block to merge all of todays notes, now I want to add another action step to export it to my Obsidian Daily note. I have these two action steps but I’m missing the the link between the step where the new draft is the target of the next action.

I’m going to have a fiddle around and see if I can figure it out myself. I’m sure it’s very simple.

1 Like

You cannot change the target draft of the action.

You can:

  1. Pass text to subsequent action steps either via variables in the case of scripting, or using custom template tags for non-scripted action steps.
  2. Or, queue another action to run with the new draft as the target draft.

For 1:

In your script, call draft.setTemplateTag("new-draft-content", dNew.content), then you can use the [[new-draft-content]] tag in subsequent action steps to get that text.

For 2:

Setup your other action the way you want, and at the end of your script do:

let action = Action.find("MY-ACTION-NAME");
app.queueAction(action, dNew);

Then the other action will run with the new draft as the target immediately after the current action finishes.

1 Like

Such a great help. Both of those solutions make sense. I chose to go with option 1 as it feels a lot cleaner (I like hearing one action beep over two). It works really well.

I should note option 2 has a slight advantage, which may or may not be meaningful in your use case. That being that if the action is queued to run with the new target draft, any generated action logs will be associated with that new draft.

If you just pass the text to the next action step, the log will still be tied to the initial draft.

May or may not be a meaningful difference to you.