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.com | ABC Corp | 대리 | 활성 | |
| 이영희 | younghee@example.com | XYZ Inc | 과장 | 활성 | |
| 박민수 | minsu@example.com | DEF 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 태그를 사용하여 이미지(), 링크(), 테이블(
InlineImage 옵션을 사용하여 첨부할 수 있습니다. 단, 과도한 이미지 사용은 스팸 필터에 걸릴 수 있으므로 텍스트와 이미지의 적절한 비율을 유지하세요.
Q3: 발송 실패한 이메일만 다시 보내려면 어떻게 하나요?
위 스크립트에서는 발송 성공 시 ‘발송완료’, 실패 시 ‘오류: 메시지’가 발송여부 열에 기록됩니다. 재발송을 위해서는 필터 조건에서 발송여부가 ‘오류’로 시작하는 행만 선택하도록 수정하면 됩니다. 예를 들어, if (row[sentIdx].toString().startsWith(‘오류’)) 조건을 추가한 재발송 전용 함수를 만들면 실패 건만 효율적으로 재처리할 수 있습니다.