Scripting Notes: The Note Class

In the Notes scripting dictionary, the note class is found in the Notes suite. It contains a few standard properties: name, id, and container; some specialized properties: body, creation date, modification date; and contains one element, attachments.

note n : a note in the Notes application

elements

contains: attachments; contained by application, folders.

properties

name (text, r/o) : The name of the note.

id (text, r/o) : The unique identifier of the note.

container (account or folder, r/o) : the container of the note

body (text) : the HTML content of the note.

creation date (date, r/o) : the creation date of the note.

modification date (date, r/o) : the modification date of the note

responds to

count, delete, exists, make, move

Example Scripts

The following script examples demonstrate how to access and manipulate the note class element. To open an example script in the AppleScript Editor application on your computer, click the script icon at the top left of an example script. (Requires OS X Mountain Lion)

The first collection of script samples, deal with the management of notes:

Click to open example in the Script Editor application Delete All Notes of an Account
This script will delete all of the notes in an account. If more than one account exists, all container hierarchy of all notes are examined to determine which notes belong in the account chosen by the user.
tell application "Notes"
set the accountCount to the count of accounts
if accountCount is 1 then
set the dialogMessage to ¬
"This script will attempt to delete all notes of the current account."
else
set the dialogMessage to ¬
"This script will attempt to delete all notes of a chosen account."
end if
display dialog dialogMessage & linefeed & linefeed & ¬
"This action cannot be undone." buttons {"Cancel", "Continue"} ¬
default button 1 with icon 2
if the accountCount is 1 then
delete every note
else
set thisAccountName to (my getNameOfTargetAccount("Choose an account:"))
set allNotesOfAccount to (my getAllNotesFromAccountNamed(thisAccountName))
repeat with i from 1 to the count of allNotesOfAccount
delete (item i of allNotesOfAccount)
end repeat
end if
display dialog "All notes have been deleted from account “" & thisAccountName & ¬
".”" buttons {"OK"} default button 1 with icon 1
end tell

on getNameOfTargetAccount(thisPrompt)
tell application "Notes"
if the (count of accounts) is greater than 1 then
set theseAccountNames to the name of every account
set thisAccountName to ¬
(choose from list theseAccountNames with prompt thisPrompt)
if thisAccountName is false then error number -128
set thisAccountName to thisAccountName as string
else
set thisAccountName to the name of account 1
end if
return thisAccountName
end tell
end getNameOfTargetAccount

on getAllNotesFromAccountNamed(targetAccountName)
tell application "Notes"
set the matchingNotes to {}
repeat with i from 1 to the count of notes
set thisNote to note i
set thisItem to thisNote
-- walk up the container chain until the account container is reached
repeat
set thisContainer to the container of thisItem
if (the class of thisContainer) is account then
if the name of thisContainer is targetAccountName then
set the end of matchingNotes to thisNote
end if
exit repeat
else
set thisItem to thisContainer
end if
end repeat
end repeat
return matchingNotes
end tell
end getAllNotesFromAccountNamed

The first set of example scripts demonstrate using the value of the note creation date property to identify and manipulate specific notes:

Click to open example in the Script Editor application Archive Last Month’s Notes
This script will archive (move) all of the notes created last month into a folder named for the previous month, located in an archive folder at the top level of the account.
-- Create date objects for the start of the last month and the current month
set startOfThisMonth to current date
--> date "Thursday, July 19, 2012 12:08:56 PM"
set day of startOfThisMonth to 1
set time of startOfThisMonth to 0
--> date "Sunday, July 1, 2012 12:00:00 AM"
set startOfLastMonth to startOfThisMonth - (1 * days)
--> date "Saturday, June 30, 2012 12:00:00 AM"
set day of startOfLastMonth to 1
set time of startOfLastMonth to 0
--> date "Friday, June 1, 2012 12:00:00 AM"
set nameOfLastMonth to (month of startOfLastMonth) as string
set yearOfLastMonth to (year of startOfLastMonth) as string

