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(‘오류’)) 조건을 추가한 재발송 전용 함수를 만들면 실패 건만 효율적으로 재처리할 수 있습니다.

다른 도구 둘러보기

Grok 실시간 뉴스 분석 및 팩트체킹 베스트 프랙티스 가이드 모범사례 Devin 멀티파일 리팩토링 위임 베스트 프랙티스: 명세서, 브랜치 격리, 코드 리뷰 체크포인트 완벽 가이드 모범사례 Bolt 케이스 스터디: 솔로 개발자가 주말 48시간 만에 풀스택 SaaS MVP를 출시한 방법 사례 미드저니 캐릭터 컨셉아트 케이스 스터디: 인디 게임 스튜디오가 200개 에셋의 일관성을 유지한 워크플로우 사례 Antigravity AI 설치 및 설정 가이드: Python SDK, API 키 관리, Blender 통합까지 가이드 Runway Gen-3 Alpha AI 영상 생성 완벽 가이드: 계정 설정부터 렌더링 내보내기까지 가이드 Replit Agent vs Cursor AI vs GitHub Copilot Workspace 비교: 솔로 개발자를 위한 풀스택 프로토타이핑 완벽 가이드 (2026) 비교 v0에서 재사용 컴포넌트 블록으로 멀티페이지 SaaS 랜딩 사이트 만들기 완벽 가이드 방법 Kling AI vs Runway Gen-3 vs Pika Labs 비교: AI 영상 생성 품질·가격·제어력 완벽 분석 (2026) 비교 Claude 3.5 Sonnet vs GPT-4o vs Gemini 1.5 Pro 장문 요약 비교: 컨텍스트 윈도우, 정확도, 토큰 비용 완벽 분석 (2025) 비교 Midjourney v6 vs DALL-E 3 vs Stable Diffusion XL 제품 사진 비교: 포토리얼리즘, 프롬프트 제어, 이미지당 비용 분석 비교 Runway Gen-3 Alpha vs Pika 1.0 vs Kling AI 비교: 숏폼 영상 광고 제작을 위한 모션 품질·프롬프트 정확도·초당 가격 완벽 분석 (2026) 비교 BMI 계산기 - 무료 온라인 체질량지수 측정 도구 계산기 은퇴 저축 계산기 - 무료 온라인 노후 자금 시뮬레이터 계산기 401(k) 클리프 베스팅 스케줄이란? 퇴사 시 회사 매칭금이 어떻게 달라지는지 쉽게 설명 설명 중소기업을 위한 13주 현금흐름 예측 모범 사례: 주간 업데이트, 수금 추적, 시나리오 플래닝 모범사례 다점포 레스토랑 그룹 매입채무 자동화 사례: OCR 캡처·승인 라우팅·주간 지급으로 인보이스 처리 시간 단축 사례 아마존 PPC 사례: 프라이빗 라벨 건강기능식품 브랜드가 네거티브 키워드 마이닝과 Exact Match로 ACOS를 낮춘 방법 사례 Antigravity vs Jasper vs Copy.ai 비교: AI 브랜드 보이스 일관성, 콘텐츠 품질 및 협업 기능 완벽 분석 (2026) 비교 아파트 승인 준비도 퀴즈: 첫 자취생을 위한 신용점수·소득·코사이너 셀프 진단 자가진단