ch14. 복합 워크플로우 -- YouTube, Gemini, Google Docs

YouTube 영상을 Gemini로 분석하고 Google Docs에 자동 저장하는 다중 앱 파이프라인을 구축한다.

이런 불편함, 겪어보셨나요?

YouTube에서 유익한 영상을 발견했다. 내용을 정리해서 나중에 다시 볼 수 있도록 문서로 남기고 싶다. 보통은 이런 과정을 거친다.

영상을 보면서 메모장에 핵심 내용을 직접 타이핑한다. 또는 Gemini에 영상 링크를 붙여넣고 분석을 요청한다. 분석 결과가 나오면 Google Docs에 복사해서 붙여넣는다.

영상이 한두 개라면 괜찮다. 그런데 재생목록에 영상이 10개, 20개 쌓여 있다면 이야기가 달라진다. 같은 작업을 반복하는 데만 수십 분이 걸린다.

이 챕터에서는 이 전체 과정을 하나의 매크로로 자동화한다. YouTube에서 영상 URL을 추출하고, Gemini에게 분석을 맡기고, 결과를 Google Docs로 내보내는 파이프라인이다. 여기에 Chrome 프로필 전환과 NotebookLM 연동까지 더해서, 다섯 개의 매크로로 완성된 워크플로우를 만든다.

워크플로우 아키텍처

이 챕터의 매크로는 하나의 데이터 파이프라인을 구성한다. 각 매크로가 파이프라인의 서로 다른 단계를 담당한다.

YouTube 영상 URL (입력)
    |
    v
Chrome 프로필 전환 (매크로 3, 4)
    |
    v
Gemini 분석 요청 (매크로 1, 2)
    |
    v
Google Docs 저장 (매크로 1, 2)
    |
    v
NotebookLM 데이터 추가 (매크로 5)

개별 매크로를 먼저 분석한 뒤, 전체 파이프라인을 조합하는 순서로 진행한다.

매크로 분석: Youtube - Gemini Google Docs 저장

무엇을 하는 매크로인가

Gemini에서 분석한 YouTube 영상 결과를 Google Docs로 자동 내보내는 매크로다. 현재 탭의 Gemini 결과를 저장한 뒤, 열려 있는 모든 Gemini 탭을 순회하며 같은 작업을 반복한다.

트리거

트리거 타입 설명
TypedString aa 텍스트 트리거. "aa"를 입력하면 실행

액션 흐름

flowchart TD A(["트리거: TypedString 'aa'"]) --> B["JS: 공유 버튼 클릭"] B --> C[/"0.1초 대기"/] C --> D["JS: Docs로 내보내기 클릭"] D --> E[/"0.3초 대기"/] E --> F["딜레이 초기화"] F --> G(["Cmd+W 탭 닫기"]) G --> H["AS: Gemini 탭 URL 수집"] subgraph Loop["반복: 각 Gemini 탭"] I["AS: 해당 탭 활성화"] --> J[/"0.1초 대기"/] J --> K["JS: 공유 버튼 클릭"] K --> L[/"0.1초 대기"/] L --> M["JS: Docs로 내보내기 클릭"] M --> N[/"1초 대기"/] end H --> Loop Loop --> O(["완료"]) style A fill:#E3F2FD,stroke:#1976D2 style B fill:#E8F5E9,stroke:#388E3C style C fill:#F3E5F5,stroke:#7B1FA2 style D fill:#E8F5E9,stroke:#388E3C style E fill:#F3E5F5,stroke:#7B1FA2 style F fill:#F3E5F5,stroke:#7B1FA2 style G fill:#F3E5F5,stroke:#7B1FA2 style H fill:#E8F5E9,stroke:#388E3C style I fill:#E8F5E9,stroke:#388E3C style J fill:#F3E5F5,stroke:#7B1FA2 style K fill:#E8F5E9,stroke:#388E3C style L fill:#F3E5F5,stroke:#7B1FA2 style M fill:#E8F5E9,stroke:#388E3C style N fill:#F3E5F5,stroke:#7B1FA2 style O fill:#E3F2FD,stroke:#1976D2

