I’m trying to get an AppleScript to run from a rule in Mail.app under Catalina. It works fine on my old iMac running High Sierra but not on my new one running Catalina.
The script is fairly basic. It parses an email and then uses the data from it to create a Calendar Event.
-- Triggered by Mail rule.
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
tell application "Mail"
repeat with theMessage in theMessages
try
set msgsubject to subject of theMessage
set msgcontent to content of theMessage
set msgid to message id of theMessage
set {amount, dueon} to my parseMsg(msgcontent)
my createEvent(msgsubject, msgid, amount, dueon)
end try
end repeat
end tell
end perform mail action with messages
end using terms from
-- Parse the email content to extract invoice details.
on parseMsg(msgcontent)
set amount to extractBetween(msgcontent, "Invoice for", "due by")
set dueon to extractBetween(msgcontent, "due by", "Review")
return {amount, dueon}
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
-- Create a calendar event for the specified invoice.
on createEvent(msgsubject, msgid, amount, dueon)
set startdate to (current date) + 28 * days
set sentdate to current date
-- set enddate to startdate
tell application "Calendar" to tell calendar "Invoices"
set theEvent to make new event with properties {start date:startdate, summary:"Check " & msgsubject, allday event:true}
delay 5
set description of theEvent to amount & return & "Due on: " & dueon & return & "Sent on: " & sentdate
delay 5
set url of theEvent to "message:" & "%3c" & msgid & "%3e"
delay 10
tell theEvent
-- Add a email alarm
make new mail alarm at end of mail alarms with properties {trigger interval:10}
delay 10
make new sound alarm at end of sound alarms with properties {trigger interval:370, sound name:"Sosumi"}
end tell
end tell
end createEvent
I have also enabled access to the Calendar for Mail.app in the Privacy Panel of System Preferences.
The rule tries to run as I see a little gear icon appear in the menu bar and Calendar.app opens, but the calendar event isn’t added. As I say, this works perfectly in High Sierra. Has anyone got any ideas?
I’d guess this is an issue involving the security mechanisms that were introduced in Mojave and Catalina. Can you set up a test outside of Mail.app so you can see where the script is failing?
OK, I’ve made some changes so that I can run the Script in Script Editor (by giving the variables plain text strings rather than extracting them from the email).
When I run the script I get the following error: error “Calendar got an error: Can’t get calendar “Invoices”.” number -1728 from calendar “Invoices”
That gives me a clue I guess - although the Calendar that it should be adding the event to does exist in my Calendar app. Could it be something to do with the quotes around “Calendar” and “Invoices” in the following line of the script:
tell application "Calendar" to tell calendar "Invoices"
Thanks. I can’t add Script Editor to the Calendar or Automation sections of the Privacy System Preference Pane, but I have given it Full Disk Permissions. Unfortunately it makes no difference, the error is still the same:
error “Calendar got an error: Can’t get calendar “Invoices”.” number -1728 from calendar “Invoices”
tell application "Calendar" to tell calendar "Invoices"
changed to
tell application "Calendar" to tell calendar ("Invoices")
Also added an end date to the new event properties.
With that done all seems to be working again - phew! here’s the full working script again.
-- Triggered by Mail rule.
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
tell application "Mail"
repeat with theMessage in theMessages
try
set msgsubject to subject of theMessage
set msgcontent to content of theMessage
set msgid to message id of theMessage
set {amount, dueon} to my parseMsg(msgcontent)
my createEvent(msgsubject, msgid, amount, dueon)
end try
end repeat
end tell
end perform mail action with messages
end using terms from
-- Parse the email content to extract invoice details.
on parseMsg(msgcontent)
set amount to extractBetween(msgcontent, "Invoice for", "due by")
set dueon to extractBetween(msgcontent, "due by", "Review")
return {amount, dueon}
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
-- Create a calendar event for the specified invoice.
on createEvent(msgsubject, msgid, amount, dueon)
set startdate to (current date) + 28 * days
set sentdate to current date
set enddate to startdate
tell application "Calendar" to tell calendar ("Invoices")
set theEvent to make new event with properties {start date:startdate, end date:enddate, summary:"Check " & msgsubject, allday event:true}
delay 5
set description of theEvent to amount & return & "Due on: " & dueon & return & "Sent on: " & sentdate
delay 5
set url of theEvent to "message:" & "%3c" & msgid & "%3e"
delay 10
tell theEvent
-- Add a email alarm
make new mail alarm at end of mail alarms with properties {trigger interval:10}
delay 10
make new sound alarm at end of sound alarms with properties {trigger interval:370, sound name:"Sosumi"}
end tell
end tell
end createEvent
Now to start work on the script that removes the alarms when I get an email to say that the invoice has been paid! (that’s not working in Catalina either!)