Example of NSStatusBar, NSMenu and NSMenuItem

Simple example of NSStatusBar, NSMenu and NSMenuItem to perform action…
If you make a applet you need to add things in the info.plist
LSUIElement

It makes the icon of dock to be hidden, and in the script we use if statement to tell me to quit

Ps. If you use Script Debugger you could change in the script.

The script could be run directly from Script Editor.

use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions

(** add to info.plist in the applet
* <key>LSUIElement</key>
* <true/>
*)

property itemStatus : missing value

on run
	set arguments to {"Action 1", "|", "Action 2", "|", "Action 3", "|", "Action 4", "|", "Action 5", "|", "Action 6", "|", "Action 7", "|", "Quit"}
	if my NSThread's isMainThread() as boolean then
		my performMenuStatusbar:arguments
	else
		my performSelectorOnMainThread:"performMenuStatusbar:" withObject:arguments waitUntilDone:true
	end if
end run

on performMenuStatusbar:arguments
	set menuList to arguments
	set theMenu to createMenu(menuList)
	set itemStatus to (current application's NSStatusBar's systemStatusBar())'s statusItemWithLength:(current application's NSVariableStatusItemLength)
	itemStatus's setTitle:"Action Menu"
	itemStatus's setHighlightMode:true
	itemStatus's setMenu:theMenu
end performMenuStatusbar:

