HR 이메일 에이전트로 신규 입사자 온보딩하기
요약
Nylas를 활용하여 신규 입사자 온보딩 과정을 자동화하는 HR 이메일 에이전트 구축 방법을 설명합니다. 단순한 메일 읽기를 넘어 에이전트가 직접 발신자 정체성을 갖고 첨부 파일을 추출하며 캘린더를 예약하는 워크플로우를 다룹니다.
핵심 포인트
- 에이전트가 직접 사서함을 소유하여 발신자 정체성을 갖는 것이 중요함
- Nylas를 통해 이메일 발신, 수신 웹훅, 첨부 파일 추출, 캘린더 예약 구현 가능
- 온보딩 상태 관리를 위한 상태 머신(State machine)은 애플리케이션 로직에서 처리 필요
- 기존 공유 편지함 규칙 엔진보다 첨부 파일 분석 및 캘린더 연동 측면에서 우수함
신규 입사자 온보딩 (Onboarding)은 체크리스트입니다. 첫날에 환영 이메일을 보냅니다. 복리후생 등록 양식을 보냅니다. 서명된 I-9 양식을 돌려받습니다. 급여 자동 이체 (Direct-deposit) 양식을 돌려받습니다. 두 양식이 모두 들어오면, 오리엔테이션 일정을 캘린더에 등록합니다. 그게 전부입니다 — 일련의 이메일, 반대로 돌아오는 몇 개의 첨부 파일, 그리고 마지막에 하나의 캘린더 초대장입니다.
대부분의 "HR을 위한 AI" 데모는 모델을 누군가의 개인 Outlook에 연결하고 그것을 온보딩이라고 부릅니다. 에이전트가 직접 _발신자_가 되고 싶을 때까지는 괜찮습니다 — 즉, hr@yourcompany.com 사서함을 소유하고, 그 사서함에서 메일을 보내고, 답장을 모니터링하며, 답장에서 서명된 양식을 추출하고, 자신의 이름으로 오리엔테이션을 예약하는 것을 말합니다. 인간의 편지함 위를 떠다니는 모델은 이를 깔끔하게 수행할 수 없습니다. 모델에게는 정체성 (Identity)이 필요합니다.
저는 Nylas CLI 작업을 하고 있으므로, 아래의 nylas ... 명령어들은 제가 수동으로 흐름을 살펴볼 때 사용하는 정확한 명령어들입니다. 모든 작업은 두 가지 관점으로 제공됩니다: 서비스에 넣을 curl 명령과 이를 테스트하는 데 사용할 CLI입니다.
얻을 수 있는 것
전체 체크리스트를 수행하는 하나의 사서함:
- 발신 (Sends): 환영 이메일과 각 양식 요청 이메일을 보냅니다 — 첫 주 동안 시차를 두고 보내고 싶다면 일정에 맞춰 보낼 수 있습니다.
- 수신 (Receives): 표준
message.created웹훅 (Webhook)으로 들어오는 답장을 수신하며, 각 웹훅은 그것이 HR 에이전트임을 알 수 있도록grant_id를 포함합니다. - 읽기 (Reads): 해당 답장을 읽고 서명된 I-9, 급여 자동 이체 양식과 같은 첨부 파일을 추출 (Pulls the attachments) 하여 메시지에서 바로 가져옵니다.
- 오리엔테이션 예약 (Books orientation): 자신의 캘린더에 실제 이벤트로 오리엔테이션을 예약하고 신규 입사자에게 초대장을 이메일로 보냅니다.
어떤 입사자가 어느 단계에 있는지, 어떤 양식이 들어왔는지, 오리엔테이션을 예약할 때가 되었는지와 같은 온보딩 상태 (State) 는 여러분의 앱이나 데이터베이스에 저장됩니다. 에이전트 계정 (Agent Accounts)은 체크리스트를 매달 수 있는 커스텀 메타데이터 (Custom metadata)를 제공하지 않으므로, 상태 머신 (State machine)은 여러분의 몫입니다. Nylas는 메일과 캘린더를 이동시키며, 다음 단계가 무엇인지 결정하는 것은 여러분의 코드입니다.
이것이 공유 HR 편지함 + 규칙 엔진 (Rules engine)보다 나은 이유
메일 규칙이 설정된 공유 hr@ 편지함은 절반 정도는 해결해주지만 그 이후에는 멈추게 됩니다:
- 규칙은 첨부 파일을 읽을 수 없습니다. 인바운드 Nylas Rules는
from.*(발신자 주소, 도메인, TLD)에 대해서만 매칭됩니다. 제목, 본문, 또는 서명된 PDF가 첨부되었는지 여부는 확인할 수 없습니다. 양식 수신 감지 (Form-receipt detection)는 애플리케이션 로직 (application logic)입니다. 즉, 메시지를 가져와서 첨부 파일을 검사해야 합니다. 규칙이 이를 대신 해주지는 않습니다. - 공유 편지함은 캘린더 정체성이 없습니다. 오리엔테이션 안내가 나갈 때, 이는 HR 에이전트로부터 발송되어야 하며, 에이전트의 캘린더에 등록되어야 합니다. 그래야 일정 변경이나 RSVP(참석 회신)가 한 곳으로 다시 전달될 수 있습니다. 배포 목록 (distribution list)은 이벤트를 호스팅할 수 없습니다.
- 단일 감사 추적 (audit trail)이 필요합니다. 모든 발송, 모든 양식 수신, 모든 예약이 하나의
grant_id를 통해 흐릅니다. 이것이 바로 로그를 남기고 다시 재생 (replay)할 대상입니다.
시작하기 전에
다음 사항이 필요합니다:
- Nylas 애플리케이션 및 API 키. 예제는 미국 데이터 리전(
https://api.us.nylas.com)을 사용합니다. EU 리전을 사용 중이라면 호스트를 변경하세요. - 등록된 발신 도메인 — 검증된 커스텀 도메인 또는 테스트를 위한 Nylas
*.nylas.email체험용 서브도메인. 새 도메인은 약 4주에 걸쳐 워밍업 (warm up)이 필요하므로, 첫날부터 수백 명의 신규 입사자를 대량으로 온보딩하지 마세요. - 웹훅 (webhooks)을 위한 공개적으로 접근 가능한 HTTPS 엔드포인트 (endpoint).
HR 에이전트 계정 프로비저닝 (Provision)
에이전트는 POST /v3/connect/custom, 프로바이더 nylas, 그리고 등록된 도메인의 이메일을 사용하여 생성됩니다. 선택 사항인 최상위 name은 수신자가 보게 될 표시 이름을 설정합니다. OAuth나 리프레시 토큰 (refresh token)은 필요하지 않습니다.
curl --request POST \
--url 'https://api.us.nylas.com/v3/connect/custom' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
...
nylas agent account create hr@yourcompany.com --name "Acme People Ops"
이렇게 하면 grant_id가 발급됩니다. 이후의 모든 작업은 /v3/grants/{grant_id}/... 형식을 따릅니다. API는 해당 계정에 대한 기본 워크스페이스 (workspace)와 정책 (policy)을 자동으로 생성합니다. 나중에 커스텀 인바운드 정책을 사용하고 싶은 경우에만 이를 수정하면 됩니다 (nylas workspace update <workspace-id> --policy-id <policy-id>).
양식 프로비저닝 (Provision the forms)
신규 입사자가 서명하여 다시 보내는 두 가지 양식인 I-9 및 직접 입금 승인(direct-deposit authorization) 양식은 귀하의 앱이 호스팅하는 PDF입니다. 채용자별로 양식을 생성하거나 템플릿화하고, 양식 요청 이메일에 링크를 포함하며, 수신 확인 프로세스가 무엇을 기다리고 있는지 알 수 있도록 예상 파일 이름(또는 채용자별 토큰)을 저장하세요. 에이전트는 빈 양식을 호스팅하지 않습니다. 에이전트는 링크를 발송하고 서명된 사본을 다시 읽어옵니다.
환영 및 양식 요청 시퀀스 발송
첫째 날: 환영 이메일을 보냅니다. 그다음 각 문서에 대한 양식 요청 이메일을 보냅니다. 이메일을 즉시 발송하거나, CLI의 --schedule "tomorrow 9am" 옵션 또는 나중에 전송 엔드포인트를 호출하는 서버 측 작업을 사용하여 첫 주 동안 일정을 나누어 발송할 수 있습니다. (전송 API 자체는 즉시 발송하며, CLI의 --schedule은 테스트 중에 단일 메시지 발송을 연기할 수 있는 편리한 방법입니다.)
다음은 Messages 전송 엔드포인트를 통한 첫 번째 접점인 환영 이메일입니다:
curl --request POST \
--url 'https://api.us.nylas.com/v3/grants/<GRANT_ID>/messages/send' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
...
nylas email send hr@yourcompany.com \
--to priya.nair@example.com \
--subject "Welcome to Acme — your first-week checklist" \
...
양식 요청 이메일은 문구와 각 양식에 대한 링크만 다를 뿐 동일한 호출 방식입니다. I-9 요청을 즉시 보내는 대신 다음 날 아침으로 미루려면 다음과 같이 합니다:
nylas email send hr@yourcompany.com \
--to priya.nair@example.com \
--subject "Action needed: sign and return your I-9" \
...
nylas email send에는 첨부 파일(attachment) 플래그가 없습니다. 대신 링크와 본문을 전송하는데, 이는 여기서 정확히 의도한 바입니다. 즉, 귀하가 아닌 신규 입사자가 답장 시 서명된 PDF를 첨부하는 것입니다. (만약 발송 시 파일을 첨부해야 한다면 nylas email drafts create --attach를 사용하거나, 파일 폼 필드 이름이 attachment인 Drafts API에서 Base64/multipart 방식을 사용하면 됩니다.)
앱 내에서 이 채용 건에 대한 시퀀스(sequence)가 시작되었음을 기록하고, 두 양식(form)을 모두 pending 상태로 표시하세요. 해당 pending/received 매핑이 바로 체크리스트가 됩니다.
답장 수신하기
curl --request POST \
--url 'https://api.us.nylas.com/v3/webhooks' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
...
nylas webhook create \
--url https://your-app.example.com/webhooks/nylas \
--triggers message.created \
...
앱의 모든 권한 부여(grant)는 해당 URL 하나로 전달되며, 각 페이로드(payload)에는 grant_id가 포함되어 있습니다. HR 에이전트의 grant_id를 필터링하고 나머지는 무시하세요.
핸들러(handler)에서 올바르게 처리해야 할 두 가지 사항이 있습니다:
알림 id를 기준으로 중복을 제거(Dedupe)하세요. Nylas는 최소 한 번 전달(at-least-once delivery)을 보장하며, 이벤트를 최대 3번까지 재시도합니다. 최상위 수준의 알림 id는 재시도 시에도 일정하게 유지되므로, 이것이 중복 제거 키(dedup key)가 됩니다. 내부의 data.object.id는 메시지(message) ID입니다. 동일한 답장을 두 번 처리하지 않도록 이 ID를 추가로 사용하여 방어 로직을 구축할 수 있습니다.
본문(body)을 위해 페이로드를 신뢰하지 마세요. Nylas 문서에 따르면 message.created 내에 전체 본문이 인라인(inline)으로 포함되는지 여부가 상이할 수 있습니다. 어떤 경우든 안전한 방법은 동일합니다. 페이로드 본문에 의존하지 마세요. 본문이 필요할 때 ID를 통해 전체 메시지를 가져오고, message.created.truncated(Nylas가 큰 메시지를 본문 없이 전달할 때 사용하는 유형)를 기준으로 분기 처리하세요. 웹훅을 메시지에 대한 _포인터(pointer)_로 취급한 다음, 메시지를 읽으러 가십시오.
답장을 읽고 양식 찾기
첨부 파일을 검사하기 위해 ID로 수신된 메시지를 가져옵니다:
curl --request GET \
--url 'https://api.us.nylas.com/v3/grants/<GRANT_ID>/messages/<MESSAGE_ID>' \
--header 'Authorization: Bearer <NYLAS_API_KEY>'
nylas email read <MESSAGE_ID> hr@yourcompany.com
메시지 객체에는 attachments 배열이 포함되어 있으며, 각 항목은 id, filename, content_type, size를 가집니다. _이곳_이 바로 양식 영수증 탐지 (form-receipt detection)가 일어나는 지점입니다. 이는 규칙이 아니라 여러분의 코드에서 처리해야 할 영역입니다. 즉, 이 답장에 여러분이 기다리고 있는 I-9 양식과 일치하는 파일명(또는 채용별 토큰)을 가진 PDF가 포함되어 있는지를 확인하는 것입니다. 만약 그렇다면 양식을 확보한 것이고, 단순히 "감사합니다, 처리하겠습니다!"라는 내용뿐이라면 양식을 확보하지 못한 것이므로 양식 상태를 pending (대기 중)으로 남겨두어야 합니다.
원한다면 답장을 읽음 처리할 수 있는데, 이는 별도의 PUT 요청으로 이루어집니다. GET 요청의 부수 효과 (side effect)로 처리되지 않습니다:
curl --request PUT \
--url 'https://api.us.nylas.com/v3/grants/<GRANT_ID>/messages/<MESSAGE_ID>' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
...
CLI에서는 nylas email read 명령에 --mark-read를 전달하여 읽기 및 읽음 처리를 한 번에 수행할 수 있습니다. 만약 수신 확인을 위해 스레드 내에서 답장을 보내고 싶다면, nylas email reply <message-id> --body "..."를 사용하여 스레드를 유지할 수 있습니다.
서명된 양식 다운로드하기
일치하는 첨부 파일이 식별되면, 이를 다운로드하여 문서 저장소나 전자 서명 (e-signature) 아카이브로 전달합니다. 다운로드 엔드포인트는 쿼리 파라미터로 message_id를 필수적으로 요구합니다. 첨부 파일 ID만으로는 위치를 찾기에 충분하지 않습니다:
curl --request GET \
--url 'https://api.us.nylas.com/v3/grants/<GRANT_ID>/attachments/<ATTACHMENT_ID>/download?message_id=<MESSAGE_ID>' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
...
nylas email attachments download <ATTACHMENT_ID> <MESSAGE_ID> hr@yourcompany.com -o i9-priya-nair.pdf
CLI 인자 순서에 주의하세요: 첨부 파일 ID가 먼저 오고, 그다음 메시지 ID, 마지막으로 선택 사항인 grant가 옵니다. 파일 다운로드가 완료되면, 체크리스트에서 해당 양식의 상태를 pending에서 received (수신됨)로 변경하세요. I-9 양식과 급여 자동 이체 (direct-deposit) 양식이 모두 received 상태가 되면, 해당 채용자는 오리엔테이션을 받을 준비가 된 것이며, 이 전환이 예약 (booking)을 트리거하게 됩니다.
에이전트 캘린더에 오리엔테이션 예약하기
모든 Agent Account에는 실제 캘린더가 포함되어 있습니다. 두 양식이 모두 제출되면, 에이전트는 자신의 캘린더에 오리엔테이션 이벤트를 생성하고 notify_participants=true를 전달하여 신규 입사자에게 초대 이메일을 보냅니다. 신규 입사자는 hr@yourcompany.com으로부터 일반적인 캘린더 초대를 받으며, Google Calendar 또는 Outlook에서 수락합니다. 그러면 RSVP(참석 여부 회신)는 다른 참석자의 응답과 마찬가지로 에이전트의 메일함으로 다시 전달됩니다.
curl --request POST \
--url 'https://api.us.nylas.com/v3/grants/<GRANT_ID>/events?calendar_id=primary¬ify_participants=true' \
--header 'Authorization: Bearer <NYLAS_API_KEY>' \
...
nylas calendar events create hr@yourcompany.com \
--calendar primary \
--title "New-hire orientation — Priya Nair" \
...
알아두어야 할 두 가지 사항이 있습니다. 첫째, nylas calendar events send 명령은 존재하지 않습니다. 이벤트를 생성하고 (서버 측의) notify_participants=true가 초대를 발송하도록 합니다. CLI 동사는 create, update, delete, list, rsvp, show이며, 참가자에게 이메일을 보내는 것은 별도의 캘린더 명령이 아니라 API의 역할입니다. 둘째, 이것은 Scheduler가 아니라 에이전트 자체의 Events API입니다.
-
체크리스트는 여러분의 몫입니다. 에이전트 계정(Agent Accounts)은 온보딩 상태를 고정할 수 있는 임의의 커스텀 메타데이터(custom metadata)를 보유하지 않으므로, 메일함을 데이터베이스로 사용하려고 하지 마세요. 채용 인원별
pending/received맵(map)과 현재 단계를 채용 인원 및grant_id를 키(key)로 하여 여러분의 자체 저장소(store)에 유지하십시오. -
양식 탐지(Form detection)는 규칙이 아니라 코드입니다. 인바운드 규칙(Inbound Rules)은
from.*만 매칭할 뿐이며, 서명된 I-9 양식과 "좋아요!"라고 답장한 메시지를 구분할 수 없습니다. 메시지를 가져와서attachments(첨부 파일)를 검사하고, 파일 이름이나 채용 인원별 토큰(token)을 통해 매칭하십시오. 또한 규칙은rule_ids를 통해 워크스페이스(workspace)에 연결되기 전까지는 비활성 상태이므로, 여러분이 할 수 있는from.*필터링조차도 먼저 배선(wiring up) 작업이 필요합니다. -
본문을 가져오세요. 페이로드(payload)를 신뢰하지 마세요. 웹훅(webhook)이 전체 메시지를 포함하고 있다고 가정하지 말고,
message.created.truncated를 기준으로 분기하여 ID를 통해 다시 가져오십시오. -
전송 할당량(Send quotas)은 실재합니다. 무료 플랜은 계정당 하루 200개의 메시지로 제한되며,
notify_participants=true가 설정된 각 오리엔테이션 초대장은 에이전트의 일일 전송 할당량에 포함됩니다. 이벤트를 생성할 때 에이전트가 할당량을 초과한 경우, 이벤트는 저장되지만 초대는 조용히 건너뛰어집니다. 즉, 아무에게도 이메일이 발송되지 않습니다. 대규모 채용 주간에는 전송량을 주의 깊게 모니터링하십시오. -
시간을 명시적으로 설정하세요. 에이전트 계정은 사람의 캘린더와 달리 기본 시간대(default time zone)가 없습니다. 오리엔테이션이 의도한 시간에 진행되도록 생성 시
timezone을 전달하거나, 에포크(epoch) 기반의start_time/end_time을 사용하십시오.
다음 단계
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기