tell application "Notes"
set the accountCount to the count of accounts
if accountCount is 1 then
set the dialogMessage to ¬
"This script will attempt to archive all of last month’s notes of the current account."
else
set the dialogMessage to ¬
"This script will attempt to archive all of last month’s notes of a chosen account."
end if
display dialog dialogMessage & linefeed & linefeed & ¬
"This action cannot be undone." buttons {"Cancel", "Continue"} ¬
default button 1 with icon 2
if the accountCount is 1 then
-- find all of the notes created last month by searching at the application level
set the matchingNotes to ¬
(every note whose creation date is greater than or equal to startOfLastMonth ¬
and creation date is less than startOfThisMonth)
else
set thisAccountName to (my getNameOfTargetAccount("Choose an account:"))
set allNotesOfAccount to (my getAllNotesFromAccountNamed(thisAccountName))
set matchingNotes to {}
repeat with i from 1 to the count of allNotesOfAccount
set thisNote to (item i of allNotesOfAccount)
set thisCreationDate to the creation date of thisNote
if thisCreationDate is greater than or equal to startOfLastMonth ¬
and thisCreationDate is less than startOfThisMonth then
set the end of the matchingNotes to thisNote
end if
end repeat
end if
if the (count of the matchingNotes) is 0 then
display alert "NO MATCHES" message ¬
"No notes were found that were created last month." buttons {"Cancel"} ¬
default button 1 cancel button "Cancel"
end if
-- create the destination archive folder by adddressing the account class
set the archiveFolderName to ¬
"Archive" & space & nameOfLastMonth & space & yearOfLastMonth
tell account thisAccountName
if not (exists folder "Archive") then ¬
make new folder with properties {name:"Archive"}
if not (exists folder archiveFolderName of folder "Archive") then
make new folder at folder "Archive" with properties {name:archiveFolderName}
end if
end tell
if the accountCount is 1 then
-- address application-level to move matching notes
move matchingNotes to ¬
folder archiveFolderName of folder "Archive" of account thisAccountName
else
repeat with i from 1 to the count of the matchingNotes
move (item i of matchingNotes) to ¬
folder archiveFolderName of folder "Archive" of account thisAccountName
end repeat
end if
display dialog "Last month’s notes of account “" & ¬
thisAccountName & "” have been archived." buttons {"OK"} default button 1
end tell

on getNameOfTargetAccount(thisPrompt)
tell application "Notes"
if the (count of accounts) is greater than 1 then
set theseAccountNames to the name of every account
set thisAccountName to ¬
(choose from list theseAccountNames with prompt thisPrompt)
if thisAccountName is false then error number -128
set thisAccountName to thisAccountName as string
else
set thisAccountName to the name of account 1
end if
return thisAccountName
end tell
end getNameOfTargetAccount

on getAllNotesFromAccountNamed(targetAccountName)
tell application "Notes"
set the matchingNotes to {}
repeat with i from 1 to the count of notes
set thisNote to note i
set thisItem to thisNote
-- walk up the container chain until the account container is reached
repeat
set thisContainer to the container of thisItem
if (the class of thisContainer) is account then
if the name of thisContainer is targetAccountName then
set the end of matchingNotes to thisNote
end if
exit repeat
else
set thisItem to thisContainer
end if
end repeat
end repeat
return matchingNotes
end tell
end getAllNotesFromAccountNamed

The following script is another example using the every…whose clause construct to locate notes based on the value of their creation date property:

Click to open example in the Script Editor application Delete All Notes Created Prior to the Current Month
This script will delete all notes (in all accounts) that are older than the current month.
-- Create a date object for the start of the current month
set startOfThisMonth to current date
--> date "Thursday, July 19, 2012 12:08:56 PM"
set day of startOfThisMonth to 1
set time of startOfThisMonth to 0
--> date "Sunday, July 1, 2012 12:00:00 AM"

