Automatically create Calendar events when receiving email

I’m always looking for ways to automate the most repetitive tasks I find myself doing on my Mac. The other day, I realised that I spend a lot of time manually creating Calendar events by copying information from booking confirmation emails. This is exactly the sort of task that can be easily automated to save you a little bit of time and effort every day.

Here’s how you can set up a custom rule in Mail app that runs a short AppleScript to create a new event in Calendar app.

To illustrate how to do this, I’m going to use an example that I’ve set up for myself. I regularly receive booking confirmation emails from my local cinema that look like this:

Example email from cinema

All the information to create a Calendar event is there in the text, but it is annoyingly time consuming to do this manually. Let’s set up a Rule to process these emails automatically.

In Mail app, choose Preferences from the Mail menu, and click on the Rules tab. Create a new rule, and adjust the drop down menus to look like the screenshot below. The first section shows the conditions required to apply the rule to a message. In my case, I restrict the rule to only messages from “noreply@cineworldmail.com” in my “iCloud” account. When an email that meets these criteria is received, a series of actions are performed. First the message is moved out of my inbox into another mailbox, and it is marked as read.

The final action is the most complicated. It is a custom AppleScript that reads the email, figures out the name, date, time and location, then creates a Calendar event.

Mail rule to create calendar event

When you first choose Run AppleScript from the drop down menu, there will not be any AppleScripts available for you to run. First we have to create one.

To do this, open up AppleScript Editor. This is located in the Utilities folder in the Applications folder, or you can find it using Spotlight search or Launchpad. In the script window that appears, paste the following script:

-- Triggered by Mail rule.
using terms from application "Mail"
    on perform mail action with messages msgs for rule theRule
        tell application "Mail"
            repeat with msg in msgs
                try
                    set msgcontent to content of msg
                    set msgid to message id of msg
                    set {movie, runtime, cert, bref, starttime, addr, screen} to my parseMsg(msgcontent)
                    my createEvent(movie, runtime, cert, bref, starttime, addr, screen, msgid)
                end try
            end repeat
        end tell
    end perform mail action with messages
end using terms from

This is the general format of all Mail rule AppleScripts. One of the benefits of AppleScript is that it is very close to normal English language, and you can get some idea of what a script does even if you aren’t familiar with AppleScript. The above script takes each email message that the rule matched, and runs a function called parseMsg on it to extract the event details. Then it runs a function called createEvent using those details.

Next, below this paste the following functions:

-- Parse the email content to extract movie details.
on parseMsg(msgcontent)
    set movie to extractBetween(msgcontent, "You are going to see: ", "Cert: ")
    set cert to extractBetween(msgcontent, "Cert: ", "Running Time: ")
    set runtime to extractBetween(msgcontent, "Running Time: ", " minutes")
    set bref to extractBetween(msgcontent, "Booking Reference: ", "Date: ")
    set datestring to extractBetween(msgcontent, "Date: ", "Cinema: ")
    set addr to extractBetween(msgcontent, "Cinema: ", "Screen: ")
    set screen to extractBetween(msgcontent, "Screen: ", "Number of people going: ")
    set starttime to parseDateString(datestring)
    return {movie, runtime, cert, bref, starttime, addr, screen}
end parseMsg

-- Extract the substring from between two strings
to extractBetween(theString, startText, endText)
    set tid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to startText
    set startComps to text items of theString
    set AppleScript's text item delimiters to endText
    set endComps to text items of second item of startComps
    set AppleScript's text item delimiters to tid
    return trim(first item of endComps)
end extractBetween

-- Trim all whitespace from start and end of a string
on trim(theString)
    set theChars to {" ", tab, character id 10, return, character id 0, character id 8232}
    repeat until first character of theString is not in theChars
        set theString to text 2 thru -1 of theString
    end repeat
    repeat until last character of theString is not in theChars
        set theString to text 1 thru -2 of theString
    end repeat
    return theString
end trim

-- Parse date and time from the string given in the email.
on parseDateString(datestring)
    set theDate to current date
    set dateWords to words of datestring
    set day of theDate to text 1 thru -3 of item 2 of dateWords
    set time of theDate to (item 5 of dateWords) * hours + (item 6 of dateWords) * minutes
    set monthList to {January, February, March, April, May, June, July, August, September, October, November, December}
    repeat with i from 1 to 12
        if item 3 of dateWords = ((item i of monthList) as string) then
            set monthNumber to (text -2 thru -1 of ("0" & i))
            exit repeat
        end if
    end repeat
    set month of theDate to monthNumber
    return theDate
end parseDateString

This is the core of the AppleScript, which parses the email to extract the event details. The way it works is to extract the text between two other pieces of text. For example, it extracts the text between You are going to see: and Cert: and sets it as the name of the movie. You will need to modify this to match the exact format of your email. A bit of trial and error may be necessary, so you may want to test the rule on emails you send to yourself.

Finally, paste the following function that creates the Calendar event:

-- Create a calendar event for the specified movie.
on createEvent(movie, runtime, cert, bref, starttime, addr, screen, msgid)
    set endtime to starttime + runtime * minutes
    tell application "Calendar" to tell calendar "Home"
        set theEvent to make new event with properties {start date:starttime, end date:endtime, summary:"Cinema: " & movie}
        set location of theEvent to screen & ", Cineword " & addr
        set description of theEvent to "Booking Reference: " & bref & return & "Run Time: " & runtime & " minutes" & return & "Certificate: " & cert
        set url of theEvent to "message://" & "%3c" & msgid & "%3e"
    end tell
end createEvent

You will also need to modify this to match the exact details in your email messages. Above, I set the name of the even to the title of the movie and I calculate the end time by adding the running time of the movie to the start time. I set the location of the event to the screen number and the cinema address, and I add a few details to the event notes like my booking reference number. Setting the url of the event to the email message id also provides a handy link back to the original email message from within Calendar.

You can find the full script here.

Now all we need to do is save the AppleScript somewhere Mail can see it. Choose Save from the File menu, and then press Command-Shift-G to bring up the Go to folder dialog. In the text field, type ~/Library/Application Scripts/com.apple.mail and press Return. Give the script a memorable name and save it. Now, when you return to Mail, your script should be available in the drop down menu next to “Run AppleScript”.

blog comments powered by Disqus