Send to Day One (via cli)

Hi Folks,

Here is an Action written in JS to export the current Draft to a new Day One journal entry. Unlike the other options listed in the Integration Guide, this one uses the Day One command line interface (CLI) utility. Note that because of this dependency this action is macOS only.

The advantage of this approach is that it preserves metadata, including: tags, creation date, and (most importantly) location.

Send To Day One (via cli)

Before using this, launch Day One and use the “Install Command Line Tools…” option from the Day One menu.

Constructive feedback appreciated, thanks!

5 Likes

Now opens the new entry in Day One and also prompts to archive/trash the draft.

Does this only work on Desktop?

Because of the use of the Dqy One CLI utility, this approach won’t be cross platform. It will be usable on macOS only. The post is tagged for “mac” so there is a suggestion for this - just no explicit mention.

For anyone who might not be familiar with command line interface tools, the linked page on the utility does indicate it is Mac only.

Note: The following information applies to Day One Mac 2.1.2 and later.

I would suggest that the action is set so that it is not listed on iOS. The script step is set to be enabled on Mac, but these action level settings mean the action will be listed.

An alternative might be to have an iOS only step that does not use the CLI utility, or notifies the user that because it needs to utilise the command line tool, it will only function on macOS.

Thanks, have updated the description above, and removed visibility on iOS. Previously I had it disabled on iOS but I guess that is not sufficient.

From what I saw, you had disabled the first step of the action for iOS. That step settings are typically used where you want different steps within an action to run on different OSes.

The settings at the action level determine if the action is visible to end users in non-Management lists on the OSes.

They actually serve different functions, but there are no hard and fast rules on the use as such. I can think of scenarios where you might have a macOS only action visible on iOS and where you might hide an action entirely on both flavours of OS.

1 Like

Understood, thanks for clarifying.

This is really nice and I’ve managed to get it working. I suspect that, looking at the DayOne CLI page, it’s possible to send to a specific journal? I’ve tried amending your script but in the manner of someone fumbling around in the dark looking for a light switch. Any chance you could tweak so as to allow user to insert a journal name into the code? Cheers.

1 Like

Good suggestion! OK I’ve updated it to allow a journal to be specified. Just uncomment the first line and set the name of your desired journal.

If there’s a better way to configure this I’d appreciate suggestions, still finding my way around here.

1 Like

Thanks alastair for this great action.
I’ve switched over to it from using Siri Shortcuts that I had setup to do something similar.
Shortcuts is great, however I sometimes get errors, and this is noticeably quicker!

I had to tweak the match part of the script when finding the UUID from the output of the dayone2 cli.
It wasn’t opening day one and on further inspection I noticed that it was only returning “C” being the first letter of the output. My updated part is:

// Extract the UUID of the new Day One entry from the standard output
let uuid = runner.standardOutput.match(/[0-9a-fA-F]{32}/)

Your script made me open up to learning a bit more about the drafts scripting, so thanks for the inspiration.
I had added in a journal option in a slightly different method to yours. Specifying the journal as default an adjusting the name. However I like your idea of if not uncommented then apply the default.
It led me to see if there was a way to specify my journals in a list and choose from one.
I put this together (with the help of ChatGPT, which has been great for learning scripting)
For anyone who might find this helpful. Insert this at the top of the script:

// Define the journal names
let journalNames = ["Journal", "Notes", "Ideas", "Work notes", "How To"];
// Create a prompt for journal selection
let p = Prompt.create();
p.title = "Select Journal";
p.addSelect("journal", "Journal", journalNames, [], false);
p.addButton("OK");
// Show the prompt and get the selected journal
let didSelect = p.show();
let journal;
if (didSelect) {
  journal = p.fieldValues["journal"];
} else {
  journal = "Journal"; // Default journal name
}

And amend the dayone2 cli call part with:

  --journal "${journal}" -- \

I also thought to try and resolve your TODO regarding different output text name.
I wondered if I could use the uuid of the draft as the file name. After some trial and error I think I got there.

For anyone interested, here’s how I used perplexity.ai to try to get to the bottom of this:
use uuid of drafts note for temp text file output

This is the entirety of the updated script that works for me:

// Define the journal name
let journal = "Log";
// Define draft uuid
let draftUuid = draft.uuid;
// Create a local file manager
let fmLocal = FileManager.createLocal();
// Write the content of the current draft to a local file
let filePath = "/" + draftUuid + ".txt";
fmLocal.writeString(filePath, draft.content);
// Format the creation date of the draft to ISO 8601 format, removing milliseconds
let dt = draft.createdAt.toISOString().replace(/\.\d+Z$/, "Z");
// Combine the draft's tags with the tag "drafts"
let tags = ["drafts"].concat(draft.tags);
// Construct the shell script to create a new entry in Day One
// The script uses the dayone2 CLI and the content of the local file
// The entry is tagged, geotagged, and timestamped according to the draft
let script = `#!/bin/bash -eu
/usr/local/bin/dayone2 \
  --isoDate=${dt} \
  --coordinate ${draft.createdLatitude} ${draft.createdLongitude} \
  --tags ${tags.join(" ")} \
  --journal "${journal}" -- \
  new <${fmLocal.basePath}${filePath}`
// Create a shell script runner and execute the script
let runner = ShellScript.create(script);
if (!runner.execute()) {
  throw new Error(`stdout:${runner.standardOutput}\nstderr:${runner.standardError}`)
}
// Extract & Open the UUID of the new Day One entry from the standard output
let dayOneUuid = runner.standardOutput.match(/[0-9a-fA-F]{32}/)
if (dayOneUuid.length) {
    draft.setTemplateTag('d1uuid', dayOneUuid[0]);
    app.openURL(`dayone://view?entryId=${dayOneUuid[0]}`);
}

Thanks again alastair for the inspiration!

1 Like

Marvellous. Thanks for making the change. Cheers.

Wow. This looks interesting. Thanks for posting.

Hi @ditfantete and thanks for the kind comments and great suggestions. I’ve updated the action accordingly, hopefully it accommodates your usage.

Your change to add the template tag to the output uuid gave me the inspiration to allow customization of the Day On journal in a separate step. You can add steps to allow user selection of the journal via Prompt or whatever is desirable. I think this is the most flexible approach.

Following that idea I added a template tag for the default Day One tag (previously hardcoded to “drafts”). Also I incorporated your change to output the Day One UUID as a template tag, although it is currently unused.

I also incorporated your changes to the UUID regex and to the output file name. Thanks so much for those!

I didn’t include your change to the passing of the --journal parameter, as I wasn’t exactly sure what problem it was solving? I am using the -- argument as suggested by the Day One CLI docs, namely as a delimiter for the --tags argument.

Thanks again for the feedback! Cheers.