tell application "Notes"
display dialog "This script will delete all notes created before the current month." & linefeed & linefeed & "This action cannot be undone." buttons {"Cancel", "Continue"} default button 1 with icon 2
delete (every note whose creation date comes before the startOfThisMonth)
display dialog "All notes older than the current month, have been deleted." buttons {"OK"} default button 1 with icon 1
end tell

The Note Body

The value of the body property of a note is text written using HTML (Hypertext Markup Language). Because of this, note body can be presented with nearly all aspects stylized and formatted. The following example scripts demonstrate some of the possible styling options.

NOTE: pasting formatted text into a stylized note created by a script, may cause the note styling to be lost. Therefore, to preserve note styling, only paste plain text into the styled note. For your convenience, a script has been included in this section, that converts styled text on the clipboard to plain text on the clipboard. Run the script before pasting into a style note.

Click to open example in the Script Editor application Create Note with Chosen Background & Font Colors
This script will create a new note with a background color and font color chosen by the user. To preserve the chosen formatting when pasting text into the note, use the next script (below this script) to convert the clipboard contents to plain text.
tell application "Notes"
display dialog "This script will create a new note with a background color and font color you have chosen." with icon 1 with title "Create New Note"
set the chosenBackgroundRBGValue to choose color default color {60708, 59901, 43325}
set the chosenBackgroundColorAsHTML to my RGB2HTML(chosenBackgroundRBGValue)
set the chosenFontRBGValue to choose color default color {60708, 59901, 43325}
set the chosenFontColorAsHTML to my RGB2HTML(chosenFontRBGValue)
set the noteBody to "<html>
<head>
<style type=\"text/css\">
div.background{background-color:" & chosenBackgroundColorAsHTML & ";margin:0;height:100%;width:100%;position:absolute;top:0;left:0;z-index:-1;-webkit-user-select:none;}
ol, ul, li{color:" & chosenFontColorAsHTML & "}
</style>
</head>
<body style=\"color:" & chosenFontColorAsHTML & ";margin:0;padding:24px;\">New Note
<p>To avoid losing the background color of this note when pasting text into it, paste only plain text into this note body.</p>
<p>For more information about scripting Notes, visit: <a href=\"http://macosxautomation.com/applescript/notes\">MACOSXAUTOMATION.COM</a></p>
<div class=\"background\"></div>
</body>
</html>"
set thisAccountName to my getNameOfTargetAccount("Choose an account:")
-- make a new note at the top application-level:
make new note at folder "Notes" of account thisAccountName with properties {name:"New Note", body:noteBody}
end tell

on RGB2HTML(RBGValues)
-- NOTE: this sub-routine expects the RBG values to be from 0 to 65535
set the hex_list to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
set the the hex_value to ""
repeat with i from 1 to the count of the RBGValues
set this_value to (item i of the RBGValues) div 256
if this_value is 256 then set this_value to 255
set x to item ((this_value div 16) + 1) of the hex_list
set y to item (((this_value / 16 mod 1) * 16) + 1) of the hex_list
set the hex_value to (the hex_value & x & y) as string
end repeat
return ("#" & the hex_value) as string
end RGB2HTML

on getNameOfTargetAccount(thisPrompt)
tell application "Notes"
if the (count of accounts) is greater than 1 then
set theseAccountNames to the name of every account
set thisAccountName to ¬
(choose from list theseAccountNames with prompt thisPrompt)
if thisAccountName is false then error number -128
set thisAccountName to thisAccountName as string
else
set thisAccountName to the name of account 1
end if
return thisAccountName
end tell
end getNameOfTargetAccount
Click to open example in the Script Editor application Convert Clipboard to Unicode Text
Use this script to convert styled text on the clipboard to Unicode text on the clipboard.
set the clipboard to (the clipboard as Unicode text)
beep 2

By including advanced HTML source in the script, very stylized notes can be created. These notes can optionally be re-purposed as HTML-based Mail messages:

