Create a New Note From AppleScript

I like your thinking…

Right now, I’m just exploring the realm of the possible for someone like me with limited skills in AppleScript and Action Code. Having the URL in the $Text is useful for now. It might be neater to have it in the $URL attribute, making that attribute among the $KeyAttributes for the p_Entry prototype.

(Also, the lower case E and C are what appear in the URI as detected by AppleScript, and which do open the email when clicked in the clipboard manager. So I’m not certain that would be an error.)

I’ll have to sit down and think of the steps to get the URL into the AppleScript. Automator has some handy URL actions that I hope to explore, but I would do so cautiously. Alternatively, some $Rule that would scan $Text and auto-populate $URL, but then I’m bumping up against my Action Code ignorance. (At the moment, that feels like a lower barrier to overcome than fancy work with AS and attributes.)

For now, I was wondering if there was something I could invoke like “paste as unstyled text” or something like that from the clipboard that would make the URL clickable in $Text. (Which I just thought of, or I’d have tried it before posting this.)

But thanks for the response, you’ve given me an idea or two. This is such a nice community.

Thanks, I’ll check it out!

I’ve joined the PopClip forum and posed a question there regarding Snippets, which seem to be the relevant approach. That link is from 2019 and the Terminal command doesn’t find the array of URL schemes on my machine.

In other developments… I copied the URI to the clipboard, entered some text into a new log entry (not relying on any automation, just working in the file in Tinderbox).

I selected a portion of the text and used the Make Web Link… menu item to make that text into a link.

It worked. Clicking on the text opens the email in Mail.

Likewise, entering the URI into the SourceURL attribute (added as a $DisplayedAttribute in p_Entry), makes it clickable when I click on the globe icon in the Displayed Attributes.

So I think the URI is correct in all respects. It would just be nice to have that URI, ugly as it may be, be a clickable link in the $Text attribute.

Failing that, or in addition to, having some action code scan the $Text for a URI or URL and having it automatically populate the $SourceURL attribute would be a significant improvement.

Thinking through this some more, the “workflow” for making a log entry referencing an email would rely on the $Name attribute to record whatever comment about the email was relevant for the log. “Nice email from Mark Anderson” or something.

Then the $Text would exclusively be the Mail URI.

I think I should be able to cobble together some Action Code in a $Rule(?) to make $SourceURL=$Text and have a clickable link in the log entry note with no further user intervention.

Maybe I should try that rather than taking up everyone’s time here. But it seems like I “see what I think” here too…

