Last active
December 10, 2025 03:56
-
-
Save drewkerr/0f2b61ce34e2b9e3ce0ec6a92ab05c18 to your computer and use it in GitHub Desktop.
Read the current Focus mode on macOS Monterey (12.0+) using JavaScript for Automation (JXA)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const app = Application.currentApplication() | |
| app.includeStandardAdditions = true | |
| function getJSON(path) { | |
| const fullPath = path.replace(/^~/, app.pathTo('home folder')) | |
| const contents = app.read(fullPath) | |
| return JSON.parse(contents) | |
| } | |
| function run() { | |
| let focus = "No focus" // default | |
| const assert = getJSON("~/Library/DoNotDisturb/DB/Assertions.json").data[0].storeAssertionRecords | |
| const config = getJSON("~/Library/DoNotDisturb/DB/ModeConfigurations.json").data[0].modeConfigurations | |
| if (assert) { // focus set manually | |
| const modeid = assert[0].assertionDetails.assertionDetailsModeIdentifier | |
| focus = config[modeid].mode.name | |
| } else { // focus set by trigger | |
| const date = new Date | |
| const now = date.getHours() * 60 + date.getMinutes() | |
| for (const modeid in config) { | |
| const triggers = config[modeid].triggers.triggers[0] | |
| if (triggers && triggers.enabledSetting == 2) { | |
| const start = triggers.timePeriodStartTimeHour * 60 + triggers.timePeriodStartTimeMinute | |
| const end = triggers.timePeriodEndTimeHour * 60 + triggers.timePeriodEndTimeMinute | |
| if (start < end) { | |
| if (now >= start && now < end) { | |
| focus = config[modeid].mode.name | |
| } | |
| } else if (start > end) { // includes midnight | |
| if (now >= start || now < end) { | |
| focus = config[modeid].mode.name | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return focus | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Reading the JSON files in the user library throws permissions problems for me when attempting to run the script outside of a terminal (e.g. on a schedule via Lingon.app). That goes for the both the JavaScript for Automation as well as the Python variants that were posted. Any suggestions on how to overcome this other than running as root?
With @roman-ld's Python script, I also ran into errors thrown because of keys that were expected by the script but missing in the JSON files on my system. I'm barely familiar with python but was able to come up with workarounds in case it's useful for someone:
The
storeAssertionRecordskey in the lineassertJ = json.load(open(ASSERT_PATH))['data'][0]['storeAssertionRecords']was missing, so I replaced that line with:and the index
0in the linetriggers = configJ[modeid]['triggers']['triggers'][0]was missing, so I replaced that line with these:EDIT: The solution to the permissions problem mentioned above was to drag the script onto MacOS's Settings > Privacy & Security > Full Disk Access pane. (Manually adding with the
+button sometimes works too depending on the script extension). At least on my system, the script will not show up in the GUI of the preferences pane (thanks, Apple), but will be registered as having full disk access. Good luck removing its permission if you ever want to, without being able to select it in the GUI, however. I had to use Tinkertool System to remove full disk access perms for everything.