그림 14-1. Youtube - Gemini Google Docs 저장 매크로 흐름도

  1. JavaScript 실행 -- 공유 버튼 클릭. Gemini 페이지에서 data-test-id="share-button" 속성을 가진 버튼을 찾아 클릭한다. DOM을 직접 조작하는 방식이다.
  2. 0.1초 대기. UI 렌더링을 기다린다.
  3. JavaScript 실행 -- Docs 내보내기 클릭. 모든 버튼을 순회하며 "Docs로 내보내기" 텍스트를 포함한 버튼을 찾아 클릭한다.
  4. 0.3초 대기. 내보내기 처리를 기다린다.
  5. 딜레이 초기화. 이후 액션의 실행 속도를 빠르게 설정한다.
  6. Cmd+W로 탭 닫기. 내보내기가 완료된 탭을 닫는다.
  7. AppleScript 실행 -- Gemini 탭 URL 수집. Chrome의 모든 창과 탭을 순회하며 Gemini URL을 가진 탭 목록을 수집한다.
  8. For Each 반복 -- 나머지 탭 처리. 수집된 Gemini 탭 각각에 대해 (a) AppleScript로 해당 탭 활성화, (b) 공유 버튼 클릭, (c) Docs 내보내기 클릭을 반복한다.

핵심 기술 해설

AppleScript로 Chrome 탭 수집

이 매크로의 핵심은 AppleScript로 Chrome의 탭 정보를 가져오는 부분이다.

tell application "Google Chrome"
    set tabURLs to ""
    repeat with w in windows
        repeat with t in tabs of w
            set tabURL to URL of t
            if tabURL contains "https://gemini" then
                -- Gemini 탭 URL을 수집
            end if
        end repeat
    end repeat
end tell

Chrome의 모든 창(windows)과 탭(tabs)을 이중 반복으로 순회한다. URL에 "gemini"가 포함된 탭만 골라서 목록에 추가한다. 이 목록이 KM 변수로 저장되고, For Each 루프의 입력이 된다.

JavaScript로 DOM 버튼 탐색

Gemini 페이지의 버튼을 찾는 JavaScript 코드도 주목할 만하다.

function clickDocsExportButton() {
  const buttons = document.querySelectorAll('button');
  for (const btn of buttons) {
    if (
      btn.innerText &&
      btn.innerText.includes('Docs로 내보내기')
    ) {
      btn.click();
      return true;
    }
  }
  return false;
}
clickDocsExportButton();

data-test-id 같은 안정적인 선택자가 없는 버튼은 텍스트 내용으로 찾는다. 모든 button 요소를 순회하면서 innerText를 확인하는 방식이다. 웹 UI 자동화에서 자주 쓰이는 패턴이지만, UI 텍스트가 변경되면 동작하지 않을 수 있다.

For Each 루프와 AppleScript-JavaScript 협업

이 매크로는 세 가지 스크립팅 기술이 협력한다.

  • AppleScript: Chrome 탭 목록 수집, 특정 탭 활성화
  • JavaScript: 웹페이지 DOM 조작 (버튼 클릭)
  • KM For Each: 수집된 탭 목록을 순차적으로 처리

각 기술이 자신이 가장 잘하는 역할을 맡는 구조다. AppleScript는 앱 제어에, JavaScript는 웹페이지 조작에, KM은 흐름 제어에 강하다.

활용 팁

  • Gemini 외에 ChatGPT 등 다른 AI 서비스에도 같은 패턴을 적용할 수 있다. 버튼 선택자만 변경하면 된다.
  • 탭을 닫는 동작(Cmd+W)을 제거하면 결과를 다시 확인하면서 저장할 수 있다.

매크로 분석: Youtube - Gemini Google Docs 저장 [복수]

무엇을 하는 매크로인가

앞선 매크로와 동일한 기능이지만, 트리거가 없다. 다른 매크로에서 호출하거나 수동으로 실행하는 용도다. 열려 있는 모든 Gemini 탭의 결과를 한 번에 Google Docs로 내보낸다.

트리거

트리거 타입 설명
(없음) - 수동 실행 또는 다른 매크로에서 호출

액션 흐름

  1. 딜레이 초기화.
  2. Cmd+W로 현재 탭 닫기.
  3. AppleScript -- Gemini 탭 URL 수집. 모든 Chrome 창에서 Gemini URL을 가진 탭을 찾는다.
  4. For Each 반복. 수집된 각 탭에 대해 활성화 후 공유 버튼 클릭, Docs 내보내기 클릭을 실행한다.

