AppleScript 로 MacOS 단축키 생성하기
MacOS에서 AppleScript와 Automator를 활용하여 단축키를 생성하고 원하는 동작을 간편하게 실행하는 방법을 소개합니다.
Contents
- 개요
 - AppleScript 작성하기
 - Automator 를 이용하여 단축키 등록하기
 - 1. Automator 의 새 Quick Action 생성
 - 2. AppleScript 추가하기
 - 3. Quick Action 저장하기
 - 4. MacOS 단축키 등록하기
 - 정리하며
 
개요
MacOS 에서 별도의 의존성 없이, 가장 많은 권한을 지닌 스크립트 파일을 생성하고 싶다면, AppleScript 를 작성하면 좋습니다. 개인적으로는 AppleScript 를 통해서 다음과 같은 스크립트를 작성하여 사용하고 있습니다.
- 브라우저에서 특정 사이트 열기
 - Jira 가 Chrome 탭에 있다면 활성화하고, 없으면 Chrome 탭을 실행시킨 후 로드하기
 - ChatGPT 가 Chrome 탭에 있다면 활성화하고, 없으면 Chrome 탭을 실행시킨 후 로드하기
 - 특정 어플리케이션 실행하기
 - iTerm2 어플리케이션이 실행중이면 활성화하고, 실행중이지 않다면 실행시키기
 - IntelliJ IDEA 어플리케이션이 실행중이면 활성화하고, 실행중이지 않다면 실행시키기
 
AppleScript 작성하기
위의 사례 중 Slack 어플리케이션을 활성화 시키는 예시 스크립트는 아래와 같습니다.
#!/usr/bin/osascript
tell application "Slack"
    activate
end tell
위의 스크립트를 스크립트화하여 PATH 로 등록하면, 터미널에서 MacOS 의 원하는 동작을 실행시킬 수 있습니다. 그렇다면, 원하는 스크립트를 단축키르 등록하여 실행할 수도 있을까요 ?
Automator 를 이용하여 단축키 등록하기
MacOS 의 Automator 를 이용하면, 별도의 어플리케이션을 설치하지 않고도 단축키를 등록할 수 있습니다. 지금부터는 MacOS 의 automator 어플리케이션을 이용하여 단축키를 등록시키는 방법을 소개하겠습니다.
1. Automator 의 새 Quick Action 생성
워크플로우 앱을 실행한 후, File > New 메뉴를 통해 Quick Action 을 생성합니다.

2. AppleScript 추가하기

Library 의 Run AppleScript 를 선택한 뒤, 위에서 작성한 AppleScript 르 붙여넣습니다. 원한다면 Run 버튼을 눌러 테스트로 스크립트를 실행해 볼 수 있습니다.
3. Quick Action 저장하기

  cmd+S 버튼을 눌러 생성한 Quick Action 을 저장합니다.
4. MacOS 단축키 등록하기
MacOS 의 Settings > Keyboard > Keyboard Shortcuts 메뉴를 클릭합니다. 단축키 등록 모달이 뜨면, Services > General 하위에서 생성한 Quick Action 을 찾아 단축키를 등록합니다.
  기본적으로 Automator 에서 생성한 Workflow 들은 ~/Library/Services 하위에 저장되어 있습니다. 만약 단축키로 등록할 Service 가 보이지 않는다면, 해당 경로에 파일이 있는지 확인해보세요.

정리하며
AppleScript 를 이용하여 MacOS 에서 원하는 동작을 실행시키는 방법을 소개하였습니다. AppleScript 의 간단한 명령어들을 조합하면, 아래와 같은 간단한 Launcher 를 만드는 것도 가능합니다.

