Action buttons applescript functions - notifications

I am trying to make an AppleScript which creates a notification when I receive a specific email.
Rules are set up, and I have a script which launches an app with the following code:
display notification "A newBuild is now available!" with title "New Build"
tell application "Safari"
activate
tell window 1
set current tab to (make new tab with properties URL:"https://latestSuccessful")
end tell
tell application "System Events"
set visible of process "Safari" to true
end tell
end tell
This launches safari and take to the the web page as soon as the notification is displayed.
Ideally I would display the notification as an Alert, with an action on the 'Show' button which then takes me to the web page. The 'Close button' naturally closes the alert.
Is this possible? Thanks in advance for any pointers.

Do you mean something like this?
set alertReply to display alert "New Build" message "A new build is now available!" buttons ["Cancel", "Show"] default button 2 giving up after 5
if button returned of alertReply is equal to "Show" then
tell application "Safari"
activate
tell window 1
set current tab to make new tab with properties {URL:"http://www.google.com"}
end tell
end tell
end if

Notifications with action buttons are not possible in AppleScript,
because AppleScript can't handle the callbacks.

You can definitely do this! You'll have to install Growl for this. It used to be free, but costs $4 now. It's a pretty damn good long-term investment in my opinion, and it'll allow you to do awesome things with notifications in AppleScript. The code to use once it's installed is this:
set notifications to {"EMailNotify"}
tell application "Growl"
register as application "AppleScript App" all notifications notifications default notifications notifications
notify with name "EMailNotify" title "E-Mail received!" description "it's here!" application name "AppleScript App" callback URL "http://www.apple.com/"
end tell
Keep in mind that you must use one of the notification names in the list on the first line, as the name for the notification on the fourth line, and you must use the same application name that you register the application with on the third line, as the "application name" on the fourth line. Growl lets you specify a callback URL as an argument, which should get you exactly what you're looking for!
Keep in mind that you can configure Growl to use OS X notifications in order to get exactly what you were looking for, but Growl's notifications are far more customizable.

Related

How can I activate a specific window (but not all window) at specific app in Cocoa apps?

I am trying to create a OS X app which manages windows to switch them.
But I cannot find a appropriate solution to activate a specific window.
I found these way.
Using AppleScript.
Specifing window by window title or window number.
However, if a window has same window title of other window, the activating is not working correctly.
-- For example, this script activate Google Chrome's second window
tell application "System Events"
tell process "Google Chrome"
set thewindow to window 2
tell thewindow
perform action "AXRaise"
end tell
set frontmost to true
end tell
end tell
Using NSApplicationActivateIgnoringOtherApps.
However, this way cannot specify a window.
NSRunningApplication* app = [NSRunningApplication runningApplicationWithProcessIdentifier: PID];
[app activateWithOptions: NSApplicationActivateIgnoringOtherApps];
Does exist other appropricate way to activate specific window?
Accessibility works fine for this. With AXRaiseWindow & switchToApp you can switch to any window.
Look at: https://github.com/jsuder/WindowFairy/blob/master/WindowManager.m
(Disclaimer: not my code and im not acquainted with the author. just using google)
note: There is also a CGWindowList API that can be used to enum windows but it is being deprecated. AX* stays though

i need an applescript to open safari in full screen an to hide the toolbar on mavericks

I need an applescript to open safari in full screen an to hide the toolbar on mavericks.
it sounds easy but it isnt!
i need to open safari then open google in full screen mode an then hide the toolbar.
it would be the equivilent to the below sample but instead for safari
tell application "Google Chrome"
open location "http://internet.ceo.wa.edu.au/Pages/default.aspx"
end tell
tell application "Google Chrome" to activate
tell application "System Events"
keystroke "f" using {command down, shift down}
end tell
Could be simple as this:
tell application "Safari"
activate
if (count of windows) is 0 then -- Remove "if" statement if you don't want to make a new window if there is none
make new document at front
end if
tell application "System Events" to keystroke "f" using {command down, control down}
end tell
Not sure if you can make it with no toolbar at all.
Update 4/4
not sure what you can do with it but look into this program. If it works the way you want. Add a system events to use the drop downs to select the item.
The Barbarian Group has a freeware app called "Plainview", which seems to be just a wrapper around Webkit. It works as a "Fullscreen kiosk-style presentation content viewer", similar to what Chrome presentation mode does.
Anyways, it's a free download, so no risk in trying. Scroll almost to the bottom of this page:
http://barbariangroup.com
Direct download:
http://s3.amazonaws.com/plainviewapp/plainview_1.0.178.zip
Easy way:
set MyApps to {"Google Chrome", "Skype", "Finder"}
repeat with MyApp in MyApps
tell application MyApp
activate
delay 3
tell application "System Events" to tell process MyApp
set value of attribute "AXFullScreen" of window 1 to true
end tell
end tell
end repeat

