구글 앱스 스크립트로 성공한 자동화를, 왜 n8n으로 다시 짰나
지난 글에서 견적 발송 자동화를 구글 앱스 스크립트로 끝냈다고 썼습니다. 그런데 저는 그 뒤에 n8n을 하나 더 들였습니다. 이 글은 그 이야기입니다.
클로드 코드와의 협업, 성공적인 견적 발송 자동화 진행
견적 자동화는 지금도 구글 앱스 스크립트 위에서 그대로 돌아가고 있습니다. 요청이 들어오면 가격과 할인율이 계산되고, 환율이 붙고, PDF가 만들어져 메일로 나갑니다. 사람 손은 들어가지 않습니다.
그리고 이 영역에서 구글 앱스 스크립트는 정말 강합니다. SpreadsheetApp 한 줄이면 시트에 붙고, GmailApp 한 줄이면 메일이 나갑니다. 인증 코드를 단 한 줄도 쓰지 않습니다. 서버도 필요 없고 비용도 0원입니다. 구글 안에서 끝나는 일이라면 이보다 빠른 길은 별로 없습니다.
막힌 곳은 그다음 항목이었습니다
문제는 목록의 다음 줄이었습니다. 발송한 견적을 슬랙 채널에 알리고, 응답이 없으면 며칠 뒤에 리마인드하고, 계약으로 넘어가면 다른 도구에 기록을 남기는 흐름입니다. 여기서 자동화가 구글 밖으로 한 발 나갑니다.
그 순간 난이도가 뒤집힙니다.
구글 서비스는 SpreadsheetApp. 만 치면 되지만, 바깥 서비스는 전부 UrlFetchApp으로 직접 붙여야 합니다. 토큰을 발급받고, 갱신 로직을 직접 구현하고, 스크립트 속성에 저장하고, 만료를 처리합니다. 그리고 이 작업이 자동화를 하나 만들 때마다 처음부터 다시 붙습니다. 자동화의 본체는 열 줄인데 인증 뒷바라지가 백 줄이 되는 구조입니다.
n8n에서는 이게 인증 정보를 한 번 등록하는 일로 끝납니다. 토큰 갱신은 n8n이 알아서 하고, 한 번 등록해 두면 이후 모든 워크플로우가 그것을 그대로 씁니다. 체감으로는 구글 앱스 스크립트로 두 시간 걸리던 외부 연동이 십오 분이 됐습니다.
이게 시작이었습니다. 그리고 붙여 보니 이유가 더 나왔습니다.
도구를 하나 더 들인 이유
1. 실패했을 때 "그때 그 데이터"가 남습니다
구글 앱스 스크립트 실행 로그에는 제가 Logger.log로 찍어 둔 것만 남습니다. 실패하면 스택트레이스가 담긴 메일이 한 통 오고 끝입니다. 그때 무슨 값이 들어와서 깨진 것인지는 알 수 없습니다. 재현하려고 로그를 더 심고, 다시 돌리고, 또 기다립니다.
n8n은 실행할 때마다 각 단계의 입력과 출력을 통째로 저장합니다. 3주 전에 실패한 건을 열어서 다섯 번째 단계에 무엇이 들어왔는지 눈으로 보고, 값을 고쳐서 거기서부터 다시 실행합니다.
디버깅에 걸리는 시간 차이가 가장 컸습니다. 자동화는 만들 때보다 고칠 때 시간이 더 듭니다.
2. 6분이 지나면 스크립트가 중간에 강제로 멈춥니다
구글 앱스 스크립트는 내 컴퓨터가 아니라 구글 서버에서 대신 돌아갑니다. 남의 서버를 무료로 빌려 쓰는 셈이라, 구글은 한 번 실행에 쓸 수 있는 시간을 정해 두었습니다. 그것이 6분입니다.
6분이 지나면 어떻게 될까요. 경고가 오지도 않고, 잠시 쉬었다가 이어서 하지도 않습니다. 하던 일 중간에서 그냥 끊깁니다. 100건을 처리하던 중이었다면 37건까지만 되고 나머지는 안 된 채로 끝납니다. 게다가 스크립트는 자기가 어디까지 했는지 기억하지 못합니다.
견적서 한 장을 만들어 보내는 일은 몇 초면 끝나니 이 제한 근처에도 가지 않습니다. 문제는 여러 건을 한 번에 도는 일입니다.
그리고 여기서 오해하기 쉬운 부분이 있습니다. 회사에서 유료 구글 워크스페이스를 쓰고 계시다면 이 제한이 없거나 넉넉할 것이라고 생각하기 쉬운데, 6분은 유료 워크스페이스에서도 똑같습니다. 요금제를 올려서 풀리는 항목이 아닙니다.
계정 종류에 따라 달라지는 것은 하루 총량 쪽입니다.
| 항목 | 무료 구글 계정 | 유료 워크스페이스 |
|---|---|---|
| 실행 한 번의 시간 제한 | 6분 | 6분, 동일 |
| 하루 트리거 실행 총량 | 90분 | 6시간 |
| 하루 메일 수신자 수 | 100명 | 1,500명 |
| 하루 외부 API 호출 | 20,000회 | 100,000회 |
전체 수치는 구글 앱스 스크립트 할당량 문서에 있습니다.
그래서 거래처 500곳에 안내를 돌리는 배치를 짜는 순간, 하루 총량이 아니라 실행 하나의 6분에 먼저 걸립니다. 그때부터 "어디까지 했는지 기록해 두었다가 다음 실행에서 이어서 하는" 코드를 직접 짜게 됩니다. 하려던 일과 아무 상관 없는 코드입니다.
n8n에는 이렇게 무조건 6분이라는 시간만으로 실행을 중단시키는 제약은 없습니다.
3. 넘겨줄 수 있는 결과물인가
여기가 저에게는 가장 결정적이었습니다.
구글 앱스 스크립트로 만들어 드리면 결과물이 코드입니다. 사장님은 열어볼 수 없고, 다른 사람이 이어받기도 어렵습니다. 만든 사람 입장에서는 붙잡아 두는 장치처럼 보일 수도 있습니다.
그런데 실제로는 반대로 작동합니다. 계약을 막는 쪽으로요. "이분이 없어지면 우리는 어떡하지"가 작은 회사가 외주를 망설이는 가장 큰 이유입니다. 저도 발주하는 입장에 서 보면 똑같이 망설입니다.
n8n은 화면입니다. 흐름이 그림으로 보이고, "알림 받는 시각을 9시에서 8시로" 정도는 사장님이 직접 바꿉니다. 볼 수 있다는 것만으로 신뢰가 생깁니다. 그리고 신뢰가 생기면 이야기가 다음으로 넘어갑니다.
4. 구글 계정에 매달려 있지 않습니다
구글 앱스 스크립트는 특정 구글 계정에 붙어서 삽니다. 그 계정이 퇴사한 직원 것이라면, 혹은 계정이 정지되면, 자동화가 통째로 사라집니다. 흔한 일이 아니라고 생각하기 쉬운데 실무에서 실제로 일어납니다. 회사가 돌아가는 데 필요한 것이 개인 계정 하나에 걸려 있는 상태는 언젠가 값을 치릅니다.
5. 유지보수를 청구할 근거가 생깁니다
솔직한 이야기를 하나 보태겠습니다. 구글 앱스 스크립트 납품은 "코드 한 번 짜준 것"으로 받아들여져서 월 유지보수비를 말하기가 어렵습니다. 반면 n8n은 돌아가는 서버와 모니터링과 백업이라는 눈에 보이는 실체가 있습니다. 월정액이 자연스럽게 설명됩니다.
도구를 고르는 기준에 이런 것이 들어가도 되나 싶지만, 저는 들어가야 한다고 봅니다. 사업으로 지속되지 않는 방식은 결국 고객의 자동화도 방치되게 만듭니다.
그래도 구글 앱스 스크립트가 이기는 영역
그래서 구글 앱스 스크립트를 버렸느냐 하면 아닙니다. 아래 상황에서는 여전히 구글 앱스 스크립트가 낫습니다.
| 상황 | 이유 |
|---|---|
| 시트 셀을 고칠 때 바로 반응해야 함 | n8n의 시트 연동은 주기적으로 확인하는 방식이라 최소 1분 지연이 생깁니다. 구글 앱스 스크립트 트리거는 즉시 반응합니다 |
| 스프레드시트 커스텀 함수 | n8n으로는 불가능합니다 |
| 구글 문서와 슬라이드를 정교하게 다루기 | 구글 앱스 스크립트 API가 훨씬 깊습니다 |
| 서버 비용 0원이 절대 조건 | 아주 영세한 경우에는 현실적인 판단입니다 |
| 로직이 복잡해서 노드가 50개를 넘어감 | 그 지점부터는 코드가 낫습니다 |
| 시트 안에 사이드바나 입력창이 필요함 | 구글 앱스 스크립트만 가능합니다 |
특히 첫 줄이 중요합니다. 견적 발송 자동화가 구글 앱스 스크립트에 남아 있는 이유가 바로 이것입니다. 시트에서 상태를 바꾼 순간 반응해야 하는 일이고, 여기서는 구글 앱스 스크립트가 압승입니다.
실무 결론, 둘 다 씁니다
경계를 이렇게 정리했습니다.
구글 앱스 스크립트는 스프레드시트 "안쪽" 일. n8n은 시스템과 시스템 "사이" 일.
써 보니 이 경계가 꽤 깔끔하게 맞아떨어집니다. 그리고 섞어도 됩니다. 구글 앱스 스크립트에서 UrlFetchApp으로 n8n의 웹훅을 호출해 주면, 시트 편집에는 즉시 반응하면서 바깥 서비스 연동은 n8n이 처리합니다. 위 표의 첫 줄에 적힌 1분 지연을 이렇게 피해 갑니다.
도구를 갈아탄 것이 아니라 역할을 나눈 것입니다. 잘 돌아가는 것을 굳이 뜯어고칠 이유는 없습니다.
구글 앱스 스크립트를 하던 사람이 딱 하나 헷갈리는 것
넘어가면서 처음에 반드시 막히는 지점이 하나 있어서 적어 둡니다.
구글 앱스 스크립트에서는 for (const row of rows) 라고 내가 루프를 씁니다. n8n에서는 앞 단계가 항목 3개를 내보내면 뒤 단계가 알아서 3번 실행됩니다. 루프문이 없습니다.
편할 때는 아주 편합니다. 그런데 "전체를 한 번에 받아서 합계를 내고 싶을 때" 처음에 꼭 걸립니다. 그 답은 Aggregate 노드와 Merge 노드입니다. 흩어진 항목을 하나로 모아 주는 역할입니다.
코드를 쓰던 사람일수록 루프가 없다는 사실이 더 어색합니다. 이 감각을 먼저 잡고 시작하시는 편이 낫습니다.
그래서
이번에 확인한 것은 도구의 우열이 아니었습니다. 결과물을 남의 손에 넘길 수 있는가였습니다.
두 글 전에 방치된 홈페이지 이야기를 했습니다. 몇 년째 그대로였던 이유가 기술이 없어서가 아니라 손대기가 무서워서였다고요. 자동화도 똑같은 자리에 놓입니다. 잘 돌아가지만 만든 사람 말고는 아무도 열어볼 수 없는 자동화는, 언젠가 방치된 홈페이지와 같은 물건이 됩니다. 돌아가는 동안에는 아무 문제가 없다가, 고쳐야 하는 날 문제가 됩니다.
그래서 저는 지금 두 가지를 같이 봅니다. 이 일이 지금 잘 돌아가는가. 그리고 내가 없어도 이 일이 계속 돌아가는가.
다음 링크는 실제로 만든 워크플로우 이야기로 이어가겠습니다.
비슷한 상황이라면 편하게 물어보세요. hello@codechains.dev
← 목록으로