#!/usr/bin/osascript
set options to {"Blog", "ChatGPT", "Chrome", "Confluence", "Datadog", "Github", "Gmail", "Google Calendar", "IntelliJ IDEA", "Iterm2", "Jira", "KakaoTalk", "Proxyman", "Screenshot", "Slack"}
set chosenOption to choose from list options with prompt "Select App to Launch :" default items {"Iterm2"}
if chosenOption is not false then
  set selectedOption to item 1 of chosenOption
  if selectedOption is "ChatGPT" then
    openInChrome("https://chatgpt.com")
  end if
  if selectedOption is "Chrome" then
    activateApp("Chrome")
  end if
  if selectedOption is "Confluence" then
    openInChrome("https://test.atlassian.net/wiki/")
  end if
  if selectedOption is "Blog" then
    openInChrome("https://h16rk.im")
  end if
  if selectedOption is "Jira" then
    openInChrome("https://test.atlassian.net/jira")
  end if
  if selectedOption is "Datadog" then
    openInChrome("https://app.datadoghq.com")
  end if
  if selectedOption is "Github" then
    openInChrome("https://github.com/")
  end if
  if selectedOption is "Gmail" then
    openInChrome("https://mail.google.com")
  end if
  if selectedOption is "Calendar" then
    openInChrome("https://calendar.google.com")
  end if
  if selectedOption is "IntelliJ IDEA" then
    activateApp("IntelliJ IDEA")
  end if
  if selectedOption is "Iterm2" then
    activateApp("Iterm2")
  end if
  if selectedOption is "KakaoTalk" then
    activateApp("KakaoTalk")
  end if
  if selectedOption is "Proxyman" then
    activateApp("Proxyman")
  end if
  if selectedOption is "Screenshot" then
    activateApp("Screenshot")
  end if
  if selectedOption is "Slack" then
    activateApp("Slack")
  end if
end if
on activateApp(appName)
  tell Application appName
    activate
  end tell
end activateApp
property targetTab : null
property targetTabIndex : -1
property targetWindow : null
-- 메인 스크립트 호출 함수
on openInChrome(theURL)
    tell application "Google Chrome"
        if (count every window) = 0 then
            make new window
        end if
        -- 1: ChatGPT URL이 열려있는지 찾는다.
        -- 있으면 return
        set found to my lookupTabWithUrl(theURL)
        if found then
            set targetWindow's active tab index to targetTabIndex
            tell targetWindow to activate
            set index of targetWindow to 1
            return
        end if
        -- 2: 빈 탭이 있는지 찾는다.
        -- URL 탭이 없으면 새로 만들어야 한다.
        -- 이 때 빈 탭을 우선적으로 사용한다.
        set found to my lookupTabWithUrl("chrome://newtab/")
        if found then
            set targetWindow's active tab index to targetTabIndex
            set URL of targetTab to theURL
            tell targetWindow to activate
            return
        end if
        -- 3: 새 탭을 만든다.
        -- 열려있는 탭과 비어있는 탭이 둘다 없는 경우
        -- 입력받은 URL로 새 탭을 연다.
        tell window 1
            activate
            make new tab with properties {URL:theURL}
        end tell
    end tell
end openInChrome
-- 공용함수:
-- lookupUrl에 해당하는 크롬 탭을 찾는다.
-- 만약 탭이 있다면 tab, index, window를 property에 저장한다.
-- (properties 는 상단에 선언되어있다.)
on lookupTabWithUrl(lookupUrl)
    tell application "Google Chrome"
        -- lookup...
        set found to false
        set theTabIndex to -1
        repeat with theWindow in every window
            set theTabIndex to 0
            repeat with theTab in every tab of theWindow
                set theTabIndex to theTabIndex + 1
                if (theTab's URL as string) contains lookupUrl then
                    -- assign properties
                    set targetTab to theTab
                    set targetTabIndex to theTabIndex
                    set targetWindow to theWindow
                    set found to true
                    exit repeat
                end if
            end repeat
            if found then
                exit repeat
            end if
        end repeat
    end tell
    return found
end lookupTabWithUrl
            
            이것도 읽어보세요