on createMenu(menuList)
	set theMenu to current application's NSMenu's alloc()'s init()
	set theCount to 1
	repeat with i in menuList
		if (contents of i) as string is not "|" then
			set menuItem to (current application's NSMenuItem's alloc()'s initWithTitle:(contents of i) action:"actionHandler:" keyEquivalent:"")
		else
			set menuItem to current application's NSMenuItem's separatorItem()
		end if
		(menuItem's setTarget:me)
		(menuItem's setTag:theCount)
		(theMenu's addItem:menuItem)
		if (contents of i) as string is not "|" then
			set theCount to theCount + 1
		end if
	end repeat
	return theMenu
end createMenu

on actionHandler:sender
	set menuTitle to title of sender as string
	
	if menuTitle is "Quit" then
		current application's NSStatusBar's systemStatusBar()'s removeStatusItem:itemStatus
		if (name of current application) is not "Script Editor" then
			tell me to quit
		end if
	else if menuTitle is "Action 1" then
		display dialog "This is action 1..."
	else if menuTitle is "Action 2" then
		display dialog "This is action 2..."
	else if menuTitle is "Action 3" then
		display dialog "This is action 3..."
	else if menuTitle is "Action 4" then
		display dialog "This is action 4..."
	else if menuTitle is "Action 5" then
		display dialog "This is action 5..."
	else if menuTitle is "Action 6" then
		display dialog "This is action 6..."
	else if menuTitle is "Action 7" then
		display dialog "This is action 7..."
	end if
end actionHandler:

I update other script here on macscripter:
https://www.macscripter.net/viewtopic.php?pid=196609#p196609

This one include subMenu and 4 actions and some useful logging.

Could be run directly in Script Editor or as applet…

use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions

(** add to info.plist in the applet
* <key>LSUIElement</key>
* <true/>
*)

property theStatusItem : missing value

on run
	set theStatusBar to showStatusBar given arguments:{"ActionGroup 1", {"Action 1", "Action 2"}, "ActionGroup 2", {"Action 3", "Action 4"}, "", "Quit"}
end run

on showStatusBar given arguments:arguments
	if my NSThread's isMainThread() as boolean then
		my performMenuStatusbar:arguments
	else
		my performSelectorOnMainThread:"performMenuStatusbar:" withObject:arguments waitUntilDone:true
	end if
end showStatusBar

on performMenuStatusbar:arguments
	set menuList to arguments as list
	set theMenu to createMenu(menuList)
	set theStatusBar to createStatusBar("Action", theMenu)
end performMenuStatusbar:

on createStatusBar(theTitle, menuList)
	-- Returns the system-wide status bar located in the menu bar.
	set theStatusBar to current application's NSStatusBar's systemStatusBar()
	-- A status item length that dynamically adjusts to the width of its contents.
	set theStatusItem to theStatusBar's statusItemWithLength:(current application's NSVariableStatusItemLength)
	theStatusItem's setTitle:theTitle
	theStatusItem's setImage:(current application's NSImage's imageNamed:(current application's NSImageNameActionTemplate))
	theStatusItem's setHighlightMode:true
	log theStatusItem's |description|() as text
	theStatusItem's setMenu:menuList
	log theStatusItem's button()'s |description|() as text
	log theStatusItem's |menu|()'s |description|() as text
	return theStatusItem
end createStatusBar

on createMenu(menuList)
	set theMenu to current application's NSMenu's alloc()'s init()
	set {theCount, prevMenuItem} to {10, ""}
	
	repeat with i in menuList
		if (contents of i) is equal to "" then
			set theMenuItem to (current application's NSMenuItem's separatorItem())
			(theMenu's addItem:theMenuItem)
			
		else if ((class of (contents of i)) as string) = "list" then
			--Generate Submenu
			set subMenu to current application's NSMenu's alloc()'s init()
			(theMenuItem's setSubmenu:subMenu)
			set subCounter to 1
			
			repeat with j in (contents of i)
				set subMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:(contents of j) action:"actionHandler:" keyEquivalent:"")
				(subMenuItem's setTarget:me)
				(subMenuItem's setTag:(theCount + subCounter))
				(subMenu's addItem:subMenuItem)
				set subCounter to subCounter + 1
			end repeat
		else
			set theMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:(contents of i) action:"actionHandler:" keyEquivalent:"")
			(theMenuItem's setTag:theCount)
			(theMenuItem's setTarget:me)
			(theMenu's addItem:theMenuItem)
			set theCount to theCount + 10
			copy theMenuItem to prevMenuItem
		end if
	end repeat
	return theMenu
end createMenu

on actionHandler:sender
	set menuTitle to title of sender as string
	
	if menuTitle is "Quit" then
		current application's NSStatusBar's systemStatusBar()'s removeStatusItem:theStatusItem
		if (name of current application) is not "Script Editor" then
			tell me to quit
		end if
	else if menuTitle is "Action 1" then
		display dialog "This is action 1..."
	else if menuTitle is "Action 2" then
		display dialog "This is action 2..."
	else if menuTitle is "Action 3" then
		display dialog "This is action 3..."
	else if menuTitle is "Action 4" then
		display dialog "This is action 4..."
	end if
end actionHandler:

If we like to run script with paramers… we could do something like this…

Make AppleScript with name: scriptToRun.scpt and save it to desktop.

on run {input, parameters}
	display dialog "My running script from menu status bar with: " & parameters
end run

Now open the script below and run…

EDIT: 210707 Have clean-up the original code and add a separator character for menu and submenu.

use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions

(** add to info.plist in the applet
* <key>LSUIElement</key>
* <true/>
**
* on run {input, parameters}
*	display dialog "My running script from menu status bar with: " & parameters
* end run
*)

property theStatusItem : missing value

on run
	set theStatusBar to showStatusBar given arguments:{"Action Group 1", {"Action 1", "|", "Action 2", "Action 3", "Action 4"}, "Action Group 2", {"Action 5", "|", "Action 6"}, "|", "Quit"}
end run

on showStatusBar given arguments:arguments
	if my NSThread's isMainThread() as boolean then
		my performMenuStatusbar:arguments
	else
		my performSelectorOnMainThread:"performMenuStatusbar:" withObject:arguments waitUntilDone:true
	end if
end showStatusBar

on performMenuStatusbar:arguments
	set menuList to arguments as list
	set theMenu to createMenu(menuList, "|")
	set theStatusBar to createStatusBar("Action", theMenu)
end performMenuStatusbar:

on createStatusBar(theTitle, menuList)
	-- Returns the system-wide status bar located in the menu bar.
	set theStatusBar to current application's NSStatusBar's systemStatusBar()
	-- A status item length that dynamically adjusts to the width of its contents.
	set theStatusItem to theStatusBar's statusItemWithLength:(current application's NSVariableStatusItemLength)
	theStatusItem's setTitle:theTitle
	theStatusItem's setImage:(current application's NSImage's imageNamed:(current application's NSImageNameActionTemplate))
	theStatusItem's setHighlightMode:true
	log theStatusItem's |description|() as text
	theStatusItem's setMenu:menuList
	log theStatusItem's button()'s |description|() as text
	log theStatusItem's |menu|()'s |description|() as text
	return theStatusItem
end createStatusBar

on createMenu(menuList, seperator)
	set theMenu to current application's NSMenu's alloc()'s init()
	set theCount to 1
	
	repeat with i in menuList
		if (contents of i) as string is seperator then
			set theMenuItem to (current application's NSMenuItem's separatorItem())
			(theMenu's addItem:theMenuItem)
			
		else if ((class of (contents of i)) as string) = "list" then
			--Generate Submenu
			set subMenu to current application's NSMenu's alloc()'s init()
			(theMenuItem's setSubmenu:subMenu)
			
			repeat with j in (contents of i)
				if (contents of j) as string is seperator then
					set theMenuItem to (current application's NSMenuItem's separatorItem())
					(subMenu's addItem:theMenuItem)
				else
					set subMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:(contents of j) action:"actionHandler:" keyEquivalent:"")
					(subMenuItem's setTarget:me)
					(subMenuItem's setTag:theCount)
					(subMenu's addItem:subMenuItem)
				end if
			end repeat
		else
			set theMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:(contents of i) action:"actionHandler:" keyEquivalent:"")
			(theMenuItem's setTag:theCount)
			(theMenuItem's setTarget:me)
			(theMenu's addItem:theMenuItem)
			set theCount to theCount + 1
		end if
	end repeat
	return theMenu
end createMenu

on actionHandler:sender
	set menuTitle to title of sender as string
	
	if menuTitle is "Quit" then
		current application's NSStatusBar's systemStatusBar()'s removeStatusItem:theStatusItem
		if (name of current application) is not "Script Editor" then
			tell me to quit
		end if
	else if menuTitle is "Action 1" then
		run script POSIX path of (path to desktop) & "scriptToRun.scpt" with parameters {"", "Action 1"}
	else if menuTitle is "Action 2" then
		run script POSIX path of (path to desktop) & "scriptToRun.scpt" with parameters {"", "Action 2"}
	else if menuTitle is "Action 3" then
		run script POSIX path of (path to desktop) & "scriptToRun.scpt" with parameters {"", "Action 3"}
	else if menuTitle is "Action 4" then
		run script POSIX path of (path to desktop) & "scriptToRun.scpt" with parameters {"", "Action 4"}
	else if menuTitle is "Action 5" then
		run script POSIX path of (path to desktop) & "scriptToRun.scpt" with parameters {"", "Action 5"}
	else if menuTitle is "Action 6" then
		run script POSIX path of (path to desktop) & "scriptToRun.scpt" with parameters {"", "Action 6"}
	end if
end actionHandler: