################################################################################# # Title: Create reminder from selected Mail ################################################################################# # Use at your own risk and responsibility # Backup your data before use # Last update: 2016-03-15 # Version: 0.5.0 # Tested on OS X 10.11.3 El Capitan # Description # When installed as a Service, this AppleScript script can be used to automatically create a reminder (in pre-defined Reminder lists) # from a selected email and flag the email. # If you run the script against an email that matches an existing reminder it can mark the reminder as completed and clear the flag in Mail # Contributors and sources # Rick0713 at https://discussions.apple.com/thread/3435695?start=30&tstart=0 # http://www.macosxautomation.com/applescript/sbrt/sbrt-06.html # http://www.michaelkummer.com/2014/03/18/how-to-create-a-reminder-from-an-e-mail/ ################################################################################# # Configuration ################################################################################# # Set this according to your email account names and Reminder's lists # Depending on your needs multiple accounts can send reminders to one or more reminder lists set Work1AccountName to "Work" set Work1RemindersList to "Work" set Work2AccountName to "WorkOther" set Work2RemindersList to "Work" set Personal1AccountName to "Privat" set Personal1RemindersList to "Privat" set Personal2AccountName to "iCloud" set Personal2RemindersList to "Privat" set Personal3AccountName to "Google" set Personal3RemindersList to "Privat" set Personal4AccountName to "PrivatOther" set Personal4RemindersList to "Privat" # Set the name of the default reminder list (depends on your OS Language) set DefaultReminderList to "Reminders" # On my machine 5 is the Purple flag, which is the color I would like to use for mails flagged as Reminder # choose something between 1 and 6 set FlagIndex to 5 # Set the default reminder date # these are the possible choices: "Tomorrow", "2 Days", "3 Days", "4 Days", "End of Week", "Next Monday", "1 Week", "2 Weeks", "1 Month", "2 Months", "3 Months", "Specify" set defaultReminder to "1 Week" # Set the default reminder time in hours after midnight, I suggest any number between 0,5 and 23,5 # for a reminder at "8:00 am" set "8", for "3 PM" or "15:00" set "15", for "8h45" set "8,75" set defaultReminderTime to "9" # For 'zero-mail' inbox: if this switch is set 'on' it will move the message automatically to the archive once a reminder has been set, # Set to 'off' if you want to keep the message where it is # switch 'auto-achive' "on" or "off" set switchArchive to "on" # Set the archive target mailbox set Work1Archive to "Archive" set Work2Archive to "Archive" set Personal1Archive to "Archive" set Personal2Archive to "Archive" set Personal3Archive to "Archive" set Personal3Archive to "Archive" ################################################################################# # Script ################################################################################# tell application "Mail" set theSelection to selection as list # do nothing if no email is selected in Mail try set theMessage to item 1 of theSelection on error return end try set theSubject to theMessage's subject set theOrigMessageId to theMessage's message id set theUrl to {"message:%3C" & my replaceText(theOrigMessageId, "%", "%25") & "%3E"} # Make sure reminder doesn't already exist so we don't create duplicates tell application "Reminders" set theNeedlesName to name of reminders whose body is theUrl and completed is false if theNeedlesName is not {} then # make sure dialog is in focus when called as a service # without the below, Mail would be the active application tell me activate end tell set theButton to button returned of (display dialog "The selected email matches an existing reminder: '" & theNeedlesName & "'. Would you like to mark the reminder as complete and clear any remaining flags of this message?" with title "Create Reminder from E-Mail" buttons {"New date", "Cancel", "Mark complete"} default button 3) if theButton is "Mark complete" then tell application "Mail" # unflag email/message set flag index of theMessage to -1 end tell # find correct reminder based on subject and mark as complete set theNeedle to last reminder whose body is theUrl and completed is false set completed of theNeedle to true return else if theButton is "New date" then # set the new reminder date # present user with a list of follow-up times (in minutes) (choose from list {"Tomorrow", "2 Days", "3 Days", "4 Days", "End of Week", "Next Monday", "1 Week", "2 Weeks", "1 Month", "2 Months", "3 Months", "Specify"} default items defaultReminder OK button name "Set new date" with prompt "Set follow-up time" with title "Set new reminder date") set reminderDate to result as text # Exit if user clicks Cancel if reminderDate is "false" then return # choose the reminder date set remindMeDate to my chooseRemindMeDate(reminderDate) set time of remindMeDate to 60 * 60 * defaultReminderTime # find correct reminder based on subject and mark as complete set theNeedle to last reminder whose body is theUrl and completed is false set remind me date of theNeedle to remindMeDate return else if theButton is "Cancel" then return end if end if end tell # display a dialog to ask for the reminder title if flag index of theMessage is not FlagIndex then display dialog "Create a reminder with the following title: '" & theSubject & "' or choose 'Other'" with title "Choose a title for the reminder" buttons {"Other", "Cancel", "OK"} default button 3 set theSubjectChoice to button returned of result if theSubjectChoice is "OK" then set theSubject to theMessage's subject else if theSubjectChoice is "Cancel" then return else if theSubjectChoice is "Other" then set theSubject to text returned of (display dialog "Choose a title:" default answer theSubject) end if end if # present user with a list of follow-up times (in minutes) (choose from list {"Tomorrow", "2 Days", "3 Days", "4 Days", "End of Week", "Next Monday", "1 Week", "2 Weeks", "1 Month", "2 Months", "3 Months", "Specify"} default items defaultReminder OK button name "Create" with prompt "Set follow-up time" with title "Create Reminder from E-Mail") set reminderDate to result as rich text # exit if user clicks Cancel or Escape if reminderDate is "false" then return # for all the other options, calculate the date based on the current date set remindMeDate to my chooseRemindMeDate(reminderDate) # set the time for on the reminder date set time of remindMeDate to 60 * 60 * defaultReminderTime # Flag selected email/message in Mail set flag index of theMessage to FlagIndex # Get the unique identifier (ID) of selected email/message set theOrigMessageId to theMessage's message id #we need to encode % with %25 because otherwise the URL will be screwed up in Reminders and you won't be able to just click on it to open the linked message in Mail set theUrl to {"message:%3C" & my replaceText(theOrigMessageId, "%", "%25") & "%3E"} # determine correct Reminder's list based on account the email/message is in if name of account of mailbox of theMessage is Work1AccountName then set RemindersList to Work1RemindersList else if name of account of mailbox of theMessage is Work2AccountName then set RemindersList to Work2RemindersList else if name of account of mailbox of theMessage is Personal1AccountName then set RemindersList to Personal1RemindersList else if name of account of mailbox of theMessage is Personal2AccountName then set RemindersList to Personal2RemindersList else if name of account of mailbox of theMessage is Personal3AccountName then set RemindersList to Personal3RemindersList else if name of account of mailbox of theMessage is Personal4AccountName then set RemindersList to Personal4RemindersList else if account type of account of mailbox of theMessage is "r/o" then #default list name in Reminders set RemindersList to DefaultReminderList else #default list name in Reminders set RemindersList to DefaultReminderList end if # dispatch the mailbox where to archive the selected message if switchArchive is "on" then if name of account of mailbox of theMessage is Work1AccountName then move theMessage to mailbox Work1Archive of account Work1AccountName else if name of account of mailbox of theMessage is Work2AccountName then move theMessage to mailbox Work2Archive of account Work2AccountName else if name of account of mailbox of theMessage is Personal1AccountName then move theMessage to mailbox Personal1Archive of account Personal1AccountName else if name of account of mailbox of theMessage is Personal2AccountName then move theMessage to mailbox Personal2Archive of account Personal2AccountName else if name of account of mailbox of theMessage is Personal3AccountName then move theMessage to mailbox Personal3Archive of account Personal3AccountName else if name of account of mailbox of theMessage is Personal4AccountName then move theMessage to mailbox Personal4Archive of account Personal4AccountName end if end if end tell tell application "Reminders" tell list RemindersList # create new reminder with proper due date, subject name and the URL linking to the email in Mail make new reminder with properties {name:theSubject, remind me date:remindMeDate, body:theUrl} end tell end tell ################################################################################# # Functions ################################################################################# # string replace function # used to replace % with %25 on replaceText(subject, find, replace) set prevTIDs to text item delimiters of AppleScript set text item delimiters of AppleScript to find set subject to text items of subject set text item delimiters of AppleScript to replace set subject to "" & subject set text item delimiters of AppleScript to prevTIDs return subject end replaceText # date calculation with the selection from the dialogue # use to set the initial and the re-scheduled date on chooseRemindMeDate(selectedDate) if selectedDate = "Tomorrow" then # add 1 day and set time to 9h into the day = 9am set remindMeDate to (current date) + 1 * days else if selectedDate = "2 Days" then set remindMeDate to (current date) + 2 * days else if selectedDate = "3 Days" then set remindMeDate to (current date) + 3 * days else if selectedDate = "4 Days" then set remindMeDate to (current date) + 4 * days else if selectedDate = "End of Week" then # end of week means Thursday in terms of reminders # get the current day of the week set curWeekDay to weekday of (current date) as string if curWeekDay = "Monday" then set remindMeDate to (current date) + 3 * days else if curWeekDay = "Tuesday" then set remindMeDate to (current date) + 2 * days else if curWeekDay = "Wednesday" then set remindMeDate to (current date) + 1 * days # if it's Thursday, I'll set the reminder for Friday else if curWeekDay = "Thursday" then set remindMeDate to (current date) + 1 * days # if it's Friday I'll set the reminder for Thursday next week else if curWeekDay = "Friday" then set remindMeDate to (current date) + 6 * days else if curWeekDay = "Saturday" then set remindMeDate to (current date) + 5 * days else if curWeekDay = "Sunday" then set remindMeDate to (current date) + 4 * days end if else if selectedDate = "Next Monday" then set curWeekDay to weekday of (current date) as string if curWeekDay = "Monday" then set remindMeDate to (current date) + 7 * days else if curWeekDay = "Tuesday" then set remindMeDate to (current date) + 6 * days else if curWeekDay = "Wednesday" then set remindMeDate to (current date) + 5 * days else if curWeekDay = "Thursday" then set remindMeDate to (current date) + 4 * days else if curWeekDay = "Friday" then set remindMeDate to (current date) + 3 * days else if curWeekDay = "Saturday" then set remindMeDate to (current date) + 2 * days else if curWeekDay = "Sunday" then set remindMeDate to (current date) + 1 * days end if else if selectedDate = "1 Week" then set remindMeDate to (current date) + 7 * days else if selectedDate = "2 Weeks" then set remindMeDate to (current date) + 14 * days else if selectedDate = "1 Month" then set remindMeDate to (current date) + 28 * days else if selectedDate = "2 Months" then set remindMeDate to (current date) + 56 * days else if selectedDate = "3 Months" then set remindMeDate to (current date) + 84 * days else if selectedDate = "Specify" then # adapt the date format suggested with what is configured in the user's 'Language/Region'-Preferences set theDateSuggestion to (short date string of (current date)) set theDateInput to text returned of (display dialog "Type the date for the reminder (e.g. '" & theDateSuggestion & "'):" default answer theDateSuggestion buttons {"Cancel", "OK"} default button "OK") try set remindMeDate to date theDateInput on error set remindMeDate to (current date) + 1 * days (display dialog "There was an error with the date input provided: '" & theDateInput & "'. The reminder was set to tomorrow." with title "Error: '" & theDateInput & "'") end try end if return remindMeDate end chooseRemindMeDate