Applescript Notifications with Buttons - terminal

Notification Alerts are fairly easy to program in Applescript:
osascript -e 'display notification "notification text content" with title "Alert!" sound name "Purr"'.
However i am yet to find an internet page or StackOverflow question which explains how to program them with buttons, similar to the type which appears when the App Store pesters you to upgrade to OS X Yosemite. In addition, the syntax would be used through the command osascript -e.
How do i program an Applescript alert through the notification centre with buttons?
Thanks in Advance.

The display notification command of Standard Additions provides only the parameters sound name, subtitle, with title and the body of the notification as direct parameter because it's not possible to handle the callbacks when the user presses a button in the AppleScript runner environment.

You can go to Preferences > Notifications, and scroll the applications to find the application Script Editor which is the application that sends the notification when you execute osascript -e '...'. Select Alerts as the alert style and you are all set!

Documentation is pretty clear here
Notifications are shown as alerts or banners, depending on the user’s settings in System Preferences > Notifications
But it doesn't provide an example code to catch the button clicked. (if you try it just opens the applescript editor)

Related

Add "Close" button to macOS notifications

I'm using a plugin for my shell that displays a notification when a long running command has completed. To do this on macOS, it's using AppleScript:
osascript -e "display notification \"$message\" with title \"$title\""
When this notification pops up, it has to time out to disappear; I cannot dismiss it.
This blocks me often as it covers my browser tabs in the top right of the screen.
I've seen similar notifications that have buttons to close them, e.g. Slack message notifications.
How can I add a "Close" button to the notification?
The "Mac Automation Scripting Guide" gives an example of this.
The guide states the difference is determined by your settings.
Notifications are shown as alerts or banners, depending on the user’s settings
To change notification settings to include buttons, go to
System Preferences > Notifications > Script Editor > Alert Style > Alerts
It's unclear how to change the AppleScript command to include the buttons when using the default "banner" notification style. It may be possible as other applications always show their notifications with buttons.
For more info on AppleScript commands and its parameters, (1) launch Script Editor and (2) open the Standard Additions dictionary, then (3) navigate to the command’s definition.
Possibly of interest, there's an open-source command line utility on GitHub, https://github.com/vjeantet/alerter, which allows you to do this, and to specify many more notification options on an alert-by-alert basis. Alerter gives you much more control over alerts than AppleScript's display notification.
Alerter allows you to create an alert with numerous options: a custom icon, custom button labels, up to three different kinds of actions to replace the default "show" button on the alert, a specified application or URL to open when the alert is clicked, a Reply box like when you receive an iMessage, a way to group and remove previously display alerts, and many more.
Alerter can give you complete control over the buttons displayed, per alert, by specifying options in the shell command you enter to create each alert. You can specify apps or urls to open when the alert is clicked, or, if you use multiple options in the alert, your script will have to process the text returned to determine which option was selected.
(Note: https://github.com/julienXX/terminal-notifier is the original project Alerter was forked from. Terminal-notifier includes a few minor extra abilities that Alerter doesn't, but doesn't give you the same control over the buttons. If you want to include a lot more functionality, it might be worth reviewing both projects.)
I'm not involved with Alerter or Terminal-notifier, just a user.
To expand on Dennis' answer:
You can set the style of notification on a per app basis in:
System Preferences > Notifications > Script Editor > Alert Style > Alerts
In the screenshot in his answer he's changing the setting for notifications generated by the 'Script Editor' app.
I had to change it in 'Automator' to get my custom scrips to have close buttons.

Change icon of notification when using osascript -e "display notification"

I'm trying to write a plugin for emacs that displays a notification using OS X's native notification display.
I've run into terminal-notifier which works, but it's a dependency that doesn't work on every mac. Plus the user should be made aware that they need to install the package.
What I want to do is call a process osascript -e and make it display the notification. The problem is, the only way to change its icon is from an external bundle. Is there any way to make osascript -e display what I want.
starting sudo osascript seems to do that, but it seems to be bad design and I also need to find a way to pass the root password every single time.
You cannot. This is simply not a macOS feature exposed to AppleScript.
If you need a custom icon, consider using a pop-up "dialog" rather than a Notification Center pop-up. With timeouts and buttons you can recreate much of the functionality, though not the integration nor aesthetics.
In `display dialog', if you wish to use the standard icons: 0, 1, or 2 (stop, note, or caution), perhaps don't have osascript be the program that displays the icon. Finder, for example:
osascript -e 'tell application "Finder"' -e 'activate' -e 'display dialog \
"this is the note icon." with icon note' -e 'end tell'
or without the tell application… you may use an icon of your choice by referencing it directly, e.g. the Terminal app's icon:
osascript -e 'display dialog "Terminal icon" with icon alias \
"Macintosh HD:Applications:Utilities:Terminal.app:Contents:Resources:Terminal.icns"'
I'm not sure what you mean by, "the only way to change its icon is from an external bundle. Is there any way to make osascript -e display what I want."  What, precisely, do you want? What have you tried?
Here's the display dialog section from Apple's documentation.
Actually, this is possible.
Just save your script as an application and then switch the applet.icns file within the application's Contents/Resources folder for the icon you want.
Any notifications sent from your script will use that icon.
Unfortunately, the "display notification" documentation shows that you can't:
display notification
Posts a notification using the Notification Center, containing a title, subtitle, and explanation, and optionally playing a sound.
Syntax
display notification – text, required
with title – text, optional
subtitle – text, optional
sound name – text, optional
(Even using the tell application "..." trick from https://stackoverflow.com/a/49079025/3528 leaves you with the default notification icon.)
The reason why terminal-notifier can is because it's using the Notification Center APIs directly which, as far as I can tell, osascript doesn't present an interface to.
Best solution for was to:
Create an AppleScript app and replace the applet.icns file, inside the /Contents/Resources folder, with your icon file
create a handler:
on notify(vTxt, vTtl)
display notification vTxt with title vTtl
end notify
Don't forget to create an 'on idle' handler as well:
on idle
return 10
end idle
Save the app as "Stay open"
Run the app
now you can call the handler from another app or process and the notification will display with the icon of your app. Call it from the command line :
osascript -e 'tell application "MyApp" to notify("Message", "TITLE")'

Redirected to applescript editor on clicking apple notification

I am using
osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'
to display notifications in Mac. However, on clicking the notification, I am getting redirected to the applescript editor. Is it possible for me to redirect the user to a url or open up a directory on clicking the notification which is generated?
The run handler will only get called if the script is saved as an app, preferably a stay-open app. In any case, the app has to be still running when someone clicks the notification. You won't get this behavior from a simple osascript string.
You could get osascript to run a compiled script file (which can store properties persistently), but you will still need to distinguish between the run event that happens when you run the script, and the run event that gets called when someone clicks the notification.
I can suggest a couple of solutions here.
Use a python library to fire off notifications and forget about
appleScript/OSA. You can find some information, and various solutions at this
stackoverflow link:
Python post osx notification
Set up a stay-open appleScript app as a kind of 'notification server' and send a message to that (possibly with OSAscript, unless you can send a raw apple event to the 'server' from python) when you want to set up some notification intercourse. This is tricky, and seems overcomplex, compared to my first suggestion. In particular, you may still need to mess about with the privacy settings (especially if on Mavericks or later) to allow OSAscript access to system events.
Here are a couple of links which may guide you with the latter approach, but I really thing the first suggestion will get you further, with fewer tears:
http://jacobsalmela.com/bash-script-enable-access-assistive-devices-programmatically-os-x-mavericks-10-9-x-simulate-keystrokes/
http://support.apple.com/kb/HT6026?viewlocale=en_US&locale=en_US
so yes there is a way to do what you would like
here is a tutorial here
this is a simplified version that does what you like, however you must save it as an application and drag a file on it.
on open theItems
display notification "Open stackoverflow ?" with title "Stackoverflow"
delay 2
end open
on run
tell application "Safari"
tell window 1
set current tab to (make new tab with properties {URL:"http://www.stackoverflow.com"})
end tell
end tell
end run

OS X Mail - Open *.eml-files in compose mode

How can I open *.eml-files in compose mode for Mac OS X Mail? For Outlook "X-Unsent: 1" seems to do the trick, but does not work for Mac OS X Mail still opens in Read-Only.
This is a super old question, but obviously has received a fair number of views. My curiosity piqued, I figured I'd take a look. After some fiddling around, I found you can add the following header to make a message editable:
X-Uniform-Type-Identifier: com.apple.mail-draft
Add that to your otherwise RFC-2822 compliant message, give it a .eml or .emlx extension, and when you double-click it'll open as an editable message in Mail.app.
Have fun.
In macOS Catalina 10.15.7, running the following commands from a Python script worked to open a new message and then switch to compose mode, but there is a race condition between opening the message and putting it in Compose mode if the osascript command runs too quickly. The sleep command is there to prevent the race, but you may need to adjust the length of sleep time to compensate for this. (I also used time.sleep(1) in Python instead of the shell command.)
/usr/bin/open -a Mail path/to/tmp/message.eml
/bin/sleep 1
/usr/bin/osascript -e 'tell application "System Events" to tell application process "Mail"' -e 'keystroke "d" using {command down, shift down}' -e 'end tell'
Note that you must grant access to Terminal to control other apps, or the osascript command will fail with an error. To do that, open System Preferences, click on the Security & Privacy item, click Accessibility from the left menu, click the lock icon to unlock the menu, then check the Terminal item (or add it if not listed) in the "Allow apps to control your computer." list.
Also note that the Cmd-Shift-D keyboard shortcut sends a message that is already in compose mode, so if someone is using Mail at the time the script runs, and they have a separate compose window in the foreground, then the script could send that message instead of putting the new message in compose mode.

Intercepting click on send in Mail.app

Is it possible to intercept click on Send in Mac OS X Mail application?
Thanks
You can, but it won't necessarily be easy. You should be able to inject some code into the program (see for example SIMBL and F-Script Anywhere) and then change the button's target.
Basically it can be done by using Accessibility APIs. I listen to moue click events in my application, so when I get a click I check whether the Mail.app is a frontmost application and whether a click came from Send button UIElement.

Resources