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

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")'

Related

What app needs to be whitelisted in OSX's Security&Privacy Accessibility list, so that my bash script can send keystrokes?

I am writing a simple (haha) bash script that will send keystrokes to an app. It uses the osacript command line to do this, like so:
osascript <<EOSCRIPT
activate application "Mini vMac"
tell application "System Events" to keystroke "a"
EOSCRIPT
When this script is run, it does bring the app to the front, but then I get the following error:
77:90: execution error: System Events got an error: osascript is not allowed to send keystrokes. (1002)
I have tried whitelisting /usr/bin/osascript but other search results suggest that it doesn't want this. The bash script itself is unselectable (which doesn't necessarily mean that it doesn't want it, just that I can't check).
How do I force it to let me run this? 10.14.6 Mojave if it matters.
I don't have Mini vMac; however, on macOS Mojave 10.14.6, the following example AppleScript code should work to send a keystroke, assuming a Mini vMac window is open, and Terminal is given permission in: System Preferences > Security & Privacy > Privacy > Accessibility
osascript -e 'activate app **Mini vMac**' -e 'delay 0.25' -e 'tell app "System Events" to keystroke "a"'
Note: The example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

Applescript Notifications with Buttons

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)

Perform actions when background image changed on Mac

Is there any way to listen to, and trigger actions when user right click and click change desktop background OR when the background image is actually changed on OSX?
You can get the current desktop image in the shell like this:
osascript -e 'tell app "finder" to get posix path of (get desktop picture as alias)'
I presume, if you really wanted to, you could create a launchd script with launchctl and a corresponding plist to check every minute or so to see if it has changed and then do something...

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.

Resources