Use Hazel to add a file to a new Apple Notes note

From your noodle to other noodles. Talk about ways to get the most from Hazel. Even exchange recipes for the cool rules you've thought up. DO NOT POST YOUR QUESTIONS HERE.

Moderators: Mr_Noodle, Moderators

For all of you trying to see if Apple Notes is a good replacement for Evernote/etc., I tried to create a way to create a new note and embed a file into it using Hazel.

I was surprised at how little I could find out there, so I clobbered this together for using in your own rules.

Before we start you need to know a few quirks about how Apple Notes notes work.
  • Every note is an HTML document
  • You currently cannot attach a note from just anywhere. Possibly due to sandboxing, the file has to be moved/copied reside into a special place ~/Library/Containers/com.apple.Notes/Data

Having said all that, all you need to do is to open Script Editor, paste the below into it, and save the file somewhere you keep those sorts of things:

Code: Select all
on hazelProcessFile(theFile, dummmy)
   set incomingFile to the POSIX path of theFile
   set notesSrc to "file://" & encodeText(incomingFile, false, false)
   set noteBody to "<html><head></head><body><img src=" & notesSrc & "></body></html>"
   tell application "Notes"
      make new note at folder "Notes" with properties {name:theFile, body:noteBody}
   end tell
   
end hazelProcessFile

on encodeText(theText, encodeCommonSpecialCharacters, encodeExtendedSpecialCharacters)
   set theStandardCharacters to "abcdefghijklmnopqrstuvwxyz0123456789"
   set theCommonSpecialCharacterList to "$+!'/?;&@=#%><{}\"~`^\\|*"
   set theExtendedSpecialCharacterList to ".-_:"
   set theAcceptableCharacters to theStandardCharacters
   if encodeCommonSpecialCharacters is false then set theAcceptableCharacters to theAcceptableCharacters & theCommonSpecialCharacterList
   if encodeExtendedSpecialCharacters is false then set theAcceptableCharacters to theAcceptableCharacters & theExtendedSpecialCharacterList
   set theEncodedText to ""
   repeat with theCurrentCharacter in theText
      if theCurrentCharacter is in theAcceptableCharacters then
         set theEncodedText to (theEncodedText & theCurrentCharacter)
      else
         set theEncodedText to (theEncodedText & encodeCharacter(theCurrentCharacter)) as string
      end if
   end repeat
   return theEncodedText
end encodeText

on encodeCharacter(theCharacter)
   set theASCIINumber to (the ASCII number theCharacter)
   set theHexList to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
   set theFirstItem to item ((theASCIINumber div 16) + 1) of theHexList
   set theSecondItem to item ((theASCIINumber mod 16) + 1) of theHexList
   return ("%" & theFirstItem & theSecondItem) as string
end encodeCharacter


  • Line 2 & 3 gets the filename Hazel is working with and does some conversion to it to make it usable in HTML. The functions it calls are not my own and are actually very powerful. Credit where credit is due
  • Line 4 is where you'll probably want to fiddle a bit to make the note more useful. As it stands, it constructs a variable with only puts the path of the file in the body text and the file itself. If you have any cool ideas about how to prettify the document with your own HTML knowledge, please do share!.
  • Lines 5-7 does the deed. Note that it creates the note in the default "Notes" folder.
  • Everything after line 10 is concerned with making sure that filenames with spaces or other weirdnesses are being handles properly

As a final note, you can delete the file once the Applescript has done its work with a followup action in Hazel. It serves no further purpose.

Here's an example of how I've set it up in a test rule:
Image

I've tested this on several PDFs and "unknown" file types. For supported file types such as PDF, Notes will display a preview. For unknown filetypes, only a placeholder will appear.
Everything syncs as expected.
snorbaard
 
Posts: 10
Joined: Fri Jan 06, 2017 5:18 am

I think note is no good place for long-term working with notes.
Reason:
Try to export more than one note. It doesn't work a good way.
There are App to batch-export notes, BUT only in text form.
Devon think can import notes but their attachments are detached in a separate folder with a cryptic name.
The only way to export the file as is, is to print it to a PDF, but one after another. Very bad.
I can't advise.
Moeri
 
Posts: 11
Joined: Tue Feb 09, 2016 10:46 am

Moeri wrote:Try to export more than one note. It doesn't work a good way.
There are App to batch-export notes, BUT only in text form.


Not yet, anyway. I'm sure someone can figure out how to export Notes in Markdown is something like that.
The thing is - there isn't really one standard for storing notes except text, especially when you take the multimedia-rich OneNote into count.

Notes only fairly recently started supporting more than text, but you have a good point.
snorbaard
 
Posts: 10
Joined: Fri Jan 06, 2017 5:18 am

@snorbaard

I wrote a script you might be interested in - it's basically similar to the one you wrote, but instead of taking one attachment and making a note out of it, it takes an email (e.g. from Mail.app) with whatever HTML styling it has and makes a note out of it. I put it up as a gist on GitHub in case you're interested here:

https://gist.github.com/milch/f775ab001 ... d6704b6d4c

I use it to create styled notes from anywhere basically, by sending it to myself as an email and sorting it into a special folder. Hazel looks for .emlx files in that mailbox, and then runs the script. Right now it only works with .emlx files, but it should be trivial to adapt to other formats.
milch
 
Posts: 2
Joined: Tue Apr 18, 2017 8:30 am

Wow that's a cool one - I'm going to look at it right now.

Thanks for sharing!
snorbaard
 
Posts: 10
Joined: Fri Jan 06, 2017 5:18 am

milch wrote:@snorbaard
I use it to create styled notes from anywhere basically, by sending it to myself as an email and sorting it into a special folder. Hazel looks for .emlx files in that mailbox, and then runs the script. Right now it only works with .emlx files, but it should be trivial to adapt to other formats.


So your Hazel rule looks for the emlx file and then executes the ruby script via a shell script?
Would you mind sharing an example of how you execute your command?

I love this!
snorbaard
 
Posts: 10
Joined: Fri Jan 06, 2017 5:18 am

Yeah, basically. I have my email set up so that every mail to notes@<my-domain>.com gets moved from my Inbox directly into a "Noted" folder. I'm using Mail.app, which creates .mbox folders for each of the mail folders in ~/Library/Mail/V4/<Account-UUID>:

Image

I've added the whole Noted.mbox folder to Hazel, created the standard "search subfolders rule" and then I added the following rule:

Image

You can also easily test to see how the script works by just calling it from the Terminal like
Code: Select all
ruby mail_to_notes.rb ~/Library/Mail/V4/.../<mail>.emlx
. All attachments, etc., should be picked up automatically. Just make sure to install the two dependencies that I've noted in the gist first.
milch
 
Posts: 2
Joined: Tue Apr 18, 2017 8:30 am

Hi, I'm using OP's script to send files to Notes App. The title of the note shows the entire file path. I would like it to show just the file name.

Does anyone know how to change the script to realise this?
Dries
 
Posts: 1
Joined: Thu Feb 01, 2018 4:40 pm

Thanks very much to the OP for this code, it works beautifully. @Dries, I had the same idea and added a bit of code achieve it.

Say you have a path such as "/Users/stefan/Library/Containers/com.apple.Notes/Data/ai.pdf", then the following code will generate a note with the title "ai", omitting both the path and the pdf extension:

Code: Select all
on hazelProcessFile(theFile, dummmy)
   tell application "Finder"
      set extension hidden of theFile to true
      set theName to displayed name of (theFile)
      set extension hidden of theFile to false
   end tell

   set incomingFile to the POSIX path of theFile
   set notesSrc to "file://" & encodeText(incomingFile, false, false)
   set noteBody to "<html><head></head><body><img src=" & notesSrc & "></body></html>"
   tell application "Notes"
      make new note at folder "Notes" with properties {name: theName, body:noteBody}
   end tell
   
end hazelProcessFile

on encodeText(theText, encodeCommonSpecialCharacters, encodeExtendedSpecialCharacters)
   set theStandardCharacters to "abcdefghijklmnopqrstuvwxyz0123456789"
   set theCommonSpecialCharacterList to "$+!'/?;&@=#%><{}\"~`^\\|*"
   set theExtendedSpecialCharacterList to ".-_:"
   set theAcceptableCharacters to theStandardCharacters
   if encodeCommonSpecialCharacters is false then set theAcceptableCharacters to theAcceptableCharacters & theCommonSpecialCharacterList
   if encodeExtendedSpecialCharacters is false then set theAcceptableCharacters to theAcceptableCharacters & theExtendedSpecialCharacterList
   set theEncodedText to ""
   repeat with theCurrentCharacter in theText
      if theCurrentCharacter is in theAcceptableCharacters then
         set theEncodedText to (theEncodedText & theCurrentCharacter)
      else
         set theEncodedText to (theEncodedText & encodeCharacter(theCurrentCharacter)) as string
      end if
   end repeat
   return theEncodedText
end encodeText

on encodeCharacter(theCharacter)
   set theASCIINumber to (the ASCII number theCharacter)
   set theHexList to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
   set theFirstItem to item ((theASCIINumber div 16) + 1) of theHexList
   set theSecondItem to item ((theASCIINumber mod 16) + 1) of theHexList
   return ("%" & theFirstItem & theSecondItem) as string
end encodeCharacter


I have used the same naming conventions as the OP. To give due credit to those who actually solved the problem in a different context, the code is an adaption from Arno's answer at stackoverlfow: https://stackoverflow.com/a/19415704.

Hope this will helps.
stefan
 
Posts: 1
Joined: Thu Mar 28, 2019 5:57 am


Return to Tips & Tricks - DO NOT POST QUESTIONS

cron