유주영HR Operations · DSRVEN
작업 파일

면접 D-1 안내메일 자동화

HR-03채용운영 중

공유 캘린더에서 익일 면접을 감지해 유형별 템플릿으로 Gmail 초안까지 생성. 발송은 의도적으로 자동화하지 않았다. 입력은 사람이 채우는 필드이고 출력은 회수 불가능하기 때문.

기간
2026.04 – 운영 중
스택
Google Apps Script · Gmail · Calendar
대체한 것
매일 수기 작성

면접 전날 후보자에게 나가는 안내 메일을, 캘린더를 읽어 초안까지 자동으로 만들어 두는 도구. 발송은 자동화하지 않았다. 그게 이 프로젝트에서 가장 중요한 결정이다.


1. 한눈에

역할 설계 · 구현 · 운영 (1인)
기간 2026-04 ~ (운영 중)
스택 Google Apps Script · Calendar API · Gmail API · clasp
규모 소스 6파일 · 커밋 11 · 통합 테스트 스위트 포함
실행 매일 오전 시간 기반 트리거 1회 · dry-run 모드 별도
대상 면접 유형 3종 (폰 스크리닝 · 직무 인터뷰 · 컬쳐핏 인터뷰)

2. 배경 — 무엇이 문제였나

면접 일정이 잡히면 전날 후보자에게 안내 메일을 보낸다. 장소, 시간, 준비물, 담당자 연락처가 들어간다.

내용 자체는 정형화되어 있다. 하지만 면접 유형마다 템플릿이 다르고, 하루에 여러 건이 잡히기도 하며, 무엇보다 잊으면 후보자 경험이 직접 나빠진다.

즉 이 일은 “어렵지 않지만 절대 빠뜨리면 안 되는” 종류였다. 사람이 매일 캘린더를 확인해서 처리하는 방식은 바쁜 날에 정확히 실패한다.


3. 무엇을 만들었나

매일 아침 자동으로 도는 Apps Script 한 벌.

  매일 오전 트리거
        │
        ▼
 ① 내일 일정 조회 ── 공유 캘린더에서 다음 날 이벤트 전체
        │
        ▼
 ② 면접 판별 ────── 제목 키워드로 유형 3종 감지
        │            (해당 없으면 건너뜀)
        ▼
 ③ 후보자 정보 파싱 ── 이벤트 설명에서 이름 · 이메일 추출
        │            ├─ 성공 → ④로
        │            └─ 실패 → 경고 목록으로 (조용히 넘기지 않는다)
        ▼
 ④ 중복 확인 ────── 같은 제목+수신자 초안이 이미 있으면 스킵
        │
        ▼
 ⑤ 초안 생성 ────── 유형별 템플릿에 변수 치환 → Gmail 초안
        │            ※ 발송하지 않는다
        ▼
 ⑥ 운영자 알림 ──── 생성 건수 + 경고 건수를 실행 계정으로 요약 발송

4. 가장 중요한 결정 — 발송하지 않는다

메일을 자동으로 보내지 않고 초안까지만 만든다.

기술적으로는 발송이 더 쉽다. 초안을 만들면 사람이 여전히 매일 메일함을 열어야 하니, 겉보기엔 자동화가 덜 된 것처럼 보인다. 그럼에도 초안을 택한 이유는 이렇다.

  • 이 메일의 수신자는 회사 밖의 지원자다. 내부 알림과 달리 잘못 나가면 회수할 수 없다.
  • 캘린더 이벤트는 사람이 손으로 채운 필드에 의존한다. 시간이 바뀌거나 취소된 일정, 설명이 덜 채워진 이벤트가 정상적으로 존재한다.
  • 즉 입력의 신뢰도가 100%가 아닌데 출력이 되돌릴 수 없는 구조다. 이 조합에서는 마지막 사람 확인을 없애면 안 된다.

자동화한 것은 “쓰는 일“이고, 자동화하지 않은 것은 “보내는 판단“이다. 반복 작업의 부담은 거의 전부 앞쪽에 있었으므로, 효용은 대부분 가져오면서 위험은 남기지 않았다.


5. 조용한 실패를 만들지 않기 위해 한 것

파싱 실패를 결과에 포함시킨다

이벤트 설명에서 후보자 이름이나 이메일을 찾지 못하면, 그 건을 그냥 건너뛰지 않는다. 오류 사유를 붙여 경고 목록에 담고, 아침 요약 메일에 함께 실어 보낸다.

건너뛰기만 하면 결과는 “초안 3건 생성”이고, 실제로 면접이 4건이었다는 사실은 아무도 모른다. 누락은 성공처럼 보이기 때문에 반드시 출력에 나타나야 한다.

알림 메일의 제목도 상황에 따라 바꿨다 — 생성 0건에 경고만 있으면 확인 필요가 제목에 들어간다. 아무 일도 안 한 아침과 문제가 있는 아침이 받은편지함에서 구분되어야 한다.

중복 실행을 견딘다

트리거는 중복 실행될 수 있고, 같은 일정이 캘린더에 두 번 들어오기도 한다. 초안을 만들기 전에 같은 제목·수신자의 초안이 이미 있는지 확인하고, 있으면 만들지 않는다. 같은 후보자에게 같은 안내가 두 번 준비되는 상황을 구조적으로 막았다.

dry-run을 따로 뒀다

초안을 만들지 않고 무엇이 만들어질지만 반환하는 실행 경로를 별도 함수로 뒀다. 템플릿을 고치거나 키워드를 추가할 때, 실제 메일함을 건드리지 않고 결과를 먼저 본다.


6. 여러 담당자가 함께 쓰도록 만든 방법

이 스크립트는 채용 담당이 바뀌거나 늘어도 그대로 동작해야 했다.

① 캘린더를 ID가 아니라 이름으로 찾는다 계정마다 캘린더 ID가 다르므로, ID를 박아두면 다른 담당자 계정에서는 동작하지 않는다. 이름으로 조회하면 그 캘린더를 구독한 어느 계정에서 실행해도 같은 코드가 동작한다. 찾지 못하면 “실행 계정이 이 공유 캘린더에 접근할 수 있어야 한다”는 메시지와 함께 명시적으로 실패한다 — 조용히 0건을 반환하지 않는다.

② 알림 수신자를 실행 시점에 해석한다 요약 메일은 고정 주소가 아니라 그 스크립트를 실행하고 있는 계정으로 간다. 초안은 실행 계정의 메일함에 만들어지므로, 알림도 같은 사람에게 가야 한다. 담당자가 바뀌어도 설정을 고칠 필요가 없다.

③ 면접 유형 키워드를 설정으로 분리했다 유형 감지는 제목 키워드 매칭이고, 그 키워드 목록은 설정 파일 한곳에 있다. 표기 흔들림(띄어쓰기 유무, 영문)을 배열로 함께 담아 두어, 새 표기가 생기면 코드가 아니라 목록에 한 줄을 추가한다.


7. 숫자로 본 결과

항목 수치
지원 면접 유형 3종 · 유형별 전용 템플릿
사람이 매일 하던 일 캘린더 확인 → 유형 판별 → 템플릿 선택 → 작성 → 발송
자동화 후 남은 일 초안 검토 후 발송 클릭
누락 방지 파싱 실패 건을 경고로 승격해 요약 메일에 포함
중복 발송 위험 초안 중복 검사로 구조적 차단
다중 운영자 캘린더 이름 조회 + 실행 계정 기준 알림으로 지원