Skip to content

Instantly share code, notes, and snippets.

@wsoyka
Last active August 9, 2024 17:56
Show Gist options
  • Save wsoyka/8e0497379b9598dfe5116f04282247d1 to your computer and use it in GitHub Desktop.
Save wsoyka/8e0497379b9598dfe5116f04282247d1 to your computer and use it in GitHub Desktop.
Applescript - Bring a specific chromium tab to front or open it in a given profile
###################################################
#
# Version: 2024-08
#
# This script will search all open Browser Windows for a specified Tab (by Title).
# At some point, this worked for Google Chrome and Brave Browser.
# Other chromium based browsers should work, but have not been tested.
#
# If no tab with the given title is found, it will open the specified URL in the
# specified Profile. If multiple tabs with the specified title exist, the first one
# found will be opened.
#
# Chromium's applescript APIs does not offer support for changing the browser profile, so we need to emulate clicks on the relevant elements.
# Due to this, the application that is going to run the script (a hotkey application (BetterTouchTool, KeyboardMaestro), or e.g
# Terminal) will have to be granted Accessibility Access (System Preferences > Security & Privacy > Privacy > Accessibility)
#
#
# Params:
# browser: the name of the app ("Google Chrome", "Brave Browser", ...)
# profileName: the exact name of the profile to be matched
# targetTabTitle: exact or partial tab title, as specified in the <title> tag
# targetUrl: the url to open, including http(s)://
#
# osascript ~/path/to/scriptname.scpt "Brave Browser" "My Profile Name" "Exact or partial <title> of the tab" "https://URLToOpenIfTabtIsNotFound.tld"
###################################################
property DEBUG : false #whether to log to /tmp/${scriptname}.log and use default args if none provided
property NOTIFICATIONS : true #whether to show notifications
property TARGET_BROWSER : "Brave Browser" #default, required here for TELL's to work. will be overwritten with provided argument.
on run argv
if (count of argv) = 4 then
set TARGET_BROWSER to item 1 of argv
set profileName to item 2 of argv
set targetTabTitle to item 3 of argv
set targetUrl to item 4 of argv
else
if DEBUG is true then
set TARGET_BROWSER to "Brave Browser"
set profileName to "Privat"
set targetTabTitle to "Example Domain - https://example.org/"
set targetUrl to "https://example.org/"
else
errExit("Use 4 arguments: <browser>, <profileName>, <targetTabTitle>, <targetUrl>")
end if
end if
mylog("New run. Target Browser: " & TARGET_BROWSER)
if browser_try_focus_tab(targetTabTitle) is false then # targetTabTitle is not yet open, lets open targetUrl it in the specified profile
#chromium browsers dont support changing profile via applescript api, hence the accessibility requirement of the script to do this
tell application "System Events" to tell process TARGET_BROWSER
set frontmost to true
end tell
try
set names to {"People", "Profiles"} #2021 - Brave (still) uses People, Chrome renamed it to Profiles, lets try both
set click_profile_selection_success to false
repeat with targetMenubarItemName in names
if click_profile_selection_success = false then
try
#chromium doesnt support changing profile via applescript api, hence the accessibility requirement
tell application "System Events" to tell process TARGET_BROWSER
click menu item profileName of menu 1 of menu bar item targetMenubarItemName of menu bar 1
end tell
click_profile_selection_success = true
exit repeat
on error
mylog(TARGET_BROWSER & " has no menu named: " & targetMenubarItemName)
end try
end if
end repeat
if click_profile_selection_success = false then
mylog("cannot open profile selection: " & targetMenubarItemName & "(probably your browser uses a different name)")
end if
on error errStr
errExit("error opening profile: " & profileName & " err:" & errStr)
end try
wait_for_browser_window()
#check again
if browser_try_focus_tab(targetTabTitle) is false then
showNotif given msg:"Opening new tab"
tell application TARGET_BROWSER
open location targetUrl
end tell
else
showNotif given msg:"Existing tab found in profile " & profileName
end if
else
showNotif given msg:"Existing tab found in current window"
end if
end run
on browser_try_focus_tab(targetTabTitle)
using terms from application "Brave Browser" # Unfortunately, the "base" application name needs to be hardcoded here.
tell application TARGET_BROWSER
activate
repeat with currentWindow in windows # currentWindow is of class "cwin" useful attributes: "title", "index", "document" (probably could do funny stuff with this one to match page content?)
my mylog("checking tabs of window" & (index of currentWindow))
set tabIndex to 0
repeat with currentTab in (every tab of currentWindow)
set tabIndex to tabIndex + 1
if title of currentTab contains targetTabTitle then
my mylog("found relevant tab")
set (active tab index of currentWindow) to tabIndex #have to set that tab to be the active tab _first_
#https://stackoverflow.com/questions/10366003/applescript-google-chrome-activate-a-certain-window/34375804#34375804
set index of currentWindow to 1
delay 0.01
do shell script "open -a " & (quoted form of TARGET_BROWSER) #focusing the browser now will show our tab
return true
end if
end repeat
end repeat
end tell
end using terms from
return false
end browser_try_focus_tab
on showNotif given title:nTitle : "", subtitle:nSubtitle : "", msg:nMsg : "", sound:nSound : "Frog"
if NOTIFICATIONS is true then
set myFilePath to POSIX path of (path to me)
set myFileName to do shell script "basename " & quoted form of myFilePath
if nTitle is "" then
set nTitle to myFileName
end if
display notification nMsg with title nTitle subtitle nSubtitle sound name nSound
end if
end showNotif
on mylog(myObj)
if DEBUG is true then
set myFilePath to POSIX path of (path to me)
set myFileName to do shell script "basename " & quoted form of myFilePath
do shell script "echo " & myFilePath & " `date '+%F %T'`: " & quoted form of (myObj as string) & " >> /tmp/" & myFileName & ".log"
end if
end mylog
on errExit(message)
showNotif given title:"Error", msg:message
if DEBUG is true then
my mylog("Error: " & message)
end if
error message #exit
end errExit
#instead of fixed delay, busy wait until profile window is open.
#based on https://apple.stackexchange.com/questions/343624/applescript-wait-for-safari-page-to-fully-load/343633
on wait_for_browser_window()
using terms from application "Brave Browser" # Unfortunately, the "base" application name needs to be hardcoded here.
tell application TARGET_BROWSER
delay 1
repeat until (loading of front window's tab 2 is false)
delay 0.2
end repeat
loading of front window's tab 2
end tell
end using terms from
end wait_for_browser_window
@oliv-j
Copy link

oliv-j commented Feb 14, 2023

If you have more than one of the specified window already open then the script will work but will also throw an error.
You can overcome this by placing the repeat section within a "try / end try" statement to catch the error.
If the title of your tab changes with context (e.g. date or email address) such as with google calendar or google mail then you can change
if title of currentTab is myTitle then
to
if title of currentTab contains myTitle then

and the variable myTitle can be just a section of the name like "Calendar" or your email address.

If you aren't passing a variable to the script then change these to something like (in the case of Gmail):

	set myProfile to "profile name as displayed in the menu bar"
	set myTitle to "[email protected]"
	set myUrl to "https://mail.google.com/mail/u/0/#inbox"

I also found that I needed to change the command to open the profiles to:

click menu item myProfile of menu 1 of menu bar item "Profiles" of menu bar 1

@tomwolber
Copy link

The "People" menu bar item is now "Profiles"

@wsoyka
Copy link
Author

wsoyka commented Aug 9, 2024

The "People" menu bar item is now "Profiles"

I also found that I needed to change the command to open the profiles to:

@tomwolber / @oliv-j Indeed. I've been using this script with Brave for a while, which still calls that menu "People".
I just updated the script to a new version that works on (probably) any chromium browser, targeting both the "Profiles" and "People" menu.

if title of currentTab contains myTitle then

@oliv-j Great idea! Added it to the new version. (Might cause conflicts if your targetTabTitle isnt unique though)

I'm currently not actively using this script, so if you find something to not be working, do let me know!

@wsoyka
Copy link
Author

wsoyka commented Aug 9, 2024

If you're not using Brave, you'll probably have to replace all instances of "Brave Browser" in the script with your flavour of chromium (e.g. "Google Chrome",..)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment