I think the problem was due to language differences. Here is a version of the script that should work under any language. Now it checks if the 1PMini window has a secure text field (for your password). If so, it is considered locked.
set searchTerm to "icloud"
tell application "System Events"
set preClip to the clipboard as text
set elements to every UI element whose creator type is "1Ph*"
if elements is {} then
log "1Password Mini is not running"
return
end if
set mini to (first item of elements)
log short name of mini & " is running as " & name of mini
open location "x-onepassword-helper://search/" & searchTerm
delay 0.2
tell its UI element (name of mini)
set isLocked to (subrole of text field 1 of window 1 is "AXSecureTextField")
if isLocked then
log "1Password Mini is locked"
return
else
set frontmost to true
keystroke "c" using {command down, shift down}
delay 0.5
set thePass to the clipboard as text
tell application "App Store" to activate
delay 0.5
keystroke thePass
key code 36
set the clipboard to preClip
end if
end tell
end tell
Previous version assumed 1P was going to already be unlocked. If it was locked, it just finished. The 1PMini window showing was from the open location command, which is a background job that runs the search and is unrelated to this script.
Here is an updated script that checks if 1P is locked and if so, waits 10 seconds for you to enter your password. Once it has been unlocked, it copies the search result as desired.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on run
set searchTerm to "icloud"
tell application "System Events"
set preClip to (the clipboard) as text
set elements to every UI element whose creator type is "1Ph*"
if elements is {} then
log "1Password Mini is not running"
return false
end if
set mini to (first item of elements)
set miniName to short name of mini
log miniName & " is running as " & name of mini
set isLocked to my isOPMiniLocked(miniName)
open location "x-onepassword-helper://search/" & searchTerm
if isLocked then
if not (my waitForUnlock(miniName, 10)) then
return false
end if
end if
tell its UI element (name of mini)
set frontmost to true
set i to 0
repeat
try
if (focused of text field 1 of window 1) is true then
tell text field 1 of window 1
set value to searchTerm
perform action "AXConfirm"
end tell
delay 1.0
keystroke "c" using {command down, shift down}
delay 0.5
set thePass to (the clipboard) as text
exit repeat
end if
end try
delay 0.1
set i to i + 1
if i > 100 then
return false
end if
end repeat
tell application "App Store" to activate
delay 0.5
keystroke thePass
key code 36
set the clipboard to preClip
end tell
end tell
end run
on isOPMiniLocked(miniName)
tell application "System Events"
tell application process miniName
perform action "AXPress" of menu bar item 1 of menu bar 1
set isLocked to (subrole of text field 1 of window 1 is "AXSecureTextField")
delay 0.1
key code 53 -- Escape key to close 1PMini window
if isLocked then
log "1Password Mini is locked"
return true
end if
log "1Password Mini is unlocked"
return false
end tell
end tell
end isOPMiniLocked
on waitForUnlock(pProcessName, pMaxTimeSec)
local startTime, elapTime, errMsg
set startTime to current application's NSDate's |date|()
log startTime
tell application "System Events"
repeat
set elapTime to (-(round ((startTime's timeIntervalSinceNow()) * 100)) / 100.0)
if (elapTime > pMaxTimeSec) then
set errMsg to "Max Time of " & pMaxTimeSec & " seconds exceeded waiting for " & pProcessName
log errMsg
return false
end if
try
set roleMode to (subrole of text field 1 of window 1) of (application process pProcessName)
if roleMode is "AXSearchField" then
return true
end if
end try
delay 0.1
end repeat
end tell
end waitForUnlock
Thousand thanks for your help The script works now. Since I’m an absolute beginner with Applescript, what do I have to do to expand the 10 seconds to 15 seconds? Longer passwords would be better.
I would like to introduce the applescript in a tutorial for KM macros. Is that okay for you? Of course, I refer to your post as a source.
My YouTube channel http://d.pr/lxpDlP is not commercial or monetarized. I would like to make KM more popular for Germany.
Thanks for sharing your scripts.
It is best if you put them in a code block:
###How to Put Script in a Forum Code Block
Just insert your script between the lines with the triple backquotes:
```applescript
-- Your Script Here
If your script is another language, like JavaScript, then use the keyword in lower case for that language, like:
`javascript`
Here is a macro that will paste the script on the clipboard into the forum in the proper format:
####[MACRO: KM Forum -- Paste Script Block](https://forum.keyboardmaestro.com/t/paste-script-block-in-km-forum/4047)
Hello @Onan & @JMichaelTX I , thank you for your help. Unfortunately, the applescript didn't work with the Touch ID on the new MacBook Pro with Touch Bar.
Since I'm a newcomer to applescripts, I kept my macro simple and solved the problem with unlocking the 1Password Mini's with screenshots. Therefore I am not only dependent on seconds to enter the master password.
I have made a tutorial in german. Maybe it also helps others to work with it
The applescript was specifically calling elements in the 1PMini menu in the OSX menu bar. If you were calling the floating 1PMini window or using the TouchBar (which is like an extension to the display) then the script would not work.
Interesting way to do the macro. Glad you found a solution that works for you.
Could you update the AppleScript to make it work with the latest version of MacOS and the latest version of 1Password? I'm interested in the script but it doesn't seem to work with the current versions. Thanks!
Thanks for your reply. I already modified your previous macro with screenshots from Mojave dark mode and the new command. And it’s working fine. But I’m curious about the AppleScript solution to check if 1Password Mini is running. So, I will look forward for @Onan's reply…
I don't have Mojave installed yet but I do have the latest version of 1Password. Here is an updated script that works for me with 1Password 7.1.2 under macOS High Sierra (10.13.6). Let me know if it doesn't work and I'll try to get Mojave installed on a test box or a VM.
You might not need this but I've changed the script to query Keyboard Maestro for variables "OPsearchTerm" and "OPwaitTime" for the text to search in 1Password and how long to wait to unlock 1P if it is locked. Set these values in your KM macro using the "Set Variable to Text" action before calling the AppleScript.
Click here to show the script
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on run
--» Get the property values from Keyboard Maestro variables
tell application "Keyboard Maestro Engine"
set searchTerm to getvariable "OPsearchTerm"
if searchTerm is "" then return false
set waitTime to getvariable "OPwaitTime"
if waitTime is "" then return false
end tell
tell application "System Events"
set preClip to (the clipboard) as text
set elements to every UI element whose creator type is "1Pwd"
if elements is {} then return false
set appRef to (first item of elements)
set menuBars to every menu bar of appRef
if (count of menuBars) is 1 then return false
set appName to short name of appRef
set isLocked to my isOPlocked(appName)
open location "onepassword://extension/search/" & searchTerm
if isLocked then
if not (my waitForUnlock(appName, waitTime)) then return false
end if
tell its UI element (name of appRef)
set frontmost to true
set i to 0
repeat
try
if (focused of text field 1 of window 1) is true then
tell text field 1 of window 1
set value to searchTerm
perform action "AXConfirm"
end tell
delay 1.0
keystroke "c" using {command down, shift down}
delay 0.5
set thePass to (the clipboard) as text
exit repeat
end if
end try
delay 0.1
set i to i + 1
if i > 100 then return false
end repeat
tell application "App Store" to activate
delay 0.5
keystroke thePass
key code 36
set the clipboard to preClip
end tell
end tell
end run
on isOPlocked(appName)
tell application "System Events"
tell application process appName
perform action "AXPress" of menu bar item 1 of menu bar 2
set isLocked to (subrole of text field 1 of window 1 is "AXSecureTextField")
delay 0.1
key code 53 -- Escape key to close 1PMini window
if isLocked then return true
return false
end tell
end tell
end isOPlocked
on waitForUnlock(pProcessName, pMaxTimeSec)
local startTime, elapTime, errMsg
set startTime to current application's NSDate's |date|()
tell application "System Events"
repeat
set elapTime to (-(round ((startTime's timeIntervalSinceNow()) * 100)) / 100.0)
if (elapTime > pMaxTimeSec) then return false
try
set roleMode to (subrole of text field 1 of window 1) of (application process pProcessName)
if roleMode is "AXSearchField" then return true
end try
delay 0.1
end repeat
end tell
end waitForUnlock
Thank you very much @Onan! This is working just fine! One more question though:
Is there a way to also copy the username in a variable?
I tried this:
delay 1.0
keystroke "c" using {command down, control down}
delay 0.5
set theUsername to (the clipboard) as text
delay 1.0
keystroke "c" using {command down, shift down}
delay 0.5
set thePass to (the clipboard) as text
But I realised that 1Password Mini closes after the first copy.
Sure. Just need to call 1P again to get the next part.
Here is an updated script
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
on run
--» Get the property values from Keyboard Maestro variables
tell application "Keyboard Maestro Engine"
set searchTerm to getvariable "OPsearchTerm"
if searchTerm is "" then return false
set waitTime to getvariable "OPwaitTime"
if waitTime is "" then return false
end tell
tell application "System Events"
set preClip to (the clipboard) as text
set elements to every UI element whose creator type is "1Pwd"
if elements is {} then return false
set appRef to (first item of elements)
set menuBars to every menu bar of appRef
if (count of menuBars) is 1 then return false
set appName to short name of appRef
set isLocked to my isOPlocked(appName)
--» Get the Username
open location "onepassword://extension/search/" & searchTerm
if isLocked then
if not (my waitForUnlock(appName, waitTime)) then return false
end if
tell its UI element (name of appRef)
set frontmost to true
set i to 0
repeat
try
if (focused of text field 1 of window 1) is true then
tell text field 1 of window 1
set value to searchTerm
perform action "AXConfirm"
end tell
delay 1.0
keystroke "c" using {command down, control down}
delay 0.5
set theUsername to (the clipboard) as text
exit repeat
end if
end try
delay 0.1
set i to i + 1
if i > 100 then return false
end repeat
end tell
--» Get the Password
open location "onepassword://extension/search/" & searchTerm
if isLocked then
if not (my waitForUnlock(appName, waitTime)) then return false
end if
tell its UI element (name of appRef)
set frontmost to true
set i to 0
repeat
try
if (focused of text field 1 of window 1) is true then
tell text field 1 of window 1
set value to searchTerm
perform action "AXConfirm"
end tell
delay 1.0
keystroke "c" using {command down, shift down}
delay 0.5
set thePass to (the clipboard) as text
exit repeat
end if
end try
delay 0.1
set i to i + 1
if i > 100 then return false
end repeat
end tell
--» Paste the Username and Password
tell application "App Store" to activate
delay 0.5
keystroke theUsername
key code 36
delay 0.5
keystroke thePass
key code 36
set the clipboard to preClip
end tell
end run
on isOPlocked(appName)
tell application "System Events"
tell application process appName
perform action "AXPress" of menu bar item 1 of menu bar 2
set isLocked to (subrole of text field 1 of window 1 is "AXSecureTextField")
delay 0.1
key code 53 -- Escape key to close 1PMini window
if isLocked then return true
return false
end tell
end tell
end isOPlocked
on waitForUnlock(pProcessName, pMaxTimeSec)
local startTime, elapTime, errMsg
set startTime to current application's NSDate's |date|()
tell application "System Events"
repeat
set elapTime to (-(round ((startTime's timeIntervalSinceNow()) * 100)) / 100.0)
if (elapTime > pMaxTimeSec) then return false
try
set roleMode to (subrole of text field 1 of window 1) of (application process pProcessName)
if roleMode is "AXSearchField" then return true
end try
delay 0.1
end repeat
end tell
end waitForUnlock