Apple Mail to Evernote

Description

Alert – September 26, 2014:
Early reports suggest that the new Evernote 5.6 update may cause errors with AppleScript. If this script is critical to your workflow, you may want to hold off from upgrading.
The Japanese Language version of this AppleScript can be found here!

You can tag your items on the way in and direct them to the proper notebook!

This AppleScript lets you move email messages directly into Evernote from Apple Mail and, if you like, tag and sort the items on the way in!

"Does it also handle attachments?", you ask. Yes -- they are also included in the Evernote item! The script includes full HTML in the items whenever possible and the header template is also fully customizable, allowing anyone with basic HTML knowledge to make their own layout. (I kept it pretty basic)

Receive Updates With GROWL Notifications

I've also built in GROWL notifications so that you'll be able to keep track of the progress of your import. THIS SCRIPT REQUIRES THE LASTEST VERSION OF GROWL. (If you prefer not to use it, just edit out these portions of the script.)

Adding By Script Vs. Adding By Email

One fast way to get items into Evernote is simply to email them. Brett Kelly's eBook, "Evernote Essentials" provides a solid guide to how this works (See the chapter called "Evernote, Email and You") along with some other great email-related tips. So why not just forward items to your Evernote email address?

You certainly can do that -- but I think this approach is actually easier and also has a few additional benefits:

  • FASTER/SMARTER WORKFLOW. If you use Keyboard Shortcuts with this AppleScript, you'll have an workflow which is incredibly fast and makes it easy to stay organized! Personally, I use ⌘E to quickly send anything to Evernote. I can also tag and direct multiple items to a notebook by using a simple, fast dialog box instead of having to email them in one at a time (Mail handles multiple emails being forwarded by combining them to a single email). Trust me -- Archiving whole folders goes much faster when you don't have to send an email for every item!

  • PRIVACY Emailing an item into Evernote probably isn't an option if you have local, non-synchronized notebooks which contain sensitive information (or should you find yourself without an internet connection). This script moves things directly -- no internet connection required!

REQUIRED / OPTIONAL APPS

THIS SCRIPT REQUIRES LION OR GREATER (OS X 10.7+) TO RUN WITHOUT MODIFICATION
NameDescription
GROWLTHE APP STORE VERSION OF GROWL IS REQUIRED FOR THIS SCRIPT TO WORK! (If you do not have it installed, you'll get an error when you try to save this script.)
Optional Apps
FastScriptsFastScripts is a powerful script management utility which gives you instant access to all your AppleScripts by keyboard shortcut or menubar -- HIGHLY RECOMMENDED!

INSTALLATION

  1. On this page, click the link below "The Code" preview window which says "Click here to open it in your Script Editor". This will open the AppleScript inside your system's default AppleScript Editor application.
  2. You can save this script to /Library/Scripts/Mail Scripts and launch it using the system-wide script menu from the Mac OS X menu bar. If you don't see the system script menu, it can be activated in the Preferences of the AppleScript Editor application. (You can, of course, save the script anywhere you like!)
  3. To use, highlight the email messages you want to archive into Evernote and run this script file.
  4. The "User Switches" at the beginning of the script allow you to customize the way it works (or switch to plaintext if HTML emails aren't being processed correctly). Please take a moment to look and familiarize yourself with the options I've put in for you!

KNOWN ISSUES / BUG REPORTS

The script isn't great at dealing with HTML-encoded emails encoded in non-English character sets. I'm looking for ways to improve this but, if you're one of the people affected, you can use the switch at the beginning of the script to turn off HTML support and process everything as plaintext.

Please don't post bug reports in the comment thread. You can click here to send a bug report directly to me.

Note to 10.9 "Mavericks" Users

10.9 and AppleScript seems to be a little glitchy at the moment…

Some of you have been reporting an annoying "There is no application set to open the URL" alert which you need to cancel out of before the AppleScript can do its job. A quick bit of Google-fu suggests that it's from a change made in 10.9, and I'm testing ways to fix or get around it on another script. Hope to share a version of this script soon which works around the bug.

I've also been receiving messages from several 10.9 users that this script is not compiling. This isn't entirely unexpected with a new OS version, but the truly fun part for me of figuring out the problem is that the script is still working fine on my 10.9 system. Sigh.

If this is happening for you, it may be that you are using the directly downloaded version of Evernote and not the one from the App Store. If you are using the App Store version and still have problems compiling, I've written a short utility script which should grab the version information for Evernote and copy it to your clipboard. You can then paste it into a Bug Report and send it to me. Reminder to new users – GROWL is required for this script to work.

If I can get enough reports, it should help me locate the issue. However, if this script is essential to your workflow, you might want to hold off on upgrading to 10.9 until the AppleScript issues are better understood/fixed/etc.

MAILTAGS SUPPORT

Earlier versions of this script supported MailTags, but I took it out to reduce the complexity of the code (and because no one said that they loved it). Recently, some people have expressed an interest in putting this back in. If you feel the same way, please let me know below.

TERMS OF USE

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

The Code

(*
◸ Veritrope.com
Apple Mail to Evernote
VERSION 2.07
March 14, 2014

// TERMS OF USE:
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

// LIKE THIS SCRIPT?
If this AppleScript is helpful to you, please show your support here:
http://veritrope.com/support

// IMPORTANT LINKS:
-- Project Page: http://veritrope.com/code/apple-mail-to-evernote

// REQUIREMENTS:
THIS SCRIPT REQUIRES LION OR GREATER (OS X 10.7+) TO RUN WITHOUT MODIFICATION

THE APP STORE VERSION OF GROWL IS REQUIRED FOR THIS SCRIPT TO WORK!
(If you do not have it installed, you'll get an error when you try to save this script.)
    -- GROWL IS AVAILABLE FOR DOWNLOAD HERE:
    -- http://bit.ly/GrowlApp

// INSTALLATION:  
-- You can save this script to /Library/Scripts/Mail Scripts and launch it using the system-wide script menu from the Mac OS X menu bar. (The script menu can be activated using the AppleScript Utility application).
-- To use, highlight the email messages you want to archive into Evernote and run this script file;
-- The "User Switches" below allow you to customize the way this script works.
-- You can save this script as a service and trigger it with a keyboard shortcut.

    (Optional but recommended)
    Easier Keyboard Shortcut with FastScripts
    -- Download and Install FastScripts here:
    -- http://bit.ly/FastScripts

// CHANGELOG:

Version 2.07: CHANGE TO UTF DECODING (THANKS EDUARDO!). CC RECIPIENTS ADDED TO NOTEHEADER

    * 2.06
    SWITCH FOR PLAINTEXT OPERATION (FOR NON-ENGLISH ENCODING), FIX FOR MISSING RECIPIENT NAME

    * 2.05
    FIX FOR LEADING SPACES IN TAG LIST
   
    * 2.04
    CHANGE TO DISPLAY MULTIPLE TO: RECIPIENTS, GROWL TWEAKS
   
    * 2.03
    FIXES AND ADJUSTMENTS FOR TAGS, ATTACHMENT OPERATIONS
   
    * 2.02
    CHANGED SOME VARIABLES TO WORK BETTER WITH "OPEN IN SCRIPT EDITOR" BUTTON
   
    * 2.01
    CONSOLIDATED SOME BASE64 CODE INTO A HANDLER, FIXED BUGS WITH ENCODING

    * 2.00 FINAL
    ELIMINATED MAILTAGS SUPPORT, GROWL REQUIREMENT, REWORKED HTML EMAIL TRANSFER FOR 10.7+ SYSTEMS

    * 2.00 b2
    BUG FIXES (USER SWITCH FOR NOTEBOOK, BETTER BASE 64 DETECTION, ATTACHMENT FIX)

    * 2.00 b1
    HTML MESSAGES, APPEND ATTACHMENTS, MAILTAGS, QUIET TEMP FILE REMOVAL

    * 1.30 (June 5, 2010)  
    ATTACHMENT CREATION. LAYING TRACK FOR HTML NOTES.
   
    * 1.20 (July 25, 2009)
    STREAMLINED MENU FOR NOTE EXPORT
   
    * 1.10 (May 6, 2009)  
    ACTIVATED MESSAGE LINKING/ADDED EVERNOTE ICON TO DIALOG BOX/MISC. CLEAN-UP!
   
    * 1.01 (April 23, 2009)
    FIXED TYPOGRAPHICAL ERROR
   
    * 1.00 (April 20, 2009)
    INITIAL RELEASE OF SCRIPT
*)


(*
======================================
// USER SWITCHES
======================================
*)


-- SET THIS TO "OFF" IF YOU WANT TO SKIP THE TAGGING/NOTEBOOK DIALOG
-- AND SEND ITEMS DIRECTLY INTO YOUR DEFAULT NOTEBOOK
property tagging_Switch : "ON"

-- IF YOU'VE DISABLED THE TAGGING/NOTEBOOK DIALOG,
-- TYPE THE NAME OF THE NOTEBOOK YOU WANT TO SEND ITEM TO
-- BETWEEN THE QUOTES IF IT ISN'T YOUR DEFAULT NOTEBOOK.
-- (EMPTY SENDS TO DEFAULT)
property EVnotebook : ""

-- IF TAGGING IS ON AND YOU'D LIKE TO CHANGE THE DEFAULT TAG,
-- TYPE IT BETWEEN THE QUOTES ("Email Message" IS DEFAULT)
property defaultTag : "Email Message"

-- SET THIS TO "OFF" IF YOU WANT TO PROCESS EMAILS
-- AS PLAINTEXT (USEFUL FOR NON-ENGLISH ENCODED EMAILS)
property HTML_Switch : "ON"


(*
======================================
// OTHER PROPERTIES
======================================
*)

property successCount : 0
property growl_Running : "false"
property myTitle : "Mail Item"
property theMessages : {}
property thisMessage : ""
property itemNum : "0"
property attNum : "0"
property errNum : "0"
property userTag : ""
property EVTag : {}
property multiHTML : ""
property theSourceItems : {}
property mySource : ""
property decode_Success : ""
property finalHTML : ""
property myHeaders : ""
property mysource_Paragraphs : {}
property base64_Raw : ""
property baseHTML : ""
property paraSource : ""
property cutSourceItems : ""
property allCC : ""

(*
======================================
// MAIN PROGRAM
======================================
*)


--RESET ITEMS
set successCount to "0"
set errNum to "0"
set AppleScript's text item delimiters to ""

try
    --CHECK FOR GROWL
    my Growl_Check()
   
    --SET UP ACTIVITIES
    my item_Check()
   
    --MESSAGES SELECTED?
    if theMessages is not {} then
       
        --GET FILE COUNT
        my item_Count(theMessages)
       
        --ANNOUNCE THE EXPORT OF ITEMS 
        my process_Items(itemNum, attNum)
       
        --PROCESS MAIL ITEMS FOR EXPORT
        my mail_Process(theMessages)
       
    else
        --NO MESSAGES SELECTED
        set successCount to -1
    end if
   
    --GROWL RESULTS
    my growl_Growler(growl_Running, successCount, errNum)
   
    --ERROR HANDLING
on error errText number errNum
    if growl_Running is true then
       
        --GROWL FAILURE FOR CANCEL
        if errNum is -128 then
            tell application "Growl"
                notify with name ¬
                    "Failure Notification" title ¬
                    "User Cancelled" description ¬
                    "Failed to export!" application name "Apple Mail to Evernote" icon of application "Mail"
               
            end tell
        else
           
            --GROWL FAILURE FOR ERROR
            tell application "Growl"
                notify with name ¬
                    "Failure Notification" title ¬
                    "Import Failure" description "Failed to export " & return & myTitle & ¬
                    ""  due to the following error: " & return & errText ¬
                    application name "
Apple Mail to Evernote" icon of application "Mail"
               
            end tell
        end if
       
        --NON-GROWL ERROR MSG. FOR ERROR
    else if growl_Running is false then
        display dialog "
Item Failed to Import: " & errNum & return & errText with icon 0
    end if
end try

(*
======================================
// PREPARATORY SUBROUTINES
=======================================
*)

--APP DETECT
on appIsRunning(appName)
    tell application "
System Events" to (name of processes) contains appName
end appIsRunning

--SET UP ACTIVITIES
on item_Check()
    set myPath to (path to home folder)
    tell application "
Mail"
        try
            set theMessages to selection
        end try
    end tell
end item_Check

--GET COUNT OF ITEMS AND ATTACHMENTS
on item_Count(theMessages)
    tell application "
Mail"
        set itemNum to count of theMessages
        set attNum to 0
        repeat with theMessage in theMessages
            set attNum to attNum + (count of mail attachment of theMessage)
        end repeat
    end tell
end item_Count

(*
======================================
// TAGGING AND NOTEBOOK SUBROUTINES
=======================================
*)

--TAGGING AND NOTEBOOK SELECTION DIALOG
on tagging_Dialog()
    try
        display dialog "
" & ¬
            "
Please Enter Your Tags Below:
(Multiple Tags Separated By Commas)" with title "Veritrope.com | Apple Mail to Evernote Export" default answer defaultTag buttons {"Create in Default Notebook", "Select Notebook from List", "Cancel"} default button "Create in Default Notebook" cancel button ¬
            "
Cancel" with icon path to resource "Evernote.icns" in bundle (path to application "Evernote")
        set dialogresult to the result
        set userInput to text returned of dialogresult
        set ButtonSel to button returned of dialogresult
        set theDelims to {"
,"}
    on error number -128
        set errNum to -128
    end try
   
    --ASSEMBLE LIST OF TAGS
    set theTags to my Tag_List(userInput, theDelims)
   
    --RESET, FINAL CHECK, AND FORMATTING OF TAGS
    set EVTag to {}
    set EVTag to my Tag_Check(theTags)
   
    --SELECT NOTEBOOK
    if ButtonSel is "
Select Notebook from List" then set EVnotebook to my Notebook_List()
end tagging_Dialog

--GET EVERNOTE'S DEFAULT NOTEBOOK
on default_Notebook()
    tell application "
Evernote"
        set get_defaultNotebook to every notebook whose default is true
        if EVnotebook is "
" then
            set EVnotebook to name of (item 1 of get_defaultNotebook) as text
        end if
    end tell
end default_Notebook

--TAG SELECTION SUBROUTINE
on Tag_List(userInput, theDelims)
    set oldDelims to AppleScript's text item delimiters
    set theList to {userInput}
    repeat with aDelim in theDelims
        set AppleScript's text item delimiters to aDelim
        set newList to {}
        repeat with anItem in theList
            set newList to newList & text items of anItem
        end repeat
        set theList to newList
    end repeat
    set AppleScript's text item delimiters to oldDelims
    return theList
end Tag_List

--CREATES TAGS IF THEY DON'T EXIST
on Tag_Check(theTags)
    tell application "
Evernote"
        set finalTags to {}
        repeat with theTag in theTags
           
            -- TRIM LEADING SPACE, IF ANY
            if (the character 1 of theTag is "
") then set theTag to text 2 thru end of theTag as text
           
            if (not (tag named theTag exists)) then
                try
                    set makeTag to make tag with properties {name:theTag}
                    set end of finalTags to makeTag
                end try
            else
                set end of finalTags to tag theTag
            end if
        end repeat
    end tell
    return finalTags
end Tag_Check

--EVERNOTE NOTEBOOK SELECTION SUBROUTINE
on Notebook_List()
    tell application "
Evernote"
        activate
        set listOfNotebooks to {} (*PREPARE TO GET EVERNOTE'S LIST OF NOTEBOOKS *)
        set EVNotebooks to every notebook (*GET THE NOTEBOOK LIST *)
        repeat with currentNotebook in EVNotebooks
            set currentNotebookName to (the name of currentNotebook)
            copy currentNotebookName to the end of listOfNotebooks
        end repeat
        set Folders_sorted to my simple_sort(listOfNotebooks) (*SORT THE LIST *)
        set SelNotebook to choose from list of Folders_sorted with title "
Select Evernote Notebook" with prompt ¬
            "
Current Evernote Notebooks" OK button name "OK" cancel button name "New Notebook" (*USER SELECTION FROM NOTEBOOK LIST *)
        if (SelNotebook is false) then (*CREATE NEW NOTEBOOK OPTION *)
            set userInput to ¬
                text returned of (display dialog "
Enter New Notebook Name:" default answer "")
            set EVnotebook to userInput
        else
            set EVnotebook to item 1 of SelNotebook
        end if
    end tell
end Notebook_List

(*
======================================
// UTILITY SUBROUTINES
=======================================
*)

-- EXTRACTION SUBROUTINE
on extractBetween(SearchText, startText, endText)
    set tid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to startText
    set endItems to text of text item -1 of SearchText
    set AppleScript's text item delimiters to endText
    set beginningToEnd to text of text item 1 of endItems
    set AppleScript's text item delimiters to tid
    return beginningToEnd
end extractBetween

--SORT SUBROUTINE
on simple_sort(my_list)
    set the index_list to {}
    set the sorted_list to {}
    repeat (the number of items in my_list) times
        set the low_item to "
"
        repeat with i from 1 to (number of items in my_list)
            if i is not in the index_list then
                set this_item to item i of my_list as text
                if the low_item is "
" then
                    set the low_item to this_item
                    set the low_item_index to i
                else if this_item comes before the low_item then
                    set the low_item to this_item
                    set the low_item_index to i
                end if
            end if
        end repeat
        set the end of sorted_list to the low_item
        set the end of the index_list to the low_item_index
    end repeat
    return the sorted_list
end simple_sort

--REMOVE EMBEDDED IMAGE REFERENCES
on stripCID(imgstpHTML)
    set theCommandString to "
echo " & quoted form of imgstpHTML & " | sed 's/"cid:.*"/""/'"
    set theResult to do shell script theCommandString
    return theResult
end stripCID

on trimStart(str)
    -- Thanks to HAS (http://applemods.sourceforge.net/mods/Data/String.php)
    local str, whiteSpace
    try
        set str to str as string
        set whiteSpace to {character id 10, return, space, tab}
        try
            repeat while str's first character is in whiteSpace
                set str to str's text 2 thru -1
            end repeat
            return str
        on error number -1728
            return "
"
        end try
    on error eMsg number eNum
        error "
Can't trimStart: " & eMsg number eNum
    end try
end trimStart


(*
======================================
// PROCESS MAIL ITEMS SUBROUTINE
=======================================
*)

on mail_Process(theMessages)
    --CHECK DEFAULT NOTEBOOK
    my default_Notebook()
    tell application "
Mail"
        try
            if tagging_Switch is "
ON" then my tagging_Dialog()
           
            repeat with thisMessage in theMessages
                try
                    --GET MESSAGE INFO
                    set myTitle to the subject of thisMessage
                    set myContent to the content of thisMessage
                    set mySource to the source of thisMessage
                    set ReplyAddr to the reply to of thisMessage
                    set EmailDate to the date received of thisMessage
                    set allRecipients to (every to recipient of item 1 of thisMessage)
                   
                    --TEST FOR CC RECIPIENTS
                    set allCCs to (every cc recipient of item 1 of thisMessage)
                   
                    --ASSEMBLE ALL TO: RECIPENTS FOR HEADER
                    set toRecipients to "
"
                    repeat with allRecipient in allRecipients
                        set toName to "
"
                        set toName to (name of allRecipient)
                        if toName is missing value then set toName to "
"
                        set toEmail to (address of allRecipient)
                        set toCombined to toName & space & "
(" & toEmail & ")<br/>"
                        set toRecipients to (toRecipients & toCombined as string)
                    end repeat
                   
                    --ASSEMBLE ALL CC: RECIPENTS FOR HEADER
                    set ccRecipients to "
"
                   
                    if allCCs is not {} then
                        repeat with allCC in allCCs
                            set ccName to "
"
                            set ccName to (name of allCC)
                            if ccName is missing value then set toName to "
"
                            set ccEmail to (address of allCC)
                            set ccCombined to ccName & space & "
(" & ccEmail & ")<br/>"
                            set ccRecipients to (ccRecipients & ccCombined as string)
                        end repeat
                    end if
                    --CREATE MAIL MESSAGE URL
                    set theRecipient to "
"
                    set ex to "
"
                    set MsgLink to "
"
                    try
                        set theRecipient to "
"
                        set theRecipient to the address of to recipient 1 of thisMessage
                        set MsgLink to "
message://%3c" & thisMessage's message id & "%3e"
                        if theRecipient is not "
" then set ex to my extractBetween(ReplyAddr, "<", ">") -- extract the Address
                    end try
                   
                    --HTML EMAIL FUNCTIONS
                    set theBoundary to my extractBetween(mySource, "
boundary="", """ & linefeed)
                    set theMessageStart to (return & "
--" & theBoundary)
                    set theMessageEnd to ("--" & theBoundary & return & "Content-Type:")
                    set paraSource to paragraphs of mySource
                    set myHeaderlines to paragraphs of (all headers of thisMessage as rich text)
                   
                   
                    --GET CONTENT TYPE
                    repeat with myHeaderline in myHeaderlines
                        if myHeaderline starts with "Content-Type: " then
                            set myHeaders to my extractBetween(myHeaderline, "Content-Type: ", ";")
                        end if
                    end repeat
                    set cutSource to my stripHeader(paraSource, myHeaderlines)
                    set evHTML to cutSource
                end try
               
                --MAKE HEADER TEMPLATE
                set the_Template to "
<table border="
1" width="100%" cellspacing="0" cellpadding="2">
<tbody>

<tr BGCOLOR="
#ffffff">
<td valign="
top"><font color="#797979"><strong>From: </strong>  </td>
<td valign="
top" ><a href="mailto:" & ex & "">" & ex & "</a></td>
</tr>

<tr BGCOLOR="
#ffffff">
<td valign="
top"><font color="#797979"><strong>Subject: </strong>  </td>
<td valign="
top" ><strong>" & myTitle & "</strong></td>
</tr>

<tr BGCOLOR="
#ffffff">
<td valign="
top"><font color="#797979"><strong>Date / Time:  </strong></td>
<td valign="
top">" & EmailDate & "</td>
</tr>

<tr BGCOLOR="
#ffffff">
<td valign="
top"><font color="#797979"><strong>To:</strong></td>
<td valign="
top">" & toRecipients & "</td>
</tr>

<tr BGCOLOR="
#ffffff">
<td valign="
top"><font color="#797979"><strong>CC:</strong></td>
<td valign="
top">" & ccRecipients & "</td>
</tr>
</tbody>
</table>
<hr />"

               
                --SEND ITEM TO EVERNOTE SUBROUTINE
                my make_Evernote(myTitle, EVTag, EmailDate, MsgLink, myContent, mySource, theBoundary, theMessageStart, theMessageEnd, myHeaders, thisMessage, evHTML, EVnotebook, the_Template)
               
            end repeat
        end try
    end tell
end mail_Process


(*
======================================
// MAKE ITEM IN EVERNOTE SUBROUTINE
=======================================
*)


on make_Evernote(myTitle, EVTag, EmailDate, MsgLink, myContent, mySource, theBoundary, theMessageStart, theMessageEnd, myHeaders, thisMessage, evHTML, EVnotebook, the_Template)
   
    tell application "Evernote"
        try
           
           
           
            --IS IT A TEXT EMAIL?  
            if myHeaders contains "text/plain" then
                set n to create note with html the_Template title myTitle notebook EVnotebook
                if EVTag is not {} then assign EVTag to n
                tell n to append text myContent
                set creation date of n to EmailDate
                set source URL of n to MsgLink
               
                -- IF HTML PROCESSING IS TURNED TO "OFF", PROCESS
                -- AS PLAINTEXT (USEFUL FOR NON-ENGLISH ENCODED EMAILS)
            else if HTML_Switch is "OFF" then
                set n to create note with html the_Template title myTitle notebook EVnotebook
                if EVTag is not {} then assign EVTag to n
                tell n to append text myContent
                set creation date of n to EmailDate
                set source URL of n to MsgLink
                --IS IT MULTIPART ALTERNATIVE?
            else if myHeaders contains "multipart/alternative" then
               
                --CHECK FOR BASE64
                set base64Detect to my base64_Check(mySource)
               
                --IF MESSAGE IS BASE64 ENCODED...
                if base64Detect is true then
                    set multiHTML to my extractBetween(mySource, "Content-Transfer-Encoding: base64", "--" & theBoundary)
                   
                    --STRIP OUT CONTENT-DISPOSITION, IF NECESSARY
                    if multiHTML contains "Content-Disposition: inline" then set multiHTML to my extractBetween(multiHTML, "Content-Disposition: inline", theBoundary)
                    if multiHTML contains "Content-Transfer-Encoding: 7bit" then set multiHTML to my extractBetween(multiHTML, "Content-Transfer-Encoding: 7bit", theBoundary)
                   
                    --TRIM LEADING LINEFEEDS
                    set baseHTML to my trimStart(multiHTML)
                   
                    --DECODE BASE64
                    set baseHTML to do shell script "echo " & (quoted form of baseHTML) & "| base64 -D"
                   
                    --MAKE NOTE IN EVERNOTE
                    set n to create note with html the_Template title myTitle notebook EVnotebook
                    if EVTag is not {} then assign EVTag to n
                    tell n to append html baseHTML
                    set creation date of n to EmailDate
                    set source URL of n to MsgLink
                else
                   
                    --IF MESSAGE IS NOT BASE64 ENCODED...
                    set finalHTML to my htmlFix(mySource, theBoundary, myContent)
                    if decode_Success is true then
                       
                        --MAKE NOTE IN EVERNOTE
                        set n to create note with html the_Template title myTitle notebook EVnotebook
                        if EVTag is not {} then assign EVTag to n
                        tell n to append html finalHTML
                        set creation date of n to EmailDate
                        set source URL of n to MsgLink
                    else
                       
                        --MAKE NOTE IN EVERNOTE
                        set n to create note with html the_Template title myTitle notebook EVnotebook
                        if EVTag is not {} then assign EVTag to n
                        tell n to append text myContent
                        set creation date of n to EmailDate
                        set source URL of n to MsgLink
                    end if
                end if
               
                --IS IT MULTIPART MIXED?
            else if myHeaders contains "multipart" then
                if mySource contains "Content-Type: text/html" then
                   
                    --CHECK FOR BASE64
                    set base64Detect to my base64_Check(mySource)
                   
                    --IF MESSAGE IS BASE64 ENCODED...
                    if base64Detect is true then
                        set baseHTML to my base64_Decode(mySource)
                       
                        --MAKE NOTE IN EVERNOTE
                        set n to create note with html the_Template title myTitle notebook EVnotebook
                        if EVTag is not {} then assign EVTag to n
                        tell n to append html baseHTML
                        set creation date of n to EmailDate
                        set source URL of n to MsgLink
                       
                        --IF MESSAGE IS NOT BASE64 ENCODED...
                    else if base64Detect is false then
                        set finalHTML to my htmlFix(mySource, theBoundary, myContent)
                        if decode_Success is true then
                           
                            --MAKE NOTE IN EVERNOTE
                            set n to create note with html the_Template title myTitle notebook EVnotebook
                            if EVTag is not {} then assign EVTag to n
                            tell n to append html finalHTML
                            set creation date of n to EmailDate
                            set source URL of n to MsgLink
                        else
                           
                            --MAKE NOTE IN EVERNOTE
                            set n to create note with html the_Template title myTitle notebook EVnotebook
                            if EVTag is not {} then assign EVTag to n
                            tell n to append text myContent
                            set creation date of n to EmailDate
                            set source URL of n to MsgLink
                        end if
                    end if
                   
                else if mySource contains "text/plain" then
                   
                    --MAKE NOTE IN EVERNOTE
                    set n to create note with html the_Template title myTitle notebook EVnotebook
                    if EVTag is not {} then assign EVTag to n
                    tell n to append text myContent
                    set creation date of n to EmailDate
                    set source URL of n to MsgLink
                   
                end if -- MULTIPART MIXED
               
                --OTHER TYPES OF HTML-ENCODING 
            else
               
                --CHECK FOR BASE64
                set base64Detect to my base64_Check(mySource)
               
                --IF MESSAGE IS BASE64 ENCODED...
                if base64Detect is true then
                    set finalHTML to my base64_Decode(mySource)
                else
                    set multiHTML to my extractBetween(evHTML, "</head>", "</html>")
                    set finalHTML to my htmlFix(multiHTML, theBoundary, myContent) as text
                end if
               
                --MAKE NOTE IN EVERNOTE
                set n to create note with html the_Template title myTitle notebook EVnotebook
                if EVTag is not {} then assign EVTag to n
                tell n to append html finalHTML
                set creation date of n to EmailDate
                set source URL of n to MsgLink
               
                --END OF MESSAGE PROCESSING
            end if
           
            --START OF ATTACHMENT PROCESSING
            tell application "Mail"
                --IF ATTACHMENTS PRESENT, RUN ATTACHMENT SUBROUTINE
                if thisMessage's mail attachments is not {} then my attachment_process(thisMessage, n)
            end tell
            --ITEM HAS FINISHED! COUNT IT AS A SUCCESS!
            set successCount to successCount + 1
        end try
    end tell
    log "successCount: " & successCount
end make_Evernote



(*
======================================
// ATTACHMENT SUBROUTINES
=======================================
*)


--FOLDER EXISTS?
on f_exists(ExportFolder)
    try
        set myPath to (path to home folder)
        get ExportFolder as alias
        set SaveLoc to ExportFolder
    on error
        tell application "Finder" to make new folder with properties {name:"Temp Export From Mail"}
    end try
end f_exists

--ATTACHMENT PROCESSING
on attachment_process(thisMessage, n)
    tell application "Mail"
       
        --MAKE SURE TEXT ITEM DELIMITERS ARE DEFAULT
        set AppleScript's text item delimiters to ""
       
        --TEMP FILES PROCESSED ON THE DESKTOP
        set ExportFolder to ((path to desktop folder) & "Temp Export From Mail:") as string
        set SaveLoc to my f_exists(ExportFolder)
       
        --PROCESS THE ATTACHMENTS
        set theAttachments to thisMessage's mail attachments
        set attCount to 0
        repeat with theAttachment in theAttachments
            set theFileName to ExportFolder & theAttachment's name
            try
                save theAttachment in file theFileName
            end try
            tell application "Evernote"
                tell n to append attachment file theFileName
            end tell
           
            --SILENT DELETE OF TEMP FILE
            set trash_Folder to path to trash folder from user domain
            do shell script "mv " & quoted form of POSIX path of theFileName & space & quoted form of POSIX path of trash_Folder
           
        end repeat
       
        --SILENT DELETE OF TEMP FOLDER
        set success to my trashfolder(SaveLoc)
       
    end tell
end attachment_process

--SILENT DELETE OF TEMP FOLDER (THANKS MARTIN MICHEL!)
on trashfolder(SaveLoc)
    try
        set trashfolderpath to ((path to trash) as Unicode text)
        set srcfolderinfo to info for (SaveLoc as alias)
        set srcfoldername to name of srcfolderinfo
        set SaveLoc to quoted form of POSIX path of SaveLoc
        set counter to 0
        repeat
            if counter is equal to 0 then
                set destfolderpath to trashfolderpath & srcfoldername & ":"
            else
                set destfolderpath to trashfolderpath & srcfoldername & " " & counter & ":"
            end if
            try
                set destfolderalias to destfolderpath as alias
            on error
                exit repeat
            end try
            set counter to counter + 1
        end repeat
        set destfolderpath to quoted form of POSIX path of destfolderpath
        set command to "ditto " & SaveLoc & space & destfolderpath
        do shell script command
        -- this won't be executed if the ditto command errors
        set command to "rm -r " & SaveLoc
        do shell script command
        return true
    on error
        return false
    end try
end trashfolder

(*
======================================
// HTML CLEANUP SUBROUTINES
=======================================
*)


--HEADER STRIP (THANKS DOMINIK!)
on stripHeader(paraSource, myHeaderlines)
   
    -- FIND THE LAST NON-EMPTY HEADER LINE
    set lastheaderline to ""
    set n to count (myHeaderlines)
    repeat while (lastheaderline = "")
        set lastheaderline to item n of myHeaderlines
        set n to n - 1
    end repeat
   
    -- COMPARE HEADER TO SOURCE
    set sourcelength to (count paraSource)
    repeat with n from 1 to sourcelength
        if (item n of paraSource is equal to "") then exit repeat
    end repeat
   
    -- STRIP OUT THE HEADERS
    set cutSourceItems to (items (n + 1) thru sourcelength of paraSource)
    set oldDelims to AppleScript's text item delimiters
    set AppleScript's text item delimiters to return
    set cutSource to (cutSourceItems as text)
    set AppleScript's text item delimiters to oldDelims
   
    return cutSource
   
end stripHeader

--BASE64 CHECK
on base64_Check(mySource)
    set base64Detect to false
    set base64MsgStr to "Content-Transfer-Encoding: base64"
    set base64ContentType to "Content-Type: text"
    set base64MsgOffset to offset of base64MsgStr in mySource
    set base64ContentOffset to offset of base64ContentType in mySource
    set base64Offset to base64MsgOffset - base64ContentOffset as real
    set theOffset to base64Offset as number
    if theOffset is not greater than or equal to 50 then
        if theOffset is greater than -50 then set base64Detect to true
    end if
    return base64Detect
end base64_Check

--BASE64 DECODE
on base64_Decode(mySource)
    --USE TID TO QUICKLY ISOLATE BASE64 DATA
    set oldDelim to AppleScript's text item delimiters
    set AppleScript's text item delimiters to "Content-Type: text/html"
    set base64_Raw to second text item of mySource
    set AppleScript's text item delimiters to linefeed & linefeed
    set base64_Raw to second text item of base64_Raw
    set AppleScript's text item delimiters to "-----"
    set multiHTML to first text item of base64_Raw
    set AppleScript's text item delimiters to oldDelim
   
    --DECODE BASE64
    set baseHTML to do shell script "echo " & (quoted form of multiHTML) & "| base64 -D"
   
    return baseHTML
end base64_Decode


--HTML FIX
on htmlFix(multiHTML, theBoundary, myContent)
   
    set oldDelims to AppleScript's text item delimiters
    --set multiHTML to evHTML as string
   
    --TEST FOR / STRIP OUT HEADER
    set paraSource to paragraphs of multiHTML
    if item 1 of paraSource contains "Received:" then
        set myHeaderlines to (item 1 of paraSource)
        set multiHTML to my stripHeader(paraSource, myHeaderlines)
    end if
   
    --TRIM ENDING
    if multiHTML contains "</html>" then
        set multiHTML to my extractBetween(multiHTML, "Content-Type: text/html", "</html>")
    else
        set multiHTML to my extractBetween(multiHTML, "Content-Type: text/html", "--" & theBoundary)
    end if
    set paraSource to paragraphs of multiHTML
   
    --TEST FOR / STRIP OUT LEADING SEMI-COLON
    if item 1 of paraSource contains ";" then
        set myHeaderlines to (item 1 of paraSource)
        set multiHTML to my stripHeader(paraSource, myHeaderlines)
        set paraSource to paragraphs of multiHTML
    end if
   
    --TEST FOR EMPTY LINE / CLEAN SUBSEQUENT ENCODING INFO, IF NECESSARY
    if item 1 of paraSource is "" then
        --TEST FOR / STRIP OUT CONTENT-TRANSFER-ENCODING
        if item 2 of paraSource contains "Content-Transfer-Encoding" then
            set myHeaderlines to (item 2 of paraSource)
            set multiHTML to my stripHeader(paraSource, myHeaderlines)
            set paraSource to paragraphs of multiHTML
        end if
        --TEST FOR / STRIP OUT CHARSET
        if item 2 of paraSource contains "charset" then
            set myHeaderlines to (item 2 of paraSource)
            set multiHTML to my stripHeader(paraSource, myHeaderlines)
            set paraSource to paragraphs of multiHTML
        end if
    end if
   
    --TEST FOR / STRIP OUT CONTENT-TRANSFER-ENCODING
    if item 1 of paraSource contains "Content-Transfer-Encoding" then
        set myHeaderlines to (item 1 of paraSource)
        set multiHTML to my stripHeader(paraSource, myHeaderlines)
        set paraSource to paragraphs of multiHTML
    end if
   
    --TEST FOR / STRIP OUT CHARSET
    if item 1 of paraSource contains "charset" then
        set myHeaderlines to (item 1 of paraSource)
        set multiHTML to my stripHeader(paraSource, myHeaderlines)
        set paraSource to paragraphs of multiHTML
    end if
   
    --CLEAN CONTENT
    set AppleScript's text item delimiters to theBoundary
    set theSourceItems to text items of multiHTML
    set AppleScript's text item delimiters to ""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "&#" & "37;" as string
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "="
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "%"
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%""
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "
=""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%" & (ASCII character 13)
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to ""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%%"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "%"
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%" & (ASCII character 10)
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to ""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%0A"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to ""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%09"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to ""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%C2%A0"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "&nbsp;"
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "%20"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to " "
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to (ASCII character 10)
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to ""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "="
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "&#" & "61;" as string
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "$"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "&#" & "36;" as string
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to "'"
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "&apos;"
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to """
    set theSourceItems to text items of theEncoded
    set AppleScript's text item delimiters to "
\\""
    set theEncoded to theSourceItems as text
   
    set AppleScript's text item delimiters to oldDelims
   
    set trimHTML to my extractBetween(theEncoded, "</head>", "</html>")
   
    set theHTML to myContent
   
    try
        set decode_Success to false
       
        --UTF-8 CONV
        set NewEncodedText to do shell script "echo " & quoted form of trimHTML & " | iconv -t UTF-8 "
        set the_UTF8Text to quoted form of NewEncodedText
       
        --URL DECODE CONVERSION
        set theDecodeScript to "php -r "echo utf8_encode(urldecode(utf8_decode(" & the_UTF8Text & ")));"" as text
        set theDecoded to do shell script theDecodeScript
       
        --FIX FOR APOSTROPHE / PERCENT / EQUALS ISSUES
        set AppleScript's text item delimiters to "&apos;"
        set theSourceItems to text items of theDecoded
        set AppleScript's text item delimiters to "'"
        set theDecoded to theSourceItems as text
       
        set AppleScript's text item delimiters to "&#" & "37;" as string
        set theSourceItems to text items of theDecoded
        set AppleScript's text item delimiters to "%"
        set theDecoded to theSourceItems as text
       
        set AppleScript's text item delimiters to "&#" & "61;" as string
        set theSourceItems to text items of theDecoded
        set AppleScript's text item delimiters to "="
        set theDecoded to theSourceItems as text
       
        --RETURN THE VALUE
        set finalHTML to theDecoded
        set decode_Success to true
        return finalHTML
    end try
   
end htmlFix

(*
======================================
// GROWL SUBROUTINES
=======================================
*)


--CHECK FOR GROWL
on Growl_Check()
    if appIsRunning("Growl") then
        set growl_Running to true
        tell application "Growl"
            set allNotificationsFiles to {"Import To Evernote", "Success Notification", "Failure Notification"}
            set enabledNotificationsFiles to {"Import To Evernote", "Success Notification", "Failure Notification"}
            register as application ¬
                "Apple Mail to Evernote" all notifications allNotificationsFiles ¬
                default notifications enabledNotificationsFiles ¬
                icon of application "Mail"
        end tell
    end if
end Growl_Check

--ANNOUNCE THE COUNT OF TOTAL ITEMS TO EXPORT
on process_Items(itemNum, attNum)
    set attPlural to ""
    if attNum = 0 then
        set attNum to "No"
    else if attNum > 1 then
        set attPlural to "s"
    end if
    tell application "Finder"
        if growl_Running is true then
            set Plural_Test to (itemNum) as number
            if Plural_Test is greater than 1 then
                tell application "Growl"
                    notify with name ¬
                        "Import To Evernote" title ¬
                        "Import To Evernote Started" description "Now Processing " & itemNum & " Items with " & attNum & ¬
                        " attachment" & attPlural & "." application name ¬
                        "Apple Mail to Evernote" icon of application "Mail"
                end tell
            else
                tell application "Growl"
                    notify with name ¬
                        "Import To Evernote" title ¬
                        "Import To Evernote Started" description "Now Processing " & itemNum & " Item With " & attNum & ¬
                        " Attachment" & attPlural & "." application name ¬
                        "Apple Mail to Evernote" icon of application "Mail"
                   
                end tell
            end if
        end if
    end tell --FINDER
end process_Items

--GROWL RESULTS
on growl_Growler(growl_Running, successCount, errNum)
    if growl_Running is true then
        tell application "Growl"
            -- GROWL FAILURE FOR CANCEL
            if errNum is -128 then tell application "Growl" to notify with name ¬
                "Failure Notification" title ¬
                "User Cancelled" description ¬
                "Failed to export!" application name "Apple Mail to Evernote" icon of application "Mail"
           
           
            -- GROWL FAILURE
            set Plural_Test to (successCount) as number
            if Plural_Test is -1 then
                notify with name ¬
                    "Failure Notification" title ¬
                    "Import Failure" description "No Items Selected In Apple Mail!" application name "Apple Mail to Evernote" icon of application "Mail"
            else if Plural_Test is 0 then
                notify with name ¬
                    "Failure Notification" title ¬
                    "Import Failure" description "No Items Exported From Mail!" application name "Apple Mail to Evernote" icon of application "Mail"
               
               
                -- GROWL SUCCESS
            else if Plural_Test is equal to 1 then
                notify with name ¬
                    "Success Notification" title ¬
                    "Import Success" description "Successfully Exported " & itemNum & ¬
                    " Item to the " & EVnotebook & " Notebook in Evernote" application name "Apple Mail to Evernote" icon of application "Mail"
               
               
                -- GROWL SUCCESS
            else if Plural_Test is greater than 1 then
                notify with name ¬
                    "Success Notification" title ¬
                    "Import Success" description "Successfully Exported " & itemNum & ¬
                    " Items to the " & EVnotebook & " Notebook in Evernote" application name "Apple Mail to Evernote" icon of application "Mail"
               
            end if
        end tell
        set itemNum to "0"
    end if
end growl_Growler

99 Responses to “Apple Mail to Evernote”

  1. Kel May 10, 2012 at 9:54 pm #

    hey thanks for the script donation made 🙂
    cheers.

  2. Mark Arana June 29, 2012 at 8:12 pm #

    Hey there, this is a fantastic script!

    Just as an FYI, I took this script and created an Automater Service (only executing an AppleScript). So now it lives in the Services pane whenever I right click a piece of mail. Seems to be working well so far.

    I’ve also added a keyboard shortcut for it (through the Keyboard PrefsPane). Yes, I’m too lazy to go up to the scripts menu 😉

    • Justin Lancy June 29, 2012 at 9:10 pm #

      Thanks for the kind words (and for the donation), Mark!

      I’ve heard of others plugging the script into a service – thinking about putting together a “deluxe package” that contains the AppleScript, an Automator Service, and maybe even a Mail.app rule version for people.

      Anyone out there interested in something like that?

  3. polocanada July 5, 2012 at 12:35 am #

    I am getting Syntax Error when trying to save this script:
    Expected “given”, “into”, “with”, “without”, other parameter name, etc. but found “””.

    The error seems to be in this section:
    ———–
    — GROWL FAILURE FOR CANCEL
    if errNum is -128 then
    tell application “Growl”
    notify with name ¬
    “Failure Notification” title ¬
    “User Cancelled” description ¬
    “Failed to export!” application name “Mail to Evernote”
    end tell
    else
    —————–

    • Sander Datema March 6, 2013 at 9:30 am #

      I get the same error, also for most of the Growl sections.
      ML 10.8 and EN 5.0.6

      • BJ Wade April 24, 2013 at 8:36 pm #

        Unable to save script… Growl 2.0.1 and EV 5.0.7. Any remedies? Would love to use this script! Thanks in advance…

        • Justin Lancy April 25, 2013 at 9:56 am #

          There seems to be a bug with Evernote not allowing the script to save if it is not running. Try running Evernote first and see if that fixes your problem!

          • BJ Wade April 25, 2013 at 10:27 am #

            Thank you for such a prompt reply… I am still unable to save it with EV open receiving, the document could not be saved as… “you can duplicate the document or discard your changes to close it.” Again, thanks for your time!

      • Frank Jing May 27, 2013 at 10:00 pm #

        Same problem here. But I got it working by saving it to a temporary place, then drop it to the script folder.

        • Bill June 6, 2013 at 1:11 am #

          Great workaround, now I’m off to upgrade the script to a keystroke.

  4. Barry July 10, 2012 at 4:19 am #

    Would it be possible to convert this script to work with Sparrow?

    • Justin Lancy July 11, 2012 at 10:13 am #

      Hi Barry – my recollection is that Sparrow isn’t very scriptable, but I’ll look into it… I think a lot of people would like that one!

  5. pandaren August 9, 2012 at 2:31 am #

    hi again. Just wanna let you know the reason why ur script is not working in mountain Lion, is because most evernote users are using sandbox version of evernote (from app store). Great script but in order to overcome it you may have to talk to evernote online API….sorry to tell.

    • Justin Lancy August 9, 2012 at 8:10 pm #

      Good to hear from you!

      I’m seeing some issues with 3.3 — both the App Store and directly downloaded versions. I’ve reached out to Evernote to ask if it’s a known issue and, since it affects a number of the AppleScripts here, I will update everyone on the main page and on the Veritrope Twitter feed if I get an update.

      • Simon January 14, 2013 at 12:22 am #

        Did you ever get a response from Evernote? I’m using the latest version of evernote and getting a growl message saying import failed.

        • Justin Lancy January 15, 2013 at 4:01 am #

          Just made some quick tweaks — try the latest version of the script and let me know if it helps!

          • fort February 11, 2013 at 7:22 am #

            Hi Justin,

            I’m getting an error when I run the script while in Mail:

            The action “Run AppleScript” encountered an error.

            Check the actionʼs properties and try running the workflow again.

            and when I run it in Automator it stops on line 85 with the syntax error:

            Expected “end” but found “property”.

            Am I doing something wrong or are there still problems with sandboxing on Mountain Lion?

            Thanks!

            fort

          • Justin Lancy February 13, 2013 at 8:22 pm #

            Running a script in Automator or as application is always a different thing… Usually requires certain code changes for it to run successfully.

            I’m not sure why you would be getting that error running directly as an AppleScript, though… If you’re still having issues, fill out a bug report using the link on this page and give me some more details about your system and the errors themselves.

  6. Addison October 16, 2012 at 11:22 am #

    how do I edit out the Growl portions. My knowledge of scripts is terrible. sorry

  7. Spendicus January 26, 2013 at 8:45 pm #

    Nice job on the script! I’d like to echo the previous request by “Addison”. Any chance you could simplify this awesome script by dropping the Growl requirement?

    • Justin Lancy February 13, 2013 at 8:12 pm #

      Thanks for the kind compliment!

      As far as GROWL, I’m thinking through how I want to handle this in the future… Right now, it seems like the best way to do notifications for people running a variety of operating systems (e.g., Pre-10.8 Systems). I also realize that many people don’t want or need notifications. In the future, I may release a “no notifications version”, though I am reluctant to do so as it means I have to maintain two different code pages.

      The nice thing about AppleScript is, with a little bit of trial and error, you can edit out the bits that you don’t like and further tailor the script to your exact personal specifications. My hope is to add some additional tools/forums to help people do this soon!

  8. Rob Lewis March 2, 2013 at 10:57 pm #

    Hi. Looking at the version history, I see “eliminated MailTags support”. Shucks; I’m sure you must have a good reason, but I use MailTags a lot and it would be great if MailTags could be converted to Evernote tags (even better: Evernote supports OpenMeta, but oh well).

    • Justin Lancy March 3, 2013 at 12:52 am #

      Hi Rob,

      You know — I took it out because I try to keep the code as simple (and readable by humans) as possible. When I added support for MailTags I thought there would be a solid response for the feature, but I didn’t hear a peep from anyone! Same for when I eliminated it.

      If enough people want it, maybe I’ll add it back… and I’ll count your comment a vote for moving in that direction!

      😀

      • Sander Datema March 6, 2013 at 9:27 am #

        In that case I’d like to vote for MailTags as well. 🙂

        • Jose Alonso September 23, 2013 at 10:49 am #

          Another vote for MailTags support. As the code was already there, it might be not that difficult to add it?
          If you could tweak it to add support for reminder (now that Evernote has it) that would be awesome and make a nice GTD system.

          • Justin Lancy September 24, 2013 at 6:00 am #

            Here’s a link to a *very* untested version.

          • Jose Alonso September 24, 2013 at 6:54 am #

            Justin, I downloaded it. All I could see when I tried to open the .scpt file to see the code was garbage text. I moved the file to the scripts folder anyway but didn’t work.
            Is that the right file? May it be corrupted or something?

          • Justin Lancy September 24, 2013 at 7:04 am #

            It helps when I turn the debugging off! 😛

            Try again…

          • Jose Alonso September 24, 2013 at 7:24 am #

            Works now, thanks. Will try to test it over the next few days.

      • Rob Lewis March 6, 2013 at 11:35 am #

        Thanks, I appreciate it. Suggestion: as long as this debate is buried in the comments, not many people will see it. Why not ask for opinions in your main post?

        • Justin Lancy March 7, 2013 at 7:04 am #

          Good point, Rob! I’ll add it to the main post and mention it in a post I’m planning to do for the main page.

  9. Sander Datema March 6, 2013 at 12:40 pm #

    There are a few mails that will give an error in Evernote (error on line 9 at column 303: PCDATA invalid Char value 27). Somehow the decoding of base64 goes wrong.

    I can mail you the source of one of the mails if you like (where shall I mail it to?).

    • Justin Lancy March 7, 2013 at 7:02 am #

      Hi Sander — You should be able to attach the file using the Bug Reporter but, if you have any trouble, let me know and I’ll reach out to you via email!

  10. Jonathan March 14, 2013 at 2:25 pm #

    I can’t get the script to compile on Mountain Lion. I have Growl, and also added Evernote to the library but I get
    “Syntax Error – Expected class name but found identifier”
    on this line (“notebook” is highlighted):

    set get_defaultNotebook to every notebook whose default is true

    If I comment that line out, I get:
    “Syntax Error – Expected “,” but found property or key form.”
    on this line (“named” is highlighted):

    if (not (tag named theTag exists)) then

    Any ideas?

    • Justin Lancy March 22, 2013 at 6:37 am #

      Hi Jonathan,

      I’m seeing reports of a couple of new Evernote / AppleScript errors, one of which involves scripts not compiling if Evernote isn’t running.

      You may want to double-check that Evernote is open and try again to see if that gets you going. If not, you can use the Bug Report button on this page to send me some more details.

      • Jonathan March 22, 2013 at 8:18 am #

        That must be it, it works now.

        I am having some issues, though, with it selecting the right message. If I have it bound to a key in Mail Act-On that also involves moving the message, then this script seems to run asynchronously – i.e. the message gets moved before this script grabs the right message. That typically means I get the next message in the folder.

        Any ideas on how to avoid that?

  11. Jose June 7, 2013 at 11:16 am #

    Tagging behavior.

    Is this behavior expected?
    I have a tag named “testing”
    When I run the script I type “test” in the tag field. I expected that it would find the tag named testing (like emailing into evernote works) however it creates a new tag named “test”.

    Is it possible to have tags work the same as when you forward email to evernote?

    thanks, this is an awesome script, I just need this to have my perfect Mail-Evernote workflow

    • Justin Lancy June 8, 2013 at 1:14 am #

      Hi Jose,

      I didn’t realize that Email-to-Evernote does an “auto-complete” on tags… nice find! 🙂

      The AppleScript works differently: It looks through your list of tags and creates one based on what you typed in if it doesn’t already exist. I suppose someone could write some “fuzzy matching” code that loads a full list of tags and select based on a match criteria (e.g., Are there any tags which start with the entered text?)

      If you play around with that approach, let us know how it works out for you!

      • Jose June 23, 2013 at 11:19 pm #

        Hi, my coding skills are extremely rusty, but I’ll see if I can whip something out.

        Thanks for the reply

        • Chris July 17, 2013 at 9:00 am #

          I just adopted the mail-to-evernote workflow only to discover the lack of auto-complete for tags. Did anyone ever develop a solution for this? It would be a real time-saver on top of an already strong solution. Thanks!

  12. Dean June 13, 2013 at 11:54 am #

    Hey there… long time no talk. Hope all is well. Did you happen to look into the email itself being able to send to evernote?

    Meaning, I hit the FastScript “Mail to Evernote” it sends the email to Evernote but also attaches the actual email so that I can refer back to it quickly in Mail.

    This, coupled with the new Reminders Feature in Evernote would complete my workflow.

    Thanks again.

    • Justin Lancy June 23, 2013 at 1:20 am #

      Haven’t made any changes to the main script (other than a MailTags version which I’m testing), but an “Add Email to Note” switch is on my list of possible future features!

  13. Russell June 22, 2013 at 7:00 pm #

    Hi,
    First, thank you for dedicating so much to this.

    2nd… I’ve compiled, saved the script, but nothing seems to happen when I run it.

    Do I need to fill in certain properties with values first?

    Or better yet, anyway to get Script Editor to show events? (I think because you’ve got most of your code in handlers that the answer is no, but I’m curious if there’s a way)

    • Justin Lancy June 23, 2013 at 1:04 am #

      Hi Russell,

      You don’t need to fill in any properties, just select a message (or messages) in Mail.app and trigger the script.

      If you want to see events in AppleScript Editor, try selecting “Show Event Log” in the View menu (or pressing ⌘2 to toggle that window).

      • Russell June 23, 2013 at 11:21 am #

        Right, I was viewing the events, but just getting “”.

        (Isn’t that what happens when code is in handlers, you lose some of the “verbosity” in Event Viewer?)

        Anyway, I’m not getting anything down there. (Using 10.8.4, Mail 6.5)

  14. Paul Maher July 16, 2013 at 7:09 am #

    Hello,

    This script works great but I am having an issue. If I run the script in script editor, everything works great and emails are sent to my default Notebook

    If I run the the script using a shortcut (FastScripts) a new Notebook is created (called work) and the message is stored there instead of my default Notebook. Any ideas?

    Thanks,

    Paul

  15. Bill August 2, 2013 at 8:32 pm #

    Nice script, thanks for putting it together.

    There is a bug in the script in the stripHeader function on this line:

        set cutSourceItems to (items (n + 1) thru sourcelength of paraSource)

    because n+1 can be greater than sourcelength and was for me in my first test email oddly enough. The fix I put in that seemed to work for me was:

        if (n + 1) is less than sourcelength then
            set cutSourceItems to (items (n + 1) thru sourcelength of paraSource)
        else
            set cutSourceItems to paraSource
        end if

    Best,
    ~>Bill

  16. Rowalth August 20, 2013 at 8:32 am #

    Great work, it is awesome.

    How is it possible to use another text encoding. I have a lot of umlaut like ö, ä, ü in my language?

    • Justin Lancy September 15, 2013 at 2:32 pm #

      It’s an open issue… hope to eventually fix this!

    • Eduardo January 20, 2014 at 10:26 am #

      Rowalth,
      this works better for me.
      in line:

      set theDecodeScript to “php -r ”echo urldecode(” & the_UTF8Text & “);”" as text

      change for:

      set theDecodeScript to "php -r "echo utf8_encode(urldecode(utf8_decode(" & the_UTF8Text & ")));"" as text
  17. Justin Lancy September 24, 2013 at 5:56 am #

    To Everyone Interested In a MailTags Version of This Script:

    For those hearty souls brave enough to test something that I haven’t tested in months (i.e., since installing 10.9 on my computer), here is a rough beta that you can download.

    Hope to revisit this once the Code Library is moved to it’s new home!

  18. David Petree October 15, 2013 at 10:51 am #

    Justin,
    Just installed your new beta. I have the Mailtags beta, but I had to uninstall it because it kept locking up my Mac Mail. Hope they get a more stable version out soon.

    As for your script to send to evernote, it worked perfect. It took me a while to find the item in evernote, but once i did, i now see it gets put into “Notes” and not into a “notebook”. This is OK.

    Anyways, just wanted to say “Great Script” and Thank You for your support

  19. Ivan November 2, 2013 at 11:33 am #

    great script but not working in mavericks

    • Justin Lancy November 17, 2013 at 3:26 am #

      Several people are reporting Mavericks issues. I’ll try to take a look soon!

      • IVAN November 17, 2013 at 9:52 pm #

        Thanks, much appreciated. Its not the same without the script.

  20. Ivan November 2, 2013 at 11:51 am #

    I tried to run this code as explained here using quicksilver app ~> http://www.thesecretweapon.org/forums/topic/apple-mail-script-to-evernote-now-available

    I keep getting this syntax error!

  21. Bob Williams November 9, 2013 at 4:19 pm #

    2 Questions?

    1) Anyway to add code to automatically archive the message after moving to Evernote?
    2) Anyway to provide a drop down list of tags?

    Awesome script. Love it and appreciate the effort to make my life easier.

    • Justin Lancy November 17, 2013 at 3:24 am #

      Hi Bob – I think both are possible. Will keep this in mind for future versions!

  22. Zee November 12, 2013 at 4:13 pm #

    This script is such an awesome to all us productivity geeks! Thank you for all your hard work.

    I have one question/request:
    – We can customize the tags and selected notebook before the Evernote note is created, but is there a way to customize the note title? Oftentimes the subject line of the email is confusing or useless as a note title. Could that be one more thing we can enter before the tag is created.
    – For example for an email with the subject “Following Up,” I might want to title the note “Send email reply to John”.

    Is that possible already or would it be a feature request?

    Thanks!

    • Justin Lancy November 17, 2013 at 3:22 am #

      Hi Zee,

      That would be a “feature request”! 😉

      I’ll definitely keep it in mind for future versions but, should you not want to wait, I think it would be an easy edit for you to do. Why not give it a shot and, if you get it working, post your results back here for all the other people who want to do this!

      • Zee November 17, 2013 at 8:47 pm #

        Thanks for the reply.

        I will have to wait as I haven’t the slightest idea about how to add that. 🙂 Maybe easy for others but way out of my technical range unfortunately.

        Thanks anyways. This script is a huge help even without that.

        • Zee November 25, 2013 at 9:23 am #

          Hi Justin and everyone else,

          I am seeing now that I titling the notes is essential to a productive workflow for me.

          Even though I am new to this, I actually would like to try to edit the script to add that as described above. I’m willing to spend the time to figure it out.

          Can you give me any direction or suggestions on how to begin trying that? Any clues or tips on where to look or what to change would be great.

          Thanks!

          • Justin Lancy November 26, 2013 at 10:56 pm #

            Hi Zee!

            First, I’d suggest saving a copy as a “Change the Title” version so you have use both styles easily.

            The key section is in the

            on mail_Process(theMessages)

            subroutine. The script currently grabs the subject line of the email and assigns it to a variable for Evernote to use later on:

             set myTitle to the subject of thisMessage

            The following snippets are untested, but you might try changing it to something like this:

            set myTitle to text returned of (display dialog "Enter the title" default answer "")

            This should open an unformatted, empty text box for you to type in your title.

            If you wanted to use the subject line as the basis to modify the title, you might try something like this:

            set myTitle to text returned of (display dialog "Enter the title" default answer (the subject of thisMessage))

            Again, haven’t tested these… so play around with them if they don’t work straightaway. Good luck! 🙂

          • Zee November 27, 2013 at 3:36 pm #

            Wow. With your instructions it turned out to be super easy.

            Yes. It is working!!! Hooray.

            It does not work when I use your entry for using the subject line as the basis to modify the title. That would be cool to get working, but having a blank field can suffice for now.

            Thanks!!!!

  23. reinier van der hoek November 15, 2013 at 3:27 am #

    Hello,

    Since I installed Maverick I get with this script messages for every picture in the mail with the question that there isn’t a program for and have to select from the apple store.
    The email goes to evernote, but every time this messages is annoying.

    Anyone have the same problem or knows I to solve this.

    can’t do my work without this very nice script!
    With regards,

    Reinier van der Hoek

    • IVAN November 17, 2013 at 9:50 pm #

      Many people have problems with Maverick including me.
      I haven´t found any way yet to sort it, so i am importing ALL my email trough forwarding all in Mail Rules.

      Not the same as this script. I hope we can find a way to have it sorted soon

  24. Justin Lancy November 21, 2013 at 12:58 am #

    Note to 10.9 “Mavericks” Users

    I’ve been receiving messages from several 10.9 users that this script is not compiling. This isn’t entirely unexpected with a new OS version, but the truly fun part for me of figuring out the problem is that the script is still working fine on my 10.9 system. Sigh.

    If this is happening for you, I’ve written a short utility script which should grab the version information for Evernote and copy it to your clipboard. You can then paste it into a Bug Report and send it to me.

    If I can get enough reports, it should help me locate the issue. However, if this script is essential to your workflow, you might want to hold off on upgrading to 10.9 until the AppleScript issues are better understood/fixed/etc.

  25. Eric Alderman December 4, 2013 at 6:42 pm #

    Hi! Love this tool, thanks so much.

    I’m having one problem. It was working great for me, and then one day, everytime I kick off the script, it pops up the “Choose a Finder Item” dialog, and I have to manually navigate to my Applications folder and select the Evernote application. Then it continues as usual. I’ve checked the script and it still says

    tell application “Evernote”

    in several places, and my application is called “Evernote”. Any idea how it lost track of where the app is, and how to fix it?

    Thanks,
    Eric

    • Justin Lancy December 4, 2013 at 10:29 pm #

      Hi Eric,

      That’s a new one for me, but it seems some recent changes are causing some odd glitches like these for some people…

      Try this and let me know if it makes things better:

      Where you see…

      tell application "Evernote"

      …replace it with

        tell application id "com.evernote.evernote"

      Does this help?

      • Eric Alderman December 5, 2013 at 11:21 am #

        Hi Justin,

        Thanks. No didn’t work. When I saved the script, it asked me to locate “com.evernote.evernote”, and when I selected the application, it replaced all the instances in the script with “Evernote”, and so back to square 1.

        Eric

        • Justin Lancy December 6, 2013 at 8:30 pm #

          Hmmm… weird. I’ll think on this and let you know if I come up with anything. (And if you figure it out, let us know here!)

  26. Stephen January 6, 2014 at 6:49 pm #

    Hi Justin,

    Thanks for the script. I am trying to to use the ‘choose from list’ command in applescript to be able to choose the tags I want to put on an email, rather than typing them.

    I can get the pick list to show up but then I can’t get it to work with the existing script. I am sure it is my lack of programming expertise.

    I used your bit of code (get the list of notebooks) to get the list of tags and then display using the ‘Choose from List’. I have tried several bits and pieces but to no avail. Is it asking too much to get some help?

    on tagging_Dialog()
    try
    tell application “Evernote”

    set listOfTags to {} (*PREPARE TO GET EVERNOTE’S LIST OF Tags *)
    set EVTags to every tag (*GET THE Tag LIST *)
    repeat with currentTag in EVTags
    set currentTagName to (the name of currentTag)
    copy currentTagName to the end of listOfTags
    end repeat
    end tell

    end try
    try
    choose from list listOfTags with title “Tag Picker” with prompt “Choose one or more Tags” OK button name “Create in Default Notebook” cancel button name “Cancel” default items {“Tasks”} with multiple selections allowed

    end try

    Thanks
    Steve

  27. Aaron January 12, 2014 at 11:14 am #

    Working great for me as an Automator Service on Mavericks!

    Only issue I’m having (more of an annoyance than anything else): when I try to process emails that have embedded images – in, say, a signature – I get the same message for each one:

    “There is no application set to open the URL cid:[email protected].

    Search the App Store for an application that can open this document, or choose an existing application on your computer.”

    I CANCEL through all of these, and the processing continues fine; those embedded images, however, never make it to Evernote.

    I’m going to dig through the script to see if I can find out why, but would love your thoughts in the meantime! Thanks so much for a great script!

    • Aaron January 12, 2014 at 11:16 am #

      I lied – the embedded images *do* show up in the Evernote note. It’s just the warning popup that’s annoying.

      • reinier van der hoek February 1, 2014 at 3:51 am #

        I have the same problems!

        Really hope you can solve this, because it’s very annoying.

        Wih regards,

        Reinier van der Hoek

    • Acidham April 29, 2014 at 3:08 pm #

      I have the same issue with the URL error cid:…. and fixed it by changing a line in function

      on htmlFix(evHTML, theBoundary, myContent)

      → original code

      set theDecodeScript to "php -r "echo urldecode(" & the_UTF8Text & ");"" as text

      → changed it to

      set theDecodeScript to urlDecode(the_UTF8Text)

      and added the function to the end of the code

      -- URL Decode Subroutine
      on urlDecode(str)
          local str
          try
              return (do shell script "/bin/echo " & quoted form of str & ¬
                  " | perl -MURI::Escape -lne 'print uri_unescape($_)'")
          on error eMsg number eNum
              error "Can't urlDecode: " & eMsg number eNum
          end try
      end urlDecode
      • Justin Lancy May 2, 2014 at 7:39 am #

        Acidham – This code converts the message body to plaintext?

        • Acidham May 2, 2014 at 3:18 pm #

          I thought the Code does the same as you php version, not correct?

          For the result looks fine with the CID: image

  28. Steve January 27, 2014 at 9:55 am #

    Hi

    Thanks for this script – I have been using it for some time now with no problems (and I am no techie). However, recently it is not working 100%….it seems that it is no longer picking up my Evernote default notebook to load e-mails into. I have not changed this since it was working previously.

    Any ideas of what I can do to correct this?

    Thanks – and once again, thanks for the script donation,

    Steve

    • Justin Lancy February 1, 2014 at 2:08 am #

      Not really sure why that would be… What happens when you manually select it? Does it start working again after a system restart?

      • Steve February 4, 2014 at 10:21 am #

        Hi Justin

        It works fine when I manually select the designation – its just that my default is always “pending actions”, so its a bit of a pain to always have to change it. I have restarted before to no avail – but will retry this and let you know if it fixes the problem. Thanks for the reply.

        Steve

        • Steve February 6, 2014 at 12:52 pm #

          Unfortunately, no, system restart did not fix the problem.

  29. Steven Buehler February 6, 2014 at 1:04 pm #

    Awesome script. I did make one tweak, which was to change the message info section to grab the “date sent” rather than “date received” (which is how I usually sort my incoming email). Totally awesome though! Been looking for something like this for a while now.

  30. Dave Fordice March 3, 2014 at 4:02 pm #

    Do you have any plans to update the Mail -> Evernote script to accurately capture all the cc: addresses in the note? Right now it doesn’t appear to grab that field and put it into Evernote (whereas your other script for Outlook 2011 does do it). Thanks!

    • Justin Lancy March 14, 2014 at 2:42 am #

      I’m definitely looking at at this!

  31. Marc Vos April 2, 2014 at 9:55 am #

    Hi, I like your script – still testing and thinking about getting all my mail folders into Evernote or not. But anyway, I’ve added these two lines right below ‘-GET MESSAGE INFO’ which makes life in Evernote easier for me because now all emails are sorted. I sort alphabetically on note-name:

    set {year:y, month:m, day:d, hours:h, minutes:i} to (date received of thisMessage)
    set myTitle to (y * 10000 + m * 100 + d as string) & “_” & (h * 100 + i as string) & “.” & the subject of thisMessage

    • Marc Vos May 15, 2014 at 4:12 am #

      The above addition doesn’t handle time like 00:04 correctly. You’ll get a subject like 20140515_4.Subject instead of 20140515_0004.subject. So I corrected the code and here are the new lines to replace the old one with:

      set {year:y, month:m, day:d, hours:h, minutes:i} to (date received of thisMessage)
      set myHour to ("0000" & (h * 100 + i as string))
      copy characters (length of myHour) through ((length of myHour) - 3) of myHour as string to myHour
      set myTitle to (y * 10000 + m * 100 + d as string) & "_" & myHour & "." & the subject of thisMessage
  32. Jacob April 27, 2014 at 8:20 am #

    This is exactly what I have been looking for however I have a little issue that each email is imported 4 times. I tried both app store and direct download and run 10.8.5. Do you have any idea what I can be doing wrong?

    Thanks!!

  33. Christopher Rogers July 6, 2014 at 11:54 am #

    Justin this script is awesome and thank you for writing it. I have seen some other scripts that attempt this but yours has the added functionality of processing attachments and the ability to add tags before processing.

    I have been playing around with the script that is posted on the Evernote website that they have turned into a service. The only functionality that it has that I want to add to yours is the final action of moving the email to the archive folder. I am not much of a coder but I can hack up other people’s hard work (thanks again). Anyway here is the code that is in that script that moves the message.

    -- move the email message to archive and make it bloody obvious
                set background color of theMessage to blue
                set acc to account of mailbox of theMessage
                move theMessage to mailbox "Archive" of acc

    when I compile the added code I get an error about the background color. Any tips on moving forward?

  34. Christopher Rogers July 8, 2014 at 1:16 pm #

    I was able to copy the portion of the applescript found here that archives the email after it processes the send to Evernote. I could not figure out how to turn the new script into a .workflow like they did there. I think that the problem is that this script is too complicated to be executed from Automator, but I will keep poking around with it. I was able to assign a hot key to the script using Quicksilver.

    So I placed the script in the folder /Library/Scripts/Mail Scripts then I pointed Quicksilver to that script and assigned it a hot key.

    You can download the edited script with the archiving code here.

    Any help turning this thing into a Finder service so that a 3rd party app doesn’t have to be used would be cool.

    • Justin Lancy July 10, 2014 at 2:30 pm #

      Hi Christopher,

      Kudos to you for your scripting!

      I’ve been planning on adding Archiving to the next revision of this script; It should happen once I finish some other projects… and I’m working out a better way to share things like services so that I can roll scripts like these into them for download.

      • Christopher Rogers July 13, 2014 at 8:26 pm #

        Thanks Justin! All I did was play around with the code that other people wrote. I heard that Apple was going to make it easier to write plugins for Mail in Yosemite, so maybe Evernote will write a legit plugin soon.

  35. Brian July 9, 2014 at 10:43 am #

    I would love to see MailTags support put back in.

  36. Adam Gordon July 17, 2014 at 12:18 pm #

    Hi Justin,

    Is Growl necessary or not? In part of your write up you say it isn’t, then in several other places the copy here says it is.

    I’d rather not use Growl, and in your description, up top, you say, “(If you prefer not to use it, just edit out these portions of the script.)”

    Could you be a bit more detailed about what parts to edit out if I don’t want to use Growl? I’ve gone through the code and attempted to edit out everything that refers to Growl, yet am still getting an error message on compile that the script is looking for Growl.

    Thanks
    Adam

    • Justin Lancy July 17, 2014 at 11:07 pm #

      Hi Adam,

      Let me put the stuff you care most about up top: GROWL is currently necessary to run the script without editing it. The next version of this script will likely eliminate it, since I feel like most people have upgraded to a version of OS X with Notification Center. I am busy with other projects now, so I can’t give any ETA on a release.

      While I tried to give all the variables names that would help people locate them with a ‘Find’ search, I realize that those new to AppleScript may get a bit lost if they try to edit out those portions of the code. I can be hired to do script customizations and, if you need it fast more than you need it free, then just reach out via the contact form.