ch08. AppleScript 연동 -- Finder, Google Meet 셋업
AppleScript로 macOS 앱을 제어하고, Chrome에서 JavaScript를 실행하여 Google Meet 미팅 환경을 자동화한다.
이런 불편함, 겪어보셨나요?
Finder에서 새 텍스트 파일을 만들고 싶을 때가 있습니다. Windows에서는 마우스 오른쪽 버튼을 누르면 "새로 만들기 > 텍스트 문서"가 있습니다. macOS에는 이 기능이 없습니다. TextEdit을 열고, 저장 경로를 찾아가고, 파일 이름을 정하는 과정을 매번 거쳐야 합니다.
Google Meet 미팅도 마찬가지입니다. 접속하면 마이크 끄기, 카메라 끄기, 자막 켜기를 매번 수동으로 해야 합니다. 미팅이 잦으면 같은 동작을 하루에도 여러 번 반복합니다. 자료 공유를 시작하거나 중지할 때도 메뉴를 찾아 클릭해야 합니다.
이 챕터에서는 AppleScript와 셸 스크립트를 조합하여 Finder를 제어하는 방법과, AppleScript와 JavaScript를 조합하여 Google Meet 미팅 환경을 자동 설정하는 방법을 배웁니다.
그룹 1: Finder 매크로
매크로 분석: New text file
무엇을 하는 매크로인가
Finder에서 현재 열려 있는 폴더에 "제목없음.md" 파일을 생성합니다. 같은 이름의 파일이 있으면 "제목없음1.md", "제목없음2.md"처럼 숫자를 붙여 중복을 방지합니다. 파일 생성 후 Finder에서 해당 파일을 선택하고, 이름 변경 모드로 전환합니다.
트리거
| 트리거 타입 | 값 | 설명 |
|---|---|---|
| HotKey | ⌃N | Finder가 활성화된 상태에서만 동작 |
액션 흐름
그림 8-1. New text file 매크로 흐름도
- ExecuteAppleScript -- Finder의 현재 창 경로를 가져옵니다. 창이 없으면 데스크탑 경로를 사용합니다. 결과를
LocalPath변수에 저장합니다. - ExecuteShellScript --
LocalPath경로에서 "제목없음.md" 파일을 생성합니다. 동일 이름이 있으면 숫자를 붙여 고유한 파일명을 만듭니다. 생성된 파일명을LocalNewFileName변수에 저장합니다. - File (Reveal) --
%Variable%LocalPath%/%Variable%LocalNewFileName%경로의 파일을 Finder에서 선택합니다. - SimulateKeystroke ⌃, -- Finder의 이름 변경 모드를 활성화합니다. 사용자가 바로 파일명을 입력할 수 있습니다.
핵심 기술 해설
AppleScript로 Finder 경로 가져오기
이 매크로의 첫 번째 액션은 AppleScript입니다.
tell application "Finder"
try
set myWin to window 1
set myPath to (POSIX path of (target of myWin as alias))
on error
set myPath to (POSIX path of (path to desktop))
end try
end tell
return myPath
tell application "Finder" 구문으로 Finder에 명령을 보냅니다.
window 1은 가장 앞에 있는 Finder 창입니다.
target of myWin은 그 창이 보여주는 폴더입니다.
POSIX path of는 macOS 경로를 /Users/... 형식의 UNIX 경로로 변환합니다.
try ... on error 구문은 오류 처리입니다.
Finder 창이 하나도 없으면 window 1에서 오류가 발생합니다.
이 경우 데스크탑 경로를 기본값으로 사용합니다.
KM의 ExecuteAppleScript 액션에서 return 값은 지정한 변수에 저장됩니다.
이 매크로에서는 결과를 LocalPath 변수에 저장하도록 설정되어 있습니다.
셸 스크립트로 파일 생성하기
두 번째 액션은 셸 스크립트입니다.
#!/bin/bash
dir="$KMVAR_LocalPath"
base="제목없음"
ext=".md"
filename="$base$ext"
i=1
# 파일이 이미 존재하면 숫자를 1씩 늘려가며 빈 이름 찾기
while [ -e "$dir/$filename" ]; do
filename="${base}${i}${ext}"
((i++))
done
# 파일 생성
touch "$dir/$filename"
# 생성된 파일 이름 출력 (KM 변수로 저장됨)
echo -n "$filename"
$KMVAR_LocalPath는 KM 변수를 셸 스크립트에서 참조하는 방법입니다.
KM은 모든 변수를 KMVAR_ 접두어를 붙여 환경 변수로 노출합니다.
AppleScript에서 저장한 LocalPath 값을 셸 스크립트에서 바로 사용할 수 있습니다.
while 반복문은 같은 이름의 파일이 있는지 확인합니다.
있으면 숫자를 붙여가며 빈 이름을 찾습니다.
echo -n의 출력 결과는 LocalNewFileName 변수에 저장됩니다.
AppleScript와 셸 스크립트의 역할 분담
이 매크로는 AppleScript와 셸 스크립트를 조합합니다. AppleScript는 macOS 앱(Finder)과 대화하는 데 강합니다. 셸 스크립트는 파일 시스템 조작에 강합니다. 각 스크립트의 장점을 살려서 역할을 나눈 구조입니다.
활용 팁
ext변수를.txt나.py로 바꾸면 다른 형식의 파일도 생성할 수 있습니다.base변수를 날짜 형식($(date +%Y%m%d))으로 바꾸면 날짜 기반 파일명이 됩니다.- Finder 그룹의 Available in 설정에서 Finder만 선택하면, 다른 앱에서는 ⌃N이 원래 동작을 유지합니다.
매크로 분석: settings - default
무엇을 하는 매크로인가
Finder의 기본 보기 설정을 적용합니다. 서브매크로 두 개를 순서대로 호출하는 구조입니다.
트리거
| 트리거 타입 | 값 | 설명 |
|---|---|---|
| HotKey | ⌘2 | Finder가 활성화된 상태에서만 동작 |
액션 흐름
- SetActionDelay -- 액션 간 딜레이를 설정합니다.
- ExecuteMacro -- 첫 번째 서브매크로를 실행합니다.
- ExecuteMacro -- 두 번째 서브매크로를 실행합니다.
핵심 기술 해설
서브매크로 호출 (ExecuteMacro)
KM에서는 매크로 안에서 다른 매크로를 호출할 수 있습니다.
ExecuteMacro 액션이 그 역할을 합니다.
반복적으로 사용하는 동작을 별도 매크로로 분리하면, 여러 곳에서 재사용할 수 있습니다.
이 매크로는 Finder의 보기 설정을 두 단계로 나누어 처리합니다. 각 단계가 독립적인 서브매크로로 분리되어 있어서, 다른 매크로에서도 개별적으로 호출할 수 있습니다.
서브매크로 패턴은 ch11에서 더 자세히 다룹니다.
활용 팁
- Finder의 보기 옵션(리스트, 아이콘, 컬럼, 갤러리)마다 별도의 설정 매크로를 만들 수 있습니다.
⌘1,⌘2,⌘3등 Finder 기본 보기 전환 단축키와 결합하면 보기 전환과 동시에 설정을 적용할 수 있습니다.
그룹 2: Google Meet 매크로
Google Meet 관련 매크로는 다섯 개입니다. 모두 Chrome 그룹에 속하며, Chrome이 활성화된 상태에서만 동작합니다. 셋업 매크로를 중심으로, 미팅 종료, 팔레트 표시, 자료 공유/중지까지 미팅의 전 과정을 자동화합니다.
매크로 분석: Google meet - 셋업
무엇을 하는 매크로인가
Google Meet에 접속한 후 미팅 환경을 자동으로 설정합니다. 시스템 사운드를 음소거하고, 마이크를 끄고, 카메라를 끄고, 자막을 켭니다. AppleScript, 조건 분기, 키보드 단축키, JavaScript를 모두 사용하는 복합 매크로입니다.
트리거
| 트리거 타입 | 값 | 설명 |
|---|---|---|
| (없음) | -- | 팔레트에서 호출하거나 다른 매크로에서 서브매크로로 실행 |
액션 흐름
그림 8-2. Google Meet 셋업 매크로 흐름도
- SetActionDelay -- 액션 간 딜레이를 0.1초로 설정합니다.
- Comment -- "System sound mute all" 메모입니다.
- ExecuteAppleScript --
output muted of (get volume settings)를 실행하여 현재 음소거 상태를mute_yn변수에 저장합니다. - IfThenElse --
mute_yn변수가false(음소거 아닌 상태)이면 시스템 사운드를 음소거합니다. 이미 음소거 상태면 아무것도 하지 않습니다. - Comment -- "마이크 끄기 단축어 (Command + D)" 메모입니다.
- SimulateKeystroke ⌘D -- Google Meet에서 마이크를 끄는 단축키를 Chrome에 전송합니다.
- Comment -- "카메라 사용 또는 사용중지 단축어 (Command + E)" 메모입니다.
- SimulateKeystroke ⌘E -- Google Meet에서 카메라를 끄는 단축키를 Chrome에 전송합니다.
- ExecuteJavaScript -- Chrome에서 자막 켜기 버튼을 클릭하는 JavaScript를 실행합니다.
핵심 기술 해설
AppleScript로 시스템 상태 확인하기
output muted of (get volume settings)
이 한 줄의 AppleScript는 macOS의 음소거 상태를 확인합니다.
get volume settings는 시스템 볼륨 정보를 반환합니다.
output muted는 그중 음소거 여부를 true 또는 false로 반환합니다.
결과를 mute_yn 변수에 저장한 뒤, IfThenElse 조건 분기에서 사용합니다.
이미 음소거 상태이면 다시 음소거를 실행하지 않습니다.
"현재 상태를 확인하고, 필요할 때만 동작하는" 패턴입니다.
SimulateKeystroke로 앱 단축키 전송하기
Google Meet은 자체 단축키를 제공합니다.
⌘D는 마이크 토글, ⌘E는 카메라 토글입니다.
KM의 SimulateKeystroke 액션은 이 단축키를 Chrome에 직접 전송합니다.
대상 앱을 "Specific: Google Chrome"으로 지정하면, 현재 포커스와 무관하게 Chrome에 키 입력이 전달됩니다.
ExecuteJavaScript로 웹 요소 클릭하기
// 버튼을 선택하여 클릭하는 JavaScript 코드
document.querySelector('button[jsname="Qx7uuf"]').click();
Google Meet의 자막 버튼에는 전용 단축키가 없습니다.
이때 JavaScript로 DOM 요소를 직접 찾아서 클릭합니다.
jsname 속성은 Google이 내부적으로 사용하는 식별자입니다.
KM의 ExecuteJavaScript 액션은 Chrome의 현재 탭에서 JavaScript를 실행합니다.
웹 개발자 도구 없이도 웹페이지를 조작할 수 있는 강력한 기능입니다.
Comment 액션으로 매크로 정리하기
이 매크로는 액션 사이에 Comment 액션을 배치합니다. Comment는 아무 동작도 하지 않습니다. 코드의 주석처럼, 다음에 오는 액션이 무엇을 하는지 설명하는 역할입니다. 액션 수가 많은 매크로에서 가독성을 높이는 좋은 습관입니다.
활용 팁
jsname속성은 Google Meet 업데이트 시 변경될 수 있습니다. 동작하지 않으면 개발자 도구(⌘⌥I)에서 버튼의 속성을 다시 확인하십시오.- SetActionDelay를 0.1초로 설정한 이유는 Google Meet의 UI가 렌더링될 시간을 확보하기 위해서입니다. 네트워크 속도가 느리면 더 길게 설정해야 할 수 있습니다.
매크로 분석: Google meet - 접속 시 팔레트 보이기
무엇을 하는 매크로인가
⌃`를 누르면 Google Meet 관련 매크로 팔레트를 표시합니다. Chrome 창 제목에 "Meet -"이 포함되어 있는지 확인하고, Meet 페이지일 때만 팔레트를 보여줍니다.
트리거
| 트리거 타입 | 값 | 설명 |
|---|---|---|
| HotKey | ⌃` | Chrome이 활성화된 상태에서만 동작 |
액션 흐름
- IfThenElse -- Chrome의 창 제목에 "Meet -"이 포함되어 있는지 확인합니다.
- Then: ShowPaletteOfMacros -- 조건이 참이면 Google Meet 관련 매크로 팔레트를 표시합니다.
핵심 기술 해설
Macro Palette (매크로 팔레트)
KM의 매크로 팔레트는 관련 매크로를 버튼 형태로 모아서 보여주는 UI입니다. 팔레트에서 버튼을 클릭하면 해당 매크로가 실행됩니다. 단축키를 외울 필요 없이, 필요한 동작을 시각적으로 선택할 수 있습니다.
이 매크로에서는 Google Meet 전용 매크로들(셋업, 미팅 종료, 자료 공유 등)을 팔레트로 묶어서 보여줍니다. Meet 페이지가 아닐 때는 팔레트가 나타나지 않으므로, 불필요한 UI 노출을 방지합니다.
창 제목 기반 조건 분기
조건에서 "Any window of Google Chrome contains Meet -"을 확인합니다. Google Meet 페이지의 창 제목은 "Meet - xxx" 형식입니다. 이 패턴으로 현재 Meet 미팅 중인지 판별합니다.
활용 팁
- 팔레트의 테마, 열 수, 투명도를 커스터마이징할 수 있습니다. 이 매크로에서는 "Mojave Night" 테마를 6열로 사용합니다.
- 다른 웹 앱(Slack, Notion 등)에도 같은 패턴을 적용하여 앱별 팔레트를 만들 수 있습니다.
매크로 분석: Google meet - 미팅종료하기
무엇을 하는 매크로인가
Google Meet에서 "통화에서 나가기" 버튼을 클릭하여 미팅을 종료합니다.
트리거
| 트리거 타입 | 값 | 설명 |
|---|---|---|
| (없음) | -- | 팔레트에서 호출 |
액션 흐름
- ActivateApplication -- Google Chrome을 활성화합니다.
- PressButton -- "통화에서 나가기" 버튼을 Description 기반으로 찾아서 클릭합니다.
핵심 기술 해설
PressButton 액션
PressButton은 화면에서 버튼을 찾아 클릭하는 액션입니다.
버튼을 찾는 방법에는 Title(버튼 텍스트)과 Description(접근성 설명)이 있습니다.
이 매크로에서는 Description:통화에서 나가기로 접근성 설명을 기준으로 버튼을 찾습니다.
좌표 기반 클릭보다 안정적입니다. 창 위치나 크기가 바뀌어도 버튼을 찾을 수 있습니다. 다만 Google Meet UI의 언어 설정이 한국어여야 합니다.
매크로 분석: Google meet - 자료 공유 / 자료 공유 중지
무엇을 하는 매크로인가
"자료 공유" 매크로는 Google Meet에서 화면 공유를 시작합니다. "자료 공유 중지" 매크로는 화면 공유를 중단합니다. 두 매크로의 구조가 동일합니다.
트리거
| 트리거 타입 | 값 | 설명 |
|---|---|---|
| (없음) | -- | 팔레트에서 호출 |
액션 흐름 (자료 공유)
- ActivateApplication -- Google Chrome을 활성화합니다.
- PressButton --
Description:발표 시작버튼을 클릭합니다.
액션 흐름 (자료 공유 중지)
- ActivateApplication -- Google Chrome을 활성화합니다.
- PressButton --
Title:발표 중지하기버튼을 클릭합니다.
핵심 기술 해설
Description vs Title 버튼 검색
"자료 공유"는 Description으로, "자료 공유 중지"는 Title로 버튼을 찾습니다.
같은 PressButton 액션이지만 검색 기준이 다릅니다.
웹 앱의 버튼은 눈에 보이는 텍스트(Title)와 접근성 라벨(Description)이 다를 수 있습니다. 둘 다 시도해보고, 더 안정적으로 동작하는 쪽을 선택하면 됩니다. Chrome의 접근성 트리(⌘⌥I > Elements > Accessibility)에서 확인할 수 있습니다.
활용 팁
- 자료 공유 시작과 중지를 하나의 매크로로 만들고 토글 방식으로 구현할 수도 있습니다. 현재 공유 중인지 확인하는 조건 분기를 추가하면 됩니다.
직접 만들어보기
가장 실용적인 "New text file" 매크로를 직접 만들어봅니다.
- KM 에디터에서 Finder 그룹을 만듭니다. Available in 설정에서 Finder만 선택합니다.
- 새 매크로를 만들고 이름을 "New text file"로 설정합니다.
- 트리거를 추가합니다: Hot Key Trigger > ⌃N.
- 첫 번째 액션을 추가합니다: Execute AppleScript.
- 스크립트 입력란에 다음을 입력합니다:
tell application "Finder" try set myWin to window 1 set myPath to (POSIX path of (target of myWin as alias)) on error set myPath to (POSIX path of (path to desktop)) end try end tell return myPath- Save results to variable 옵션에서
LocalPath를 입력합니다.
- 두 번째 액션을 추가합니다: Execute Shell Script.
- 스크립트 입력란에 다음을 입력합니다:
#!/bin/bash dir="$KMVAR_LocalPath" base="제목없음" ext=".md" filename="$base$ext" i=1 while [ -e "$dir/$filename" ]; do filename="${base}${i}${ext}" ((i++)) done touch "$dir/$filename" echo -n "$filename"- Save results to variable 옵션에서
LocalNewFileName을 입력합니다.
- 세 번째 액션을 추가합니다: File > Reveal
%Variable%LocalPath%/%Variable%LocalNewFileName%. - 네 번째 액션을 추가합니다: Simulate Keystroke > ⌃, (Finder에서 이름 변경 단축키).
- 테스트: Finder에서 아무 폴더를 열고 ⌃N을 누릅니다. "제목없음.md" 파일이 생성되고, 이름 변경 모드로 전환되는지 확인합니다.
이 챕터에서 배운 것
- AppleScript의
tell application구문으로 macOS 앱(Finder)에 명령을 보내는 방법 - AppleScript의
try ... on error구문으로 오류를 처리하는 방법 $KMVAR_접두어로 KM 변수를 셸 스크립트에서 참조하는 방법- AppleScript와 셸 스크립트를 역할에 맞게 조합하는 패턴
ExecuteJavaScript로 Chrome 탭의 웹 요소를 조작하는 방법PressButton으로 접근성 기반 버튼 클릭을 수행하는 방법- 매크로 팔레트로 관련 매크로를 그룹화하여 접근하는 방법
다음 챕터 예고
ch09에서는 JavaScript 실행을 본격적으로 다룹니다. YouTube 재생목록 조작과 ChatGPT 마크다운 복사 매크로를 분석하며, 브라우저 DOM을 제어하는 고급 기법을 배웁니다.