Upload shouldn’t be disabled, but it is limited in the formats it accepts (which are tested via the uploaded file’s extension. There may be limitations on what is allowed in the name of the uploaded file.

Not quite clear is the context. I think your scenario is you are adding text to a note that includes a URI (in this case using message:// protocol). Although web links in pasted-in rich text are adopted from the RTF as a Tinderbox web links, I don’t think URIs in plain text URI are detected in the same way. If you are pasting in plain text into $Text then I doubt there is anything to trigger URI detection.

But, as you’re using AppleScript why not post RTF including a link instead of plain text? (Not that I know how to do that, as I write this)

But, as you’re using AppleScript why not post RTF including a link instead of plain text? (Not that I know how to do that, as I write this)

Precisely. I don’t know how to do it either. It’s kind of a question of how important it is.

The important thing is to have the URI somewhere in the log entry, and it’s a trivial matter to get it into $Text, although it’s not immediately clickable.

Manually, I can copy and paste it into the $SourceURL attribute (displayed in p_Entry in the present version of the file), and it becomes clickable there.

For a hands-off operation, I think a $Rule along the lines of $Text.contains some regex to describe an email URI, followed by some code to set $SourceURL to $Text.contains, though I don’t know how that works either. I think it’ll be easier to figure out than a bunch of AppleScript. I’ve been looking at aTbRef and posts in the forum, but I’m happy to let someone just show me!

Then some code to turn off the Rule after the action is completed. It only has one thing to do, and it’d become part of every log entry as it’s in the prototype.

Maybe it would be better as an $OnAdd action, if $Text.contains an email URI, then set the $SourceURL to the URI. (Through some magic that I think I can get Michael Becker to demonstrate at a meetup. :wink:)

Likewise, if $Text.contains a web URL, do the same thing.

OnAdd is probably better than a Rule in the Entry prototype. Gets processed once and it’s done.

I don’t anticipate having $Text with multiple URLs or URIs, though I know that wants and desires can grow over time. For now, it’s enough to just collect a link to the thing that was logged, assuming it has a URL or URI.

I think that’s what I’m going to pursue for now. There are other things I think I want to try with AppleScript, but I want to pick my battles so I don’t get too discouraged!

I’d welcome a precis by email of the URI questions, once those become clear; I’m beyond swamped.

1 Like

Hi Dave … I really like what you’re doing with this script, and I got it working on my end as well.

Then I played around with AppleScript to extend your script so that it brings in a selected message from Apple Mail:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application "Mail"
	--	if not it is running then activate
	
	if not (get selection) is {} then
		set theMsg to item 1 of (get selection)
	else
		return
	end if
	
	tell theMsg
		set {msgSubj, msgSender, msgContent, msgID} to {subject, sender, content, message id}
		set theText to content of theMsg
		set theSubj to subject of theMsg
		set theSender to sender of theMsg
		set msgURL to "message://%3C" & msgID & "%3E"
		set dateSentStr to my dateToStr(date sent)
		set existsAttach to exists mail attachments
	end tell
end tell

tell application "Tinderbox 9"
	set this_moment to (the current date)
	set nmMonth to (month of this_moment) as string
	set nmYear to (year of this_moment) as string
	set thePath to "CaptainsLog/" & nmYear & "/" & nmMonth & " " & nmYear & "/" & date string of this_moment
	tell document "CaptainsLog.tbx" -- suffix .tbx required on my machine
		-- this is how to specify a note down in the hierarchy:
		set theContainer to find note in it with path thePath
		set newNote to make new note at theContainer
		tell newNote
			set value of attribute "Prototype" to "pEmail"
			set value of attribute "Name" to theSubj
			set value of attribute "Attachment" to existsAttach
			set value of attribute "URL" to msgURL
			set value of attribute "StartDate" to dateSentStr
			set value of attribute "Sender" to theSender
			set value of attribute "Text" to theText
		end tell
	end tell
end tell

to dateToStr(aDate) --> convert AppleScript date to string in format that Tinderbox recognizes
	tell aDate to return date string & ", " & time string
end dateToStr

Still a work in progress, but it works! Next step is probably to do the same thing with Calendar events.

1 Like

I’ve emailed @eastgate with a summary. Essentially:

Cutting aside all the wider context the question is this:

  • via script we set $Text of a note
  • the new text includes a valid URI as plain text, i.e. there is no Tinderbox web link on the URI text.
    • e.g. This is some message://%3cdiscourse/post/41031@forum.eastgate.com%3e more text.
  • placing the text insertion cursor in $Text after the end of the URI and typing a character triggers auto-recognition/adoption of the URI. But we can’t do that during scripting.
  • how do we, can we, signal to Tinderbox that we want it to scan the note’s text and adopt any valid URI?

Note, I tried running update() on such a note but it had no effect on undetected URI.

TL;DR we are looking for a user-activated call to scan and adopt valid URIs.

1 Like

That’s very cool!

This suggests, to me, to create a separate AppleScript for logging emails to Captain’s Log.

In my conception, I wouldn’t need each of those attributes. Basically just the URL. I don’t need to replicate the contents of the email in the log, just record that I received it (for whatever reason that made it worthwhile to log, maybe my reaction to it or whatever), and a link to the original email.

I see how you’re constructing the URI (msgURL) using

"message://%3C" & msgID & "%3E"

It makes me wonder if the case of C and E is irrelevant?

So I think I’ll take your script, modify it, and then add it to the FastScripts Menu for Mail. I’d keep the same Title and Text dialogs as they, together with $Created, are the essential elements of a “log entry.” Then I wouldn’t need an OnAdd in a day’s container to move the URI from $Text to $URL as it’d be populated that attribute directly from the Mail AppleScript.

Likewise, a similar AS in the FastScripts menu for Safari to Captain’s Log.

I haven’t completely figured out what I want the interaction with Calendar to be.

The log isn’t intended as a planning document. There’s a feature that allows you to attach an Automator action to an Alert for an event (I just looked and it must be “Open File,” I’m not sure. I’m relying on watching old YouTube videos, maybe the functionality has changed), and I thought that I might, for certain events, have an entry automatically created in the log.

Medical or dental appointments, or social events, as those are the kinds of things that you’re AFK, and maybe you remember to log them when you get back or maybe you don’t. But if Calendar does it for you, no worries.

Apart from long-form entries, the log is intended as a memory aid, “When was the last time…?” (I changed the air filter. We had dinner with Faith and Rick. etc.)

I don’t need to replicate the data contained in apps better designed to contain that information, I just want to be able to get to it quickly. Presumably “Search” answers many of those questions, but I think a lot of that can be be more useful in a broader context of a personal timeline, which is what the log is intended to be.

But this has been very helpful, and has given me a new direction for making entries from other apps.

And don’t take my comments to say I think “you’re holding it wrong.” There are many ways to configure such a “log” document to suit each individual’s needs or purposes, and I’m sure they’re all different.

I think it’s remarkable that we have such a facility available to us, which rewards time spent learning Tinderbox.

Thanks again.

Thanks, Mark. I was going to reply that I’m not sure we require any action on his part at this time. I think Paul’s AppleScript answers much of the issue. And I hadn’t noticed that you can force the detection. I just tried it, and wow! Maybe I don’t even need a separate AppleScript for Mail.

So many ways to skin a cat! Which one is “best”? The tyranny of choice!

(Let me add that I am going to implement Paul’s AS solution, if for no other reason than the very worthwhile exercise of using AppleScript and hopefully learning something in the process.)

1 Like

Re the issue of ‘just’ :roll_eyes: making RTF with a link, I think this thread (from the OmniOutliner forum) might help.

%-prefixed URL-encoding codes are not case sensitive by intent: see RFC 3986: Uniform Resource Identifier (URI): Generic Syntax. But code parsing those might decide differently, in which case the choice is the coder’s not the standard.

Aside the code at play here are encoding angle brackets. The first line below is the urlencoding of the last:

message://%3cdiscourse/post/41031@forum.eastgate.com%3e
message://<discourse/post/41031@forum.eastgate.com>

IOW, the angle brackets are enclosing an email address.

1 Like

Thanks!

I’m here to report I just implemented the AppleScript I outlined above. (Had to change my Doc name because Paul went the safe route and eliminated the spaces and apostrophe. But I don’t “hear” William Shatner if it doesn’t say “Captain’s Log.” :stuck_out_tongue_winking_eye:)
It worked great! (I was also using $SourceURL, Paul went with just $URL. I made $URL a $DisplayedAttribute and it was populated as intended.)

The email I “logged” was Nick Moore, PopClip developer, responding to my query at the PopClip forum about a Mail URI extension for PopClip. Said response is here.

Another example of a generous and responsive developer. I recommend PopClip as a very useful addition to MacOS. Have used it for years. (Mostly to look up words.)

2 Likes

It still works, you didn’t do what I wrote in the linked post in 2019 :slight_smile:

You first need to use the defaults write command. Without using it PopClip’s plist doesn’t contain the OtherURLSchemes key. That’s why defaults read didn’t find it.


In your thread on the PopClip forum Nick mentioned that one can simply add new URL schemes via -array-add. Didn’t know that, it’s a lot easier than my old approach. Thanks!

2 Likes

The discussions in this other thread may be directly relevant. In fact some of the scripts above in this thread bear a striking resemblance to scripts in that thread!

Plain vanilla AppleScript is not good at outputting rtf or quasi-rtf (or whatever it is) for the Tinderbox Text pane. I haven’t found a way to do that without going through the clipboard.

The discovery by @mwra that typing a character after a (plain text) url in Text makes it clickable is intriguing! (The “raw” link unfortunately looks a bit ugly but it could work if there were some way to trigger Tinderbox to look for and activate links.)

AppleScript can easily output plain text for the URL attribute in Tinderbox where it is immediately clickable. That’s why I suggest going that route rather than trying to place a link in the Text pane. It’s easy to implement.

But if your goal is to have a pretty link in the Text pane instead of, or in addition to, the URL attribute then you can convert the plain text message link AppleScript extracts from Apple Mail into rtf using textutil within an AppleScript and place the result on the clipboard for pasting into the Text pane as a clickable link that uses the subject line of the message.

This is a script as posted in the other thread that does this …

tell application "Mail"
	tell first item of (get selection)
		set theHTMLLink to "<a href=\"" & "message://%3C" & its message id & "%3E" & "\">" & its subject & "</a>"
	end tell
end tell
-- convert html to "rtf" link and place on clipboard for pasting wherever
do shell script "echo " & quoted form of theHTMLLink & " | textutil -format html -encoding UTF-8 -convert rtf  -stdin -stdout | pbcopy -encoding UTF-8 -Prefer rtf "

Here it is in a Shortcut, also posted in the other thread:
Mail Message URL to Clipboard

(Click with Safari to view/install Shortcut)

BTW, for recent macOS version, a Shortcut in the built-in Shortcuts app pinned to the menu bar may be more convenient than going the old Automator and Services Menu route. Either way, lots of things can be done quite easily without dependency on third-party apps.

1 Like

Thanks, Sumner. It’s interesting, how many ways we can accomplish a certain result.

In this case, though, I didn’t get a clickable link in RTF on the clipboard. I copied the script from the post using the copy icon in the upper right corner of the code block, pasted it into Script Debugger and ran it without errors. But plain text(?) was what was on the clipboard.


Screenshot of UnClutter clipboard manager.

Pasting into $Text showed same:

This isn’t essential for my use case, I’m good with the link in any of the $URL attributes. But I was interested in the technique, perhaps for use in my blog.

Is there something clearly obvious I’m doing wrong?

(To clarify, I’d already created a log entry for the email notification from the forum, using the solution developed in Paul Christy’s script above. That’s why the URL is populated there. Subsequent to that entry, I went ahead and tried the script, and simply pasted the result in to the existing $Text of that log entry to see if it was an rtf link. It didn’t get there by any other “automated” means.)

Finally, I am getting good use from Captain’s Log even now. I’m looking forward to some weeks’ worth of entries and beginning to do some experiments with linking and agents and so on.

Not “wrong.” But there is something you are doing differently or something different that you have on your machine.

I can:

  1. Select a message in Mail
  2. Run the script (either from Script Editor or by choosing the Short Cut from a menu in the Menu Bars)
  3. Click in the text in the Text pane and paste.

The result is a clickable link in nice format in Text. (Or anywhere else you paste the results where rtf is accepted.)

I’m guessing you may have a third-party clipboard manager or other app that interferes with the normal operation of the clipboard.

Those can provide benefits in some situations, and can be fun to play around with. But when I’m trying to think and get work done, as opposed to play with the process, I’ve found they can be more trouble than they’re worth.

Often the built-in technology on the Mac (together with Tinderbox of course😀) is more than enough to do things efficiently. Add-ons and utilities sometimes fall in the “nice but not necessary” category.

A few years ago I used vanilla AppleScript not unlike some I posted in the other thread and you see above to bring hundreds (actually I think thousands) of emails into Tinderbox. I sorted and organized them in themes, and then dumped the result into Pages to create a nicely formatted book with an index, all with Tinderbox as the only third-party app.

If you haven’t done so already, do have a look at the built-in Shortcuts app.

2 Likes

New question:

I have an $Edict in p_Day :

$MyString="Midwatch";
create($MyString);

This worked on Friday. Of course, it was the middle of the day since that’s when I wrote it.

Today, it isn’t working. The $Edict is inherited from the $Prototype p_Day. It is enabled in the Saturday, March 9, 2024 container.

It won’t run, even with “Run now”.

Consulting aTbRef, I noted that,

but if nameStr is a unique note $Name, a new note is created as a new (last) child of the current note.

and

Essentially, the two-input form allows 3 forms of variation:

different path, different name (via two nested loops—one for paths, one for names)
different path, same name (loop with path variants)
same path, different name (loop with name variants)

This implies to me that “Midwatch” is a “unique” note $Name, as long as it’s in a “different path.”

So, why won’t this work?

I thought I had the whole “Create” thing down.

Also, thinking I had made it too complicated by using $MyString, I changed it to just the simple command:

create(“Midwatch”);

Also not working. And I checked, no curly quotes.

To recap: Worked on Friday. Won’t work on Saturday. Unique $Paths.

The code works for me both as an edict and as a stamp. But, using the create(noteName) syntax it appears that if noteName is a note $Name, then it must be unique to the whole document. In my text, once a single “Midwatch” note is present in the TBX, this code:

$MyString="Midwatch";
create($MyString);

has no result even if run in a different container to that holding the existing ‘Midwatch’. If you intend many containers to have their own ‘Midwatch’ child, then (tested!) you prototype $Edict should be:

$MyString=$Path+"/Midwatch";
create($MyString);

Guests arriving shortly, but I’d accept the ‘bare name’ syntax variant requiring the the name to unique at whole document scope and not just the current container could be made clearer in my aTbRef notes.

I think this is one of these obvious-after-the-fact things where Tinderbox is being cautious that you aren’t unintentionally spamming the TBX with loads of new notes. If there is no path element in the argument string, Tinderbox is clearly ultra cautious and allows you one note of that name per doc. Give it a path (as per my modified code), and you get one per target container. I don’t think the app defaults are bad, I just need to explain them more clearly … now I’m aware of this limitation.

†. I mean, it’s not as if we ever make mistakes writing action code and ask the app for an outcome we didn’t intend. :slight_smile:

1 Like

Roger all. Thanks!

1 Like

create([containerStr, ]nameStr) updated.

1 Like