Google Sheets와 Gmail로 메일 병합 설정하기: Apps Script를 활용한 맞춤형 대량 이메일 발송 가이드

Google Sheets와 Gmail 메일 병합이란?

메일 병합(Mail Merge)은 스프레드시트의 데이터를 기반으로 수신자별 맞춤형 이메일을 대량 발송하는 기능입니다. Google Sheets와 Gmail을 Apps Script로 연결하면 별도의 유료 도구 없이도 강력한 메일 병합 시스템을 구축할 수 있습니다. 필터 조건을 추가하면 특정 조건에 맞는 수신자에게만 이메일을 보낼 수 있어 더욱 효율적인 커뮤니케이션이 가능합니다.

사전 준비 사항

  • Google 계정 (Gmail 및 Google Sheets 접근 권한)- 수신자 정보가 포함된 Google Sheets 스프레드시트- 기본적인 JavaScript 문법 이해 (Apps Script는 JavaScript 기반)- Gmail 일일 발송 한도 확인 (무료 계정: 100통/일, Workspace: 1,500통/일)

단계별 메일 병합 설정 가이드

1단계: Google Sheets에 수신자 데이터 준비

새 Google Sheets를 열고 첫 번째 행에 헤더를 입력합니다. 아래와 같은 구조를 권장합니다.

이름이메일회사명직책상태발송여부
김철수chulsoo@example.comABC Corp대리활성
이영희younghee@example.comXYZ Inc과장활성
박민수minsu@example.comDEF Ltd사원비활성
**상태** 열은 필터 조건에 사용되며, **발송여부** 열은 중복 발송을 방지하는 데 활용됩니다.

2단계: Apps Script 편집기 열기

Google Sheets 상단 메뉴에서 확장 프로그램 → Apps Script를 클릭합니다. 새 프로젝트가 열리면 기본 코드를 모두 삭제하고 아래 스크립트를 붙여넣습니다.

3단계: 메일 병합 스크립트 작성

다음은 필터 조건과 개인화 기능이 포함된 메일 병합 스크립트입니다. function sendMailMerge() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(‘Sheet1’); const data = sheet.getDataRange().getValues(); const headers = data[0];

// 열 인덱스 설정 const nameIdx = headers.indexOf(‘이름’); const emailIdx = headers.indexOf(‘이메일’); const companyIdx = headers.indexOf(‘회사명’); const titleIdx = headers.indexOf(‘직책’); const statusIdx = headers.indexOf(‘상태’); const sentIdx = headers.indexOf(‘발송여부’);

let sentCount = 0;

for (let i = 1; i < data.length; i++) { const row = data[i];

// 필터 조건: 상태가 '활성'이고 아직 발송하지 않은 경우만
if (row[statusIdx] !== '활성' || row[sentIdx] === '발송완료') {
  continue;
}

const name = row[nameIdx];
const email = row[emailIdx];
const company = row[companyIdx];
const jobTitle = row[titleIdx];

// 이메일 템플릿 (HTML 형식)
const subject = name + '님, ' + company + ' 관련 안내드립니다';
const htmlBody = ''
  + '<p>안녕하세요, **' + name + '** ' + jobTitle + '님.

’ + ” + company + ‘에서 근무하고 계신 ’ + name + ‘님께 특별히 안내드립니다. ’ + ‘자세한 내용은 아래 링크를 참고해 주세요. ’ + ‘감사합니다. ’ + ”;

try {
  GmailApp.sendEmail(email, subject, '', {
    htmlBody: htmlBody,
    name: '발신자 이름'
  });
  
  // 발송 완료 표시
  sheet.getRange(i + 1, sentIdx + 1).setValue('발송완료');
  sheet.getRange(i + 1, sentIdx + 2).setValue(new Date());
  sentCount++;
  
  // API 제한 방지를 위한 딜레이
  Utilities.sleep(1000);
} catch (e) {
  sheet.getRange(i + 1, sentIdx + 1).setValue('오류: ' + e.message);
}

}

SpreadsheetApp.getUi().alert(sentCount + ‘통의 이메일이 발송되었습니다.’); }

4단계: 고급 필터 조건 추가

더 복잡한 필터 조건이 필요한 경우 아래와 같이 조건 함수를 분리할 수 있습니다. function shouldSendEmail(row, headers) { const status = row[headers.indexOf(‘상태’)]; const sent = row[headers.indexOf(‘발송여부’)]; const company = row[headers.indexOf(‘회사명’)];

// 다중 필터 조건 const isActive = status === ‘활성’; const notSent = sent !== ‘발송완료’; const isTargetCompany = [‘ABC Corp’, ‘XYZ Inc’].includes(company);

return isActive && notSent && isTargetCompany; }

5단계: 권한 승인 및 테스트 실행

  • Apps Script 편집기에서 실행 버튼을 클릭합니다.- 처음 실행 시 Google 계정 권한 승인 팝업이 표시됩니다.- 고급 → 프로젝트명으로 이동을 클릭하여 권한을 승인합니다.- 테스트를 위해 먼저 본인의 이메일 주소로 1~2건만 발송해 봅니다.- 이메일 내용과 형식을 확인한 후 전체 발송을 진행합니다.

6단계: 자동 실행 트리거 설정 (선택 사항)

정기적으로 메일을 발송해야 한다면 시간 기반 트리거를 설정할 수 있습니다. - Apps Script 편집기 왼쪽 메뉴에서 **트리거(시계 아이콘)**를 클릭합니다.- **트리거 추가**를 선택합니다.- 함수 선택: sendMailMerge, 이벤트 소스: 시간 기반, 원하는 주기를 설정합니다. ## 필터 조건 활용 팁 - **날짜 기반 필터**: 특정 날짜 이후에 등록된 사용자에게만 발송- **그룹 기반 필터**: 부서, 지역, 등급별로 다른 템플릿 적용- **조건부 콘텐츠**: 수신자 정보에 따라 이메일 본문 내용을 동적으로 변경- **A/B 테스트**: 짝수/홀수 행에 따라 다른 제목줄을 적용하여 성과 비교 ## 주의사항 및 제한사항 - Gmail 무료 계정은 하루 100통, Google Workspace는 1,500통까지 발송 가능합니다.- 대량 발송 시 스팸으로 분류되지 않도록 발송 간격(Utilities.sleep)을 설정하세요.- 수신자 동의 없는 마케팅 이메일은 개인정보보호법에 위반될 수 있습니다.- 발송 전 반드시 소규모 테스트를 진행하세요. ## 자주 묻는 질문 (FAQ)

Q1: Gmail 일일 발송 한도를 초과하면 어떻게 되나요?

일일 한도를 초과하면 Gmail API에서 오류가 반환되며, 해당 시점 이후의 이메일은 발송되지 않습니다. 위 스크립트에서는 try-catch 블록으로 오류를 처리하고 스프레드시트에 오류 메시지를 기록합니다. 한도가 초과된 경우 24시간 후에 다시 시도하거나, 발송 대상을 여러 날에 나누어 진행하세요. Google Workspace 계정으로 업그레이드하면 일일 1,500통까지 발송할 수 있습니다.

Q2: HTML 이메일 템플릿에 이미지나 링크를 포함할 수 있나요?

네, 가능합니다. htmlBody 변수에 표준 HTML 태그를 사용하여 이미지(), 링크(), 테이블(

) 등을 자유롭게 삽입할 수 있습니다. 이미지는 외부 URL을 참조하거나 Apps Script의 InlineImage 옵션을 사용하여 첨부할 수 있습니다. 단, 과도한 이미지 사용은 스팸 필터에 걸릴 수 있으므로 텍스트와 이미지의 적절한 비율을 유지하세요.

Q3: 발송 실패한 이메일만 다시 보내려면 어떻게 하나요?

위 스크립트에서는 발송 성공 시 ‘발송완료’, 실패 시 ‘오류: 메시지’가 발송여부 열에 기록됩니다. 재발송을 위해서는 필터 조건에서 발송여부가 ‘오류’로 시작하는 행만 선택하도록 수정하면 됩니다. 예를 들어, if (row[sentIdx].toString().startsWith(‘오류’)) 조건을 추가한 재발송 전용 함수를 만들면 실패 건만 효율적으로 재처리할 수 있습니다.

다른 도구 둘러보기

ChatGPT 사례 연구: 로펌이 계약서 검토를 자동화해 연간 2,000시간을 절감한 방법 사례 ChatGPT 사례 연구: 매출 0원 스타트업이 AI로 전체 콘텐츠 마케팅 엔진을 구축한 방법 사례 ChatGPT로 회의 준비하는 방법: 회의실에서 가장 준비된 사람이 되는 리서치 브리핑 방법 Claude Code로 API 엔드포인트 생성하는 방법: 스키마에서 테스트된 엔드포인트까지 몇 분 만에 방법 Claude로 엔터프라이즈 RAG 시스템 구축하는 방법: 직원 질문에 답하는 지식 기반 방법 Claude API로 콘텐츠 모더레이션 구축하는 방법: 확장 가능한 자동 안전 시스템 방법 Claude API 함수 호출 사용 방법: AI 에이전트 구축을 위한 Tool Use 완전 가이드 방법 ElevenLabs로 고객 서비스 IVR 구축하는 방법: 사람처럼 들리는 AI 음성 자동화 방법 ElevenLabs로 제품 데모 보이스오버 만드는 방법: SaaS 데모를 위한 전문 내레이션 방법 Gemini 멀티모달 프롬프팅 모범 사례: 이미지, 영상, 문서 분석으로 결과 얻기 모범사례 Gemini 사례 연구: 프로덕트 팀이 Deep Research로 200개 사용자 인터뷰를 3일 만에 종합한 방법 사례 Gemini 사례 연구: 부동산 회사가 Deep Research로 15개 도시 시장 분석을 수행한 방법 사례 Gemini로 코드 리뷰와 리팩토링하는 방법: AI 기반 코드 품질 개선 방법 Genspark Sparkpage 정리 모범 사례: 개인 지식 관리 시스템 구축 모범사례 Genspark으로 경쟁사 가격 분석하는 방법: AI 기반 가격 인텔리전스 방법 Grok 실시간 뉴스 분석 및 팩트체킹 모범 사례 모범사례 Grok 학술 연구 및 문헌 탐색 모범 사례: X/Twitter를 활용한 학술 인텔리전스 모범사례 Grok 콘텐츠 전략 모범 사례: 트렌딩 토픽을 정점 전에 파악하고 수요를 선점하는 콘텐츠 만들기 모범사례 Grok 사례 연구: DTC 뷰티 브랜드가 실시간 소셜 리스닝으로 제품 출시를 구한 이야기 사례 Grok 사례 연구: 제약회사가 신약 출시 중 환자 센티먼트를 추적해 FDA보다 48시간 먼저 안전 신호를 감지한 방법 사례