Mail script will not run unattended when ScreenSaver is active

I have a script which processes certain email messages overnight. Our company has a security requirement that our screensavers auto activate and require password to unlock.

The behavior is not consistent. Sometimes the script will run okay for an entire week. Then, inexplicably, the script will time out the next week. Today was such a day. I ssh’d to the Mac and tried running the script with osascript. Mail.app times out. I tried osascript -e to force Mail to the front and that times out. I tried activating the Finder, but same thing. I tried forcing the frontmost app to false and that didn’t work. I quit the foremost app. After that, when I queried System Events to determine what was now frontmost, it errored.
Next I tried sending commands directly to mail while it was in the background. Those all timed-out as well.
Sent killall ScreenSaverEngine and re-tried all above to no avail.
According to ‘top’ the process status of Mail is sleeping.

If I wake and log into the machine. Then remotely activate the screensaver. The script runs.
Same if I activate the screensaver, and then stop screensaver but not logging in. Script runs.
There’s some weird ‘unconscious state’ the system seems to get stuck in.

The script needs to save attachments from certain messages. I am open to any ideas, crazy or sane.

High Sierra

How long of a timeout do you have set in your script?

Are you able to identify the point where the timeout occurs?

• I’ve experimented with short to extremely long timeouts. It will always reach the end time.

• The timeout occurs when the script enters the “Tell Mail” block.

I ran into this issue as well with some auto-launching scripts.

It was quite frustrating because it took me a while to realize that it had to do with the sleep state. I would just come back and find scripts timed out for seemingly no reason when they should have never timed out.

The timeout would happen for me when presenting an alert. Seems like AppleScript can still work in the background when the screen is locked, but any GUI stuff will cause a timeout.

The only solution I found (which may not work for your use-case) is to run this one-liner python script (https://stackoverflow.com/questions/11505255/osx-check-if-the-screen-is-locked) in a “do shell script” to detect if the screen is locked and just wait until it’s unlocked. I also run ioreg -n IODisplayWrangler | grep -i IOPowerManagement and check the output for “CurrentPowerState”=4 to determine if the computer is awake.

These two commands together have been a reliable check for a computer being awake and unlocked.

This worked for me because my work was already done in the background and I just waited until a user came back and woke up the computer before the script presented the results dialog. But, since you want work to be happening in the background that uses Mail, it may not be possible. Of course, if it’s really fast, it could just be the first thing that happens after the computer is woken up.

1 Like

Very helpful info. The next time it times out, I’ll ssh in and run that py script.

It’s interesting how under the seemingly the same conditions the script will run to completion.
I should run that py script first on a day when the AS script is working so I can compare the results.

Thanks!

Here’s my AppleScript code to wait until a computer is awake and unlocked that may be helpful for you or any future readers:

repeat
    set isAwake to true
    try
        set powerManagementInfo to (do shell script "ioreg -n IODisplayWrangler | grep -i IOPowerManagement")
        set isAwake to false
        if ((offset of "\"CurrentPowerState\"=4" in powerManagementInfo) > 0) then set isAwake to true
    end try
    
    set isUnlocked to true
    try
        set screenIsLockedValue to (do shell script "python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d.get(\"CGSSessionScreenIsLocked\", 0);'")
        set isUnlocked to false
        if (screenIsLockedValue is equal to "0") then set isUnlocked to true
    end try
    
    if (isAwake and isUnlocked) then
        exit repeat
    else
        delay 1
    end if
end repeat
1 Like

Very nice!!

Note to self: Use Python 2.7.

Look in the man pages for pmset (and caffeinate)

With pmset you can schedule when the mac will wake from sleep. I haven’t toyed with this much, but presumably you could schedule it to wake at a specified time, which happens to be 2 minutes before your script runs. After running query your script reschedule to wake and put then system to sleep. (you said you were open to crazy ideas!)

do shell script quoted form of "pmset schedule wake "07/04/16 20:00:00"

With caffeinate I think you can control how deep the sleep is, and possibly prevent it from going into “hibernate” mode, which is a deeper sleep and may be what’s causing the inconsistent behavior.

From my experiences, the timeout will happen even if the computer is awake, but the screen is locked.

There are things like caffeinate you could do to keep the computer awake, but that would really just be bypassing the companies security requirement that screensavers auto activate and require password to unlock. That probably wouldn’t end well.

**I woke the system up and it ran to a point and then stopped. **
Progress is being made.

The script hung this morning.
I used Pico’s script to asses the state of the system. It was asleep and locked.
Then I ran Ed’s pmset line over ssh and then rechecked the system.
System showed awake (still locked).
Run but got stuck on Mail timeout again.
I manually unlocked the screen, then relocked it.
Checked status- awake- locked
Re-ran script and it ran fine.

So there’s some unresponsive state where Mail ignores scripts.

Having some luck with running this before the script runs.

caffeinate -u -t 2

1 Like