Cocoa application contains no menu bars, according to AppleScript

I am creating a mac app that needs to start dictation (OSX 10.8) by itself. Because there is no way to initiate dictation "directly" the best way to do this is through the menu bar "Edit"/"Start Dictation" because a user may have different keyboard shortcuts for it.
Here's the simple script my app calls (using an NSAppleScript object):
tell application "System Events"
tell application process "MyApp"
tell menu bar 1
tell menu bar item "Edit"
tell menu "Edit"
click menu item "Start Dictation"
end tell
end tell
end tell
end tell
end tell
Here are the results (NSLog'd the error from the AppleScript)
Error:-1719 System Events got an error:
Can’t get menu bar 1 of application process "MyApp". Invalid index.
I did a basic test to see what was going on
My App:
tell application "System Events"
tell application process "MyApp"
set x to menu bars
return x
end tell
end tell
result: <NSAppleEventDescriptor: [ ]>
Finder:
tell application "System Events"
tell application process "Finder"
set x to menu bars
return x
end tell
end tell
result: <NSAppleEventDescriptor: [ 'obj '{ 'form':'indx', 'want':'mbar', 'seld':1, 'from':'obj '{ 'form':'name', 'want':'pcap', 'seld':'utxt'("Finder"), 'from':null() } } ]>
So basically AppleScript is telling me my app has no menu bars? I run Accessibility Inspector and sure enough there is in fact a menu bar (plus I can see it...).
What's going wrong here?
I was after something similar, I wanted to activate a service from within Emacs which had otherwise overridden the global keyboard shortcut to the service - A different question which I will ask in another thread.
Running your examples above I did discover that I had to have added the application (Emacs and for testing Automator) to the Accessibility applications (System Preferences -> Security & Privacy -> Privacy -> Accessibility). Further information regarding that on select-a-menu-item-in-applescript-without-using-system-events-in-10-9-maverick and also AppleScript - uiscripting.
With that access in place I am able to see the menu items under services:
tell application "Emacs"
activate
end tell
tell application "System Events"
tell application process "Emacs"
tell menu bar 1
tell menu "Emacs"
tell menu item "Services"
tell menu "Services"
set x to menu items
click menu item "XXX"
return x
end tell
end tell
end tell
end tell
end tell
end tell
But the action is not activated!
Using the example above an error is returned that 'XXX' does not exist. Replacing the string with the correct string means no error occurs, but the action does not take place.
Have you tried activating your app with a short delay before running the system events stuff? You're also missing some other stuff. Here's how you would do it in Safari...
tell application "Safari" to activate
delay 1
tell application "System Events"
tell process "Safari"
tell menu bar item "Edit" of menu bar 1
click
delay 0.5
tell menu item "Speech" of menu 1
click
delay 0.5
click menu item "Start Speaking" of menu 1
end tell
end tell
end tell
end tell
A second point. If you are creating the application yourself then you do not need to do as you are suggesting. You state "Because there is no way to initiate dictation directly" but why do you say that? Every menu item is hooked up to a command, so in essence you can hook into that command if this is your own application. Just create a button or something in your interface and connect it to the same command that the menu item is connected to. For example I can see in Xcode that the "Start Speaking" menu item is connected to First Responder's startSpeaking command. As such you can create a button or some other item and connect it to startSpeaking of First Responder in Interface builder yourself.

How to enter password for prompt windows using applescript

I'm new to applescript and is currently stuck in access the prompt window asking for my password.
I'm creating a launcher for my daily use application and i want to automate the launching process.
Right now, I'm only launching two application, VirtualHostX and MAMP. Later I might add few some.
Here's what I done so far:
tell application "VirtualHostX" to activate
tell application "MAMP" to activate
tell application "System Events"
tell process "VirtualHostX"
tell menu bar 1
tell menu bar item "Web Server"
tell menu 1
click menu item "Start"
end tell
end tell
end tell
end tell
end tell
When launching, It will launch the two application successfully, but Virtual Host will ask me for my password for authorization. I want to integrate entering my password in the flow or code. I already tried to google for answer but failed to find a solution for it.
I can't seem to target that window and enter my password.
Let me know what am I missing.
Thank You.
Password dialogs are shown by SecurityAgent:
tell application "System Events" to tell process "SecurityAgent"
set value of text field 2 of scroll area 1 of group 1 of window 1 to "password"
click button 2 of group 2 of window 1
end tell
For Yosemite, the SecurityAgent dialog box is different. This will work:
tell application "System Events"
tell process "SecurityAgent"
set value of text field 2 of window 1 to "yourPassword"
click button 2 of window 1
end tell
end tell

Turn Bluetooth off and on programmatically

Is there a way to programmatically turn on and off the Bluetooth connection on OSX in a way that will be accepted by the Mac App Store?
From my previous question, I've found about blueutil, but it uses private APIs.
It would be somewhat surprising if Apple approved an app that modified the user's antenna settings. It sounds like the kind of thing they typically frown on, no matter how you do it. But then, sometimes I get surprised.
You can definitely do it through Applescript:
tell application "System Preferences"
set current pane to pane "com.apple.preferences.Bluetooth"
tell application "System Events"
tell process "System Preferences"
set isOnCheckbox to checkbox "On" of window "Bluetooth"
if value of isOnCheckbox is 0 then
click isOnCheckbox
end if
end tell
end tell
quit
end tell
Note that this will take over System Preferences and at the end close it even if the user was running it. That's not the best user experience, and I definitely wouldn't do it without first warning the user. But of course, I wouldn't recommend modifying the bluetooth settings without warning the user.
EDIT
Because you asked, I'll take a moment to rant here....
Regarding how to learn to read and write the above, first note that it, like most AppleScript I write professionally, was cobbled together from google searches and experimentation. I'm a purist programmer at heart, and I believe in really understanding the technology you use. Even I cobble together things in AppleScript until they "kind of work."
I wish there were a really good document. Of course there's the language guide, but it's kind of like learning Cocoa from the ObjC language definition. My current recommendations are Beginning AppleScript and then AppleScript: The Definitive Guide. Neuburg in particular does not sugarcoat the language or pretend that it makes sense. Applescript, even worse than the original COBOL (ADD X TO Y GIVING Z), is very hard to write because it tries so hard to be easy. I love and respect many languages. AppleScript is crap.
It is, however, the most supported way to interact with most of the Mac system functions, so a good Mac developer needs to at least be able to get by in it. Even if you use the new ScriptingBridge via ObjC (or MacRuby), the underlying object model is still AppleScript based. In my experience, to get ScriptingBridge code to work well, you generally have to write it first in AppleScript and then translate it into Cocoa.
This worked for me in 10.15.6, I might have over complicated my solution which is running script 1 (turn bluetooth off) and then script 2 (turn bluetooth on).
Script 1. This is for turning bluetooth OFF
tell application "System Events" to tell process "SystemUIServer"
tell (menu bar item 1 of menu bar 1 where description is "bluetooth")
click
click menu item "Turn Bluetooth Off" of menu 1
end tell
tell window 1
click button "Turn Bluetooth Off"
end tell
end tell
Script 2. This is for turning bluetooth ON
tell application "System Events" to tell process "SystemUIServer"
tell (menu bar item 1 of menu bar 1 where description is "bluetooth")
click
click menu item "Turn Bluetooth On" of menu 1
end tell
end tell
So I execute one command which will run one script after the other, the sleep is for the UI to update properly.
osascript bluetooth_off.scpt && sleep 3s && osascript bluetooth_on.scpt
You can just save the command in a file and execute it using: (they have to be in the same directory).
~ bash <fileName>
Note: You will need to give access to the terminal on Preferences > Security & Privacy