앱스스크립트에서 문자 발송하기

업무 자동화4분 읽기

앱스스크립트로 업무를 자동화하다 보면 결국 문자 발송이 필요해집니다. 자료가 올라오면, 일정이 잡히면, 보고서가 나오면 관련자에게 알려야 하기 때문입니다. 그런데 막상 SMS 연동을 붙이려고 하면 앱스스크립트라는 실행 환경 특유의 벽에 부딪힙니다. 광고대행 사업의 업무 자동화에서 문자 알림을 구현할 때 우리가 겪은 것도 이 벽이었고 그 우회 과정에서 문자 서비스를 갈아탄 이야기가 이 글의 핵심입니다.

고정 IP를 요구하는 서비스는 앱스스크립트와 맞지 않는다

처음 검토한 국내 문자 서비스는 발신 서버의 고정 IP를 화이트리스트에 등록하도록 요구했습니다. 서버에서 도는 일반적인 백엔드라면 문제가 없습니다. 그 서버의 IP는 고정이니까요. 그런데 앱스스크립트는 구글 인프라 위에서 실행되고 발신에 쓰이는 IP가 실행 때마다 바뀝니다. 고정된 발신 IP라는 것이 애초에 없습니다. 그래서 IP 화이트리스트 방식의 서비스는 아무리 자격증명이 맞아도 발송이 막힙니다.

이 지점에서 선택은 둘입니다. IP가 고정된 별도 발송 서버를 하나 세워 앱스스크립트가 그쪽을 거쳐 보내게 하거나, 아니면 IP 제한이 없는 문자 서비스로 갈아타는 것입니다. 별도 서버는 운영자가 직접 이해하고 굴려야 한다는 이 프로젝트의 원칙과 어긋납니다. 그래서 IP 제한 없이 요청마다 서명으로 인증하는 서비스로 전환했습니다.

HMAC 서명 인증으로 요청마다 스스로를 증명한다

전환한 서비스는 고정 IP 대신 HMAC 서명 방식으로 인증합니다. 원리는 이렇습니다. 발송 요청마다 현재 시각과 무작위 값(솔트)을 만들고 이 둘을 이어 붙인 문자열을 비밀 키로 HMAC-SHA256 서명합니다. 그리고 API 키, 시각, 솔트, 서명을 인증 헤더에 실어 보냅니다. 서버는 같은 비밀 키로 같은 계산을 재현해 서명이 일치하는지 확인합니다.

이 방식은 발신 위치와 무관하다는 게 장점입니다. IP가 어디든 서명만 올바르면 요청이 정당한 것으로 인정됩니다. 비밀 키 자체는 요청에 실리지 않고 서명을 만드는 데만 쓰이므로, 네트워크로 새어 나갈 일도 없습니다. 앱스스크립트에는 시각·무작위 값·HMAC 계산에 필요한 기능이 모두 내장되어 있어 이 인증 헤더를 만드는 데 외부 라이브러리도 필요하지 않았습니다. 매 발송마다 헤더를 새로 만들어 붙이는 것으로 인증이 끝납니다.

자격증명과 수신번호는 코드 밖에 둔다

문자 발송에는 두 종류의 민감한 값이 등장합니다. API 키와 비밀 키 같은 자격증명, 그리고 받는 사람의 전화번호입니다. 둘 다 코드에 박아 넣으면 안 됩니다. 자격증명은 스크립트 속성에만 두고 셋 중 하나라도 설정되어 있지 않으면 에러를 내는 대신 발송을 조용히 건너뛰고 기록만 남기도록 했습니다. 자격증명이 아직 안 들어온 개발 단계에서도 나머지 로직이 멀쩡히 돌게 하기 위해서입니다.

수신번호는 개인정보이므로 더 조심스럽게 다뤘습니다. 거래처 담당자와 관리자의 번호는 코드나 공유되는 시트가 아니라, 본사 비공개 영역의 설정 시트에만 보관합니다. 발송이 필요할 때 이 시트에서 거래처에 해당하는 번호를 읽어 옵니다. 코드는 "누구에게 보낼지"를 알지 못하고 그 정보는 접근이 통제된 자리에만 있습니다. 이렇게 하면 코드를 열어 봐도 개인정보가 드러나지 않습니다.

SMS와 LMS를 본문 길이로 자동 전환한다

마지막 디테일은 문자 규격입니다. 단문(SMS)은 본문 바이트 수에 제한이 있고 이를 넘으면 장문(LMS)으로 보내야 합니다. 한글은 한 글자가 여러 바이트를 차지하기 때문에, 글자 수가 아니라 바이트 수로 판단해야 정확합니다. 그래서 본문의 바이트 길이를 계산해 기준을 넘으면 자동으로 장문으로 전환하도록 했습니다. 알림 문구를 쓰는 사람은 규격을 신경 쓰지 않고 내용만 적으면, 발송 단계에서 알아서 맞는 형식으로 나갑니다.

이 문자 발송 모듈은 업로드 알림과 일정 알림 양쪽에서 함께 쓰입니다. 알림 채널은 이메일에서 문자로, 이후 알림톡으로 단계 전환하도록 설계했는데, 그 전체 그림은 구글 시트·앱스스크립트 거래처별 업무 자동화에서, 이 문자를 실제로 유발하는 업로드 감지는 드라이브 업로드 폴링 알림에서 볼 수 있습니다.

자주 묻는 질문

앱스스크립트에서 SMS가 안 나가면 먼저 무엇을 의심하나요?

인증 방식을 봅니다. 문자 서비스가 발신 IP 화이트리스트를 요구한다면 앱스스크립트에서는 발송이 막힐 수 있습니다. 앱스스크립트는 실행마다 IP가 바뀌어 고정 IP가 없기 때문입니다. 이 경우 IP 제한 없이 요청 서명으로 인증하는 서비스를 쓰거나, 고정 IP를 가진 별도 발송 경유 서버를 두는 방향으로 풀어야 합니다.

HMAC 서명 인증은 직접 구현하기 어렵지 않나요?

앱스스크립트에 필요한 요소가 이미 들어 있어 생각보다 간단합니다. 현재 시각, 무작위 값, HMAC-SHA256 계산이 모두 내장 기능으로 제공되므로, 시각과 솔트를 이어 서명하고 그 결과를 헤더에 담는 몇 줄이면 됩니다. 외부 라이브러리 없이 발송 요청마다 헤더를 새로 만들어 붙이는 정도의 작업입니다.

자격증명이 아직 없을 때 코드가 멈추지 않게 하려면요?

자격증명 세 가지 중 하나라도 비어 있으면 발송을 건너뛰고 기록만 남기도록 했습니다. 이렇게 하면 키가 아직 들어오지 않은 개발 단계에서도 나머지 자동화 로직이 정상적으로 돌아가고 문자 발송만 조용히 비활성 상태가 됩니다. 값을 채우는 순간 별도 배포 없이 발송이 살아납니다.

#앱스스크립트#SMS#솔라피#HMAC인증

업무자동화 구축이 필요하신가요?

무료 상담 신청