Posted on 11-02-2016 01:53 PM
At Cisco we had a need for a notification system that was more native looking than jamf helper but persistent unlike default Notification Center alerts. This led us to yo.app which is an open source notification alert utility.
By default the binary accepts arguments detailed on the project page linked above, which also means this can be scripted. The owner of the project provides a Python script that is meant for use with Casper but we found it limited in its customization ability. To that end, we wrote our bash script that allows us to create an entire alert as a policy using only script parameters. Those parameters are detailed in the screenshot below.
Here is the script that we use:
#!/bin/bash
yoBinary="/PATH/TO/yo.app/Contents/MacOS/yo"
title=$(printf %q "$4")
subtitle=$(printf %q "$5")
info=$(printf %q "$6")
otherButton=$(printf %q "$7")
actionButton=$(printf %q "$8")
actionPath=$(printf %q "$9")
scriptURL=$(printf %q "${10}")
iconURL=$(printf %q "${11}")
grabConsoleUserAndHome(){
currentUser=$(stat -f %Su "/dev/console")
homeFolder=$(dscl . read "/Users/$currentUser" NFSHomeDirectory | cut -d: -f 2 | sed 's/^ *//'| tr -d '
')
case "$homeFolder" in
* * )
homeFolder=$(printf %q "$homeFolder")
;;
*)
;;
esac
}
downloadIcon()
{
iconURLFile="${iconURL##*/}"
extension="${iconURLFile##*.}"
iconLocal="/tmp/icon."$extension""
rm -f "$iconLocal"
filerConnection=$(/usr/bin/curl -L -s -o /dev/null --silent --head --write-out '%{http_code}' "http://pkg.cloudapps.cisco.com/" --location-trusted -X GET)
if [[ "$filerConnection" = 200 ]]; then
echo "Downloading Icon..."
/usr/bin/curl -L "$iconURL" -o "$iconLocal" --location-trusted
else
echo "Unable to download icon. Skipping..."
fi
}
downloadScript()
{
scriptLocal="/tmp/script.sh"
rm -f "$scriptLocal"
filerConnection=$(/usr/bin/curl -L -s -o /dev/null --silent --head --write-out '%{http_code}' "http://pkg.cloudapps.cisco.com/" --location-trusted -X GET)
if [[ "$filerConnection" = 200 ]]; then
echo "Downloading Script..."
/usr/bin/curl -L "$scriptURL" -o "$scriptLocal" --location-trusted
chmod +x "$scriptLocal"
else
echo "Unable to download script. Exiting..."
exit 1
fi
}
grabConsoleUserAndHome
if [[ "$currentUser" == "root" ]]; then
exit 0
fi
if [[ "$iconURL" != "''" ]]
then
downloadIcon
fi
if [[ "$scriptURL" != "''" ]]
then
downloadScript
fi
IFS=$'
'
if [[ -z $otherButton ]]
then
if [[ -e "$iconLocal" ]] && [[ -e "$scriptLocal" ]]
then
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --action-btn "$actionButton" --icon "$iconLocal" --bash-action "$scriptLocal" -p"
elif [[ -e "$iconLocal" ]]
then
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --action-btn "$actionButton" --action-path "$actionPath" --icon "$iconLocal" -p"
elif [[ -e "$scriptLocal" ]]
then
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --action-btn "$actionButton" --bash-action "$scriptLocal" -p"
else
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --action-btn "$actionButton" --action-path "$actionPath" -p"
fi
else
if [[ -e "$iconLocal" ]] && [[ -e "$scriptLocal" ]]
then
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --other-btn "$otherButton" --action-btn "$actionButton" --icon "$iconLocal" --bash-action "$scriptLocal" -p"
elif [[ -e "$iconLocal" ]]
then
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --other-btn "$otherButton" --action-btn "$actionButton" --action-path "$actionPath" --icon "$iconLocal" -p"
elif [[ -e "$scriptLocal" ]]
then
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --other-btn "$otherButton" --action-btn "$actionButton" --bash-action "$scriptLocal" -p"
else
su - "$currentUser" -c "$yoBinary --title "$title" --subtitle "$subtitle" --info "$info" --other-btn "$otherButton" --action-btn "$actionButton" --action-path "$actionPath" -p"
fi
fi
unset IFS
exit 0
Let me know if this proves useful for you or if you have any comments, suggestions.
Posted on 11-02-2016 03:13 PM
Thanks for this - definitely bookmarking and will take a look when I'm able!
Matt
Posted on 11-03-2016 01:16 PM
Very cool. Thanks for posting!
Posted on 11-03-2016 10:58 PM
Thanks mate, will check it out!
Posted on 11-04-2016 11:25 AM
As an update for those that want a preview this is what the alerts look like.
Standard icon from when you built the project with Xcode:
Custom icon set with the policy:
We occasionally have a need to track if people click the action button so for that we assign a script to the action button even if just opening a URL. (Note, though, any script called by the action button will run as the user.) This allows us to write a marker file on the system to grab with an EA.
#!/bin/bash
grabConsoleUserAndHome(){
currentUser=$(stat -f %Su "/dev/console")
homeFolder=$(dscl . read "/Users/$currentUser" NFSHomeDirectory | cut -d: -f 2 | sed 's/^ *//'| tr -d '
')
case "$homeFolder" in
* * )
homeFolder=$(printf %q "$homeFolder")
;;
*)
;;
esac
}
grabConsoleUserAndHome
mkdir -p "$homeFolder"/PATH/TO/Attributes
touch "$homeFolder"/PATH/TO/Attributes/.attributegoeshere
echo "true" > "$homeFolder"/PATH/TO/Attributes/.attributegoeshere
open URLGOESHERE
Posted on 01-16-2017 08:48 PM
just wanted to say thanks @iJake, i've been using your script in testing and found it to be a reliable way to invoke yo.app using JAMF policies. much appreciated!
Posted on 01-17-2017 07:05 AM
@davidhiggs Happy to hear you're using it and glad to help!