Click to open example in the Script Editor application Create New Stylized Note
This script creates a new stylized note that includes links and an image sourced from the internet. Note that the edited stylized note can be turned into a formatted email message by using the Share menu.
tell application "Notes"
set the noteBody to "<html>
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
<style type=\"text/css\">
p{margin-left:12;margin-right:12;margin-bottom:10;font-size:normal;font-family:Verdana,sans-serif;line-height:1.8em;color:#fff;text-align:left;}
p.signature{font-family:'Noteworthy-Light',serif;font-size:xx-large;text-align:right;margin-right:72px;}
p.title{margin-top:6px;margin-bottom:8px;font-family:'ArialRoundedMTBold',sans-serif;letter-spacing:1px;font-size:x-large; font-variant:small-caps;}
div.footer{background-color:#183D0F;text-align:center;padding-top:6px;padding-bottom:6px;}
div.background{background-color:#333;margin:0;height:100%;width:100%;}
div.content{margin-left:auto;margin-right:auto;width:100%;max-width:640px;background-color:#444;padding:18 0 0 0;height:%90;}
div.banner{-webkit-user-select:none;width:%100;}
a:link{color:#FFCC66;text-decoration:none;}
img{max-width:100%;}
ul{color:#fff;margin-left:1.5em;}
ol{color:#fff;margin-left:1.5em;}
li{color:#fff;margin-bottom:6px;font-size:normal;font-family:Verdana,sans-serif;}
</style>
</head>
<body style=\"font-size:normal;font-family:Verdana,sans-serif;line-height:1.8em;color:#fff;text-align:left;word-wrap:break-word;-webkit-nbsp-mode:space;-webkit-line-break:after-white-space;-webkit-line-grid:none;margin:0;height:100%;width:100%;\">
<div class=\"background\">
<div class=\"content\">
<div class=\"banner\"><a href=\"http://bayareaforestscouts.org\"><img src=\"http://bayareaforestscouts.org/bafs-banner-700.jpg\"></a></div>
<p class=\"title\">Note Title Goes Here</p>
<p>Greetings, I’m Trudy, Director of the Bay Area Forest Scouts.</p>
<p>Mauris blandit, eros auctor feugiat pretium, massa dolor fermentum tortor, nec faucibus est nunc ullamcorper dui. Ut tincidunt, dui vel auctor facilisis, eros neque varius felis, sed eleifend eros enim sed ligula. Nulla rhoncus consectetur nunc at placerat. Cras id sollicitudin odio. Aenean pharetra turpis et neque gravida rutrum. In vitae nibh massa.</p>
<p>In congue tellus eget lacus feugiat bibendum. Vestibulum rutrum iaculis rutrum. Curabitur euismod lectus ut nisl posuere elementum. Sed facilisis volutpat turpis, et pellentesque enim lacinia vel. Duis bibendum massa id mauris aliquet et congue arcu blandit.</p>
<p class=\"signature\">Trudy Anchover</p>
<div class=\"footer\">Please visit the Bay Area Forest Scouts at <a href=\"http://bayareaforestscouts.org\">bayareaforestscouts.org</a></div>
</div>
</div>
</body>
</html>"
set thisAccountName to my getNameOfTargetAccount("Choose an account:")
make new note at folder "Notes" of account thisAccountName with properties {name:"Note Title Goes Here", body:noteBody}
end tell

on getNameOfTargetAccount(thisPrompt)
tell application "Notes"
if the (count of accounts) is greater than 1 then
set theseAccountNames to the name of every account
set thisAccountName to ¬
(choose from list theseAccountNames with prompt thisPrompt)
if thisAccountName is false then error number -128
set thisAccountName to thisAccountName as string
else
set thisAccountName to the name of account 1
end if
return thisAccountName
end tell
end getNameOfTargetAccount
stylednote

Use the Share menu in Notes to create a formatted Mail message from the stylized note:

sharemenu styledemail

TOP | CONTINUE