핵심 기술 해설

단일 vs 복수 처리 매크로 분리

"단건 저장"과 "일괄 저장"을 별도 매크로로 분리한 설계다. 단건 매크로는 텍스트 트리거("aa")로 빠르게 실행하고, 복수 매크로는 다른 매크로의 후처리 단계로 호출한다.

이런 분리 패턴은 재사용성을 높인다. 하나의 거대한 매크로를 만드는 것보다, 역할별로 분리하고 조합하는 편이 유지보수에 유리하다. ch11에서 다룬 서브매크로 패턴과 같은 원리다.

매크로 분석: Youtube - 특정 프로필로 영상 재생하기 (AI)

무엇을 하는 매크로인가

현재 보고 있는 YouTube 영상을 Chrome의 "AI" 전용 프로필에서 다시 연다. AI 관련 영상의 시청 기록과 추천 알고리즘을 별도 프로필로 분리하기 위한 매크로다.

트리거

트리거 타입 설명
HotKey Control+1 YouTube 페이지에서 실행

액션 흐름

flowchart TD A(["트리거: Control+1"]) --> B["변수 설정: MacName"] B --> C["셸 스크립트: 현재 URL 추출"] C --> D{"YouTube 영상 URL인가?"} D -->|Yes| E["AS: AI 프로필에서 URL 열기"] D -->|No| F(["완료"]) E --> F style A fill:#E3F2FD,stroke:#1976D2 style B fill:#E8F5E9,stroke:#388E3C style C fill:#E8F5E9,stroke:#388E3C style D fill:#FFF8E1,stroke:#FFA000 style E fill:#E8F5E9,stroke:#388E3C style F fill:#E3F2FD,stroke:#1976D2

그림 14-2. Youtube - 특정 프로필로 영상 재생하기 (AI) 흐름도

  1. 변수 설정 -- 컴퓨터 이름 저장. %MacName% 토큰으로 현재 Mac의 이름을 변수에 저장한다. 여러 Mac에서 같은 매크로를 사용할 때 경로를 분기하기 위한 준비다.
  2. 셸 스크립트 실행 -- 현재 URL 추출. 활성 브라우저에서 현재 탭의 URL을 가져온다. $HOME 변수를 사용하여 Mac별로 다른 홈 디렉토리에 대응한다.
  3. 조건 분기. URL이 YouTube 영상인지 확인한다.
  4. AppleScript -- 프로필 지정 열기. open -na 'Google Chrome' --args --profile-directory='Profile 4' 명령으로 특정 프로필의 Chrome 창에서 해당 URL을 연다.

핵심 기술 해설

Chrome 프로필 디렉토리 지정

Chrome은 프로필마다 별도 디렉토리를 사용한다. Default, Profile 1, Profile 2 순서로 번호가 매겨진다.

set profileName to "Profile 4"
set theURL to system attribute "KMVAR_currentUrl"

do shell script "open -na 'Google Chrome' --args --profile-directory='" & profileName & "' " & quoted form of theURL

open -na 플래그는 새 인스턴스를 여는 옵션이다. --profile-directory 인수로 원하는 프로필을 지정한다. 이 조합으로 특정 프로필의 Chrome 창에서 URL을 열 수 있다.

다중 Mac 대응 -- $HOME 변수 활용

셸 스크립트에서 $HOME을 사용하면 Mac마다 다른 홈 디렉토리를 자동으로 처리한다. 회사 Mac과 개인 Mac에서 같은 매크로를 공유할 때 유용한 패턴이다. KM 변수 %MacName%으로 컴퓨터를 식별하고, 셸의 $HOME으로 경로를 통일한다.

활용 팁

  • Chrome 프로필 번호는 ~/Library/Application Support/Google/Chrome/ 디렉토리에서 확인할 수 있다.
  • ch04에서 다룬 프로필 전환 매크로와 조합하면 더 강력한 워크플로우가 된다.

매크로 분석: Youtube - 특정 프로필로 영상 재생하기 (Entertain)

무엇을 하는 매크로인가

앞선 매크로와 같은 구조이지만, "Entertain" 프로필(Default)에서 영상을 연다. Control+2로 실행한다.

트리거

트리거 타입 설명
HotKey Control+2 YouTube 페이지에서 실행

액션 흐름

AI 프로필 매크로와 동일한 구조다. 유일한 차이는 프로필 디렉토리가 "Default"라는 점이다.

set profileName to "Default"
set theURL to system attribute "KMVAR_currentUrl"

do shell script "open -na 'Google Chrome' --args --profile-directory='" & profileName & "' " & quoted form of theURL

핵심 기술 해설

패턴 복제와 매개변수화

두 매크로는 프로필 이름만 다르고 나머지 구조가 동일하다. 이런 경우 두 가지 접근법이 있다.

첫 번째는 현재 방식처럼 매크로를 복제하고 매개변수만 변경하는 것이다. 단순하고 직관적이다. 각 매크로의 트리거를 독립적으로 설정할 수 있다.

두 번째는 서브매크로로 통합하고 변수로 프로필을 전달하는 것이다. 중복 코드가 줄어들지만, 호출 구조가 복잡해진다.

프로필이 두세 개라면 복제 방식이 충분하다. 프로필이 다섯 개 이상으로 늘어난다면 서브매크로 방식을 검토할 만하다.

매크로 분석: NotebookLM - Youtube Data 추가

무엇을 하는 매크로인가

YouTube 영상 URL을 NotebookLM 프로젝트에 소스로 추가하는 매크로다. Chrome에서 NotebookLM을 열고, 프로젝트를 선택한 뒤, YouTube 링크를 소스로 등록한다.

트리거

트리거 타입 설명
(없음) - 수동 실행 또는 다른 매크로에서 호출

액션 흐름

  1. 딜레이 초기화.
  2. Chrome 활성화. Google Chrome을 앞으로 가져온다.
  3. 메뉴 선택 -- 프로필 전환. "재식 (회사)" 프로필로 전환한다. NotebookLM이 이 프로필에 로그인되어 있기 때문이다.
  4. Safari Control -- NotebookLM 페이지 이동. NotebookLM URL로 이동한다.
  5. JavaScript 실행 -- 프로젝트 목록 추출. project-button 요소를 모두 찾아 제목을 추출한다. 파이프(|) 구분자로 연결하여 KM 변수에 저장한다.
  6. 사용자 입력 프롬프트. 추출된 프로젝트 목록에서 원하는 프로젝트를 선택한다.
  7. JavaScript 실행 -- 프로젝트 선택. 선택된 프로젝트명으로 해당 버튼을 찾아 클릭한다.
  8. 버튼 클릭 -- Add source. 소스 추가 버튼을 누른다.
  9. JavaScript 실행 -- YouTube 칩 선택. 소스 타입 중 YouTube 칩을 찾아 클릭한다.
  10. URL 입력. 변수에 저장된 YouTube URL을 입력 필드에 삽입한다.
  11. JavaScript 실행 -- 삽입 버튼 클릭. 최종 등록 버튼을 클릭한다.

핵심 기술 해설

JavaScript로 웹 앱 UI 자동화

NotebookLM은 일반 웹페이지가 아니라 웹 앱이다. 표준 HTML 요소 대신 project-button 같은 커스텀 요소를 사용한다. 이런 웹 앱을 자동화할 때는 개발자 도구(F12)로 DOM 구조를 먼저 파악해야 한다.

const projectButtons = document.querySelectorAll('project-button');
const titles = Array.from(projectButtons)
  .map(button => button.textContent.trim());
return titles.join('|');

커스텀 요소의 textContent를 추출하고, 파이프로 연결하여 KM에 반환한다. KM의 PromptForUserInput 액션이 이 목록을 드롭다운으로 보여준다.

Material Design 컴포넌트 탐색

NotebookLM은 Google의 Material Design 컴포넌트를 사용한다. 칩(chip)을 선택하는 코드는 Material Design의 클래스명에 의존한다.

const chips = document.querySelectorAll('.mdc-evolution-chip__action');
for (const chip of chips) {
  const labelSpan = chip.querySelector('.mdc-evolution-chip__text-label');
  const labelText = labelSpan?.innerText.trim();
  // "YouTube" 텍스트를 가진 칩을 찾아 클릭
}

mdc-evolution-chip__action, mdc-evolution-chip__text-label 같은 클래스명은 Material Design Components의 규칙을 따른다. 이런 프레임워크의 명명 규칙을 알면 다른 Google 서비스의 자동화에도 활용할 수 있다.

활용 팁

  • NotebookLM 외에 다른 Google 서비스(Keep, Tasks 등)에도 같은 DOM 탐색 패턴을 적용할 수 있다.
  • 프로젝트 목록이 길어지면 PromptForUserInput 대신 검색 기능을 추가하는 것도 고려할 만하다.

파이프라인 조합하기

다섯 개의 매크로를 하나의 워크플로우로 연결하면 다음과 같다.

1단계: 프로필 전환. YouTube에서 학습용 영상을 발견하면 Control+1로 AI 프로필에서 연다. 시청 기록과 추천이 분리된다.

2단계: Gemini 분석. 영상을 Gemini에 보내 분석을 요청한다. 재생목록의 여러 영상을 한 번에 처리할 수도 있다.

3단계: Docs 저장. Gemini 분석이 완료되면 "aa"를 입력하거나 복수 저장 매크로를 실행한다. 모든 Gemini 탭의 결과가 Google Docs로 내보내진다.

4단계: NotebookLM 등록. 저장된 영상을 NotebookLM에 소스로 추가하여, 나중에 AI와 대화하며 내용을 복습한다.

이 파이프라인의 핵심 설계 원칙은 "느슨한 결합"이다. 각 단계가 독립적인 매크로로 존재하기 때문에, 순서를 바꾸거나 일부 단계를 건너뛸 수 있다. Gemini 대신 ChatGPT를 사용하거나, Docs 대신 Notion에 저장하는 식으로 변형할 수 있다.

직접 만들어보기

가장 핵심이 되는 "Gemini Google Docs 저장" 매크로를 직접 구현해보자.

  1. KM 에디터에서 Gemini 그룹을 만든다.
  2. 새 매크로를 만들고 이름을 "Youtube - Gemini Google Docs 저장"으로 설정한다.
  3. 트리거를 추가한다: Typed String Trigger -- "aa"를 입력한다.
  4. 첫 번째 액션을 추가한다: Execute JavaScript in Google Chrome.
    • Gemini 페이지의 공유 버튼을 클릭하는 코드를 입력한다.
    • document.querySelector('button[data-test-id="share-button"]') 선택자를 사용한다.
  5. Pause 액션을 추가한다: 0.1초.
  6. 두 번째 Execute JavaScript in Google Chrome 액션을 추가한다.
    • "Docs로 내보내기" 버튼을 찾아 클릭하는 코드를 입력한다.
    • 모든 button 요소를 순회하며 innerText에 "Docs로 내보내기"가 포함된 버튼을 찾는다.
  7. Pause 액션: 0.3초.
  8. Execute AppleScript 액션을 추가한다.
    • Chrome의 모든 탭을 순회하며 Gemini URL을 수집하는 코드를 입력한다.
    • 수집된 URL을 줄바꿈으로 구분하여 KM 변수 gemini_tab에 저장한다.
  9. For Each 액션을 추가한다: 변수 gemini_tab을 대상으로 설정한다.
  10. For Each 안에 (a) AppleScript로 탭 활성화, (b) Pause 0.1초, (c) 공유 버튼 JavaScript, (d) Pause 0.1초, (e) Docs 내보내기 JavaScript, (f) Pause 1초를 순서대로 추가한다.
  1. 테스트: Gemini에서 YouTube 영상을 분석한 뒤, "aa"를 입력한다. Google Docs에 새 문서가 생성되는지 확인한다.

이 챕터에서 배운 것

  • AppleScript로 Chrome 탭 목록을 수집하고 순회하는 방법
  • JavaScript로 웹 앱의 DOM 요소를 탐색하고 조작하는 방법
  • For Each 루프와 AppleScript-JavaScript 협업으로 일괄 처리를 구현하는 방법
  • Chrome의 프로필 디렉토리를 지정하여 특정 프로필에서 URL을 여는 방법
  • 독립적인 매크로를 느슨하게 결합하여 데이터 파이프라인을 구성하는 방법

다음 챕터 예고

ch15에서는 AI 도구 연동 매크로를 다룬다. Claude 세션 관리, Gemini with Raycast 연동, Obsidian 자동화 등 AI 시대의 생산성 워크플로우를 구축하는 방법을 배운다.