주간 리포트는 내용보다 수집이 일입니다. 여기저기 흩어진 숫자를 모으고, 같은 형식으로 정리하고, 보내는 일이 매주 반복됩니다. 이 반복을 트리거로 옮기면 사람은 리포트를 읽고 판단하는 일만 남습니다.
시연용 초안입니다.
시간 기반 트리거
Apps Script는 코드로 트리거를 만들 수 있습니다. 매주 월요일 아침에 도는 리포트라면 이렇게 설정합니다.
function installWeeklyTrigger() {
ScriptApp.newTrigger("buildWeeklyReport")
.timeBased()
.onWeekDay(ScriptApp.WeekDay.MONDAY)
.atHour(8)
.create();
}
트리거를 코드로 만들어 두면, 다른 환경에 옮길 때도 클릭 없이 재현됩니다.
수집을 한 곳으로
리포트의 핵심은 “어떤 숫자를, 어디서, 어떻게”입니다. 출처가 여럿이어도 수집 함수를 하나의 형태로 통일해 두면 나중이 편합니다.
function collectMetrics() {
return {
week: weekLabel(),
inquiries: countRows("문의"),
delivered: countRows("완료"),
pending: countRows("대기"),
};
}
function countRows(sheetName) {
const sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);
return Math.max(0, sheet.getLastRow() - 1); // 헤더 제외
}
문서로 출력
수집한 값을 Google Docs 템플릿에 채웁니다. 자리표시자를 정해 두고 치환하면 형식이 매주 일정합니다.
function buildWeeklyReport() {
const metrics = collectMetrics();
const doc = DocumentApp.create(`주간 리포트 — ${metrics.week}`);
const body = doc.getBody();
body.appendParagraph(`주간 리포트 (${metrics.week})`).setHeading(
DocumentApp.ParagraphHeading.HEADING1,
);
body.appendParagraph(`문의: ${metrics.inquiries}건`);
body.appendParagraph(`완료: ${metrics.delivered}건`);
body.appendParagraph(`대기: ${metrics.pending}건`);
doc.saveAndClose();
}
실패를 조용히 넘기지 않기
자동화에서 가장 위험한 것은 조용한 실패입니다. 트리거가 멈춰도 아무도 모르면, 리포트가 안 와도 한참 뒤에야 알아챕니다. 그래서 실행 끝에 짧은 확인 신호를 남깁니다.
function buildWeeklyReport() {
try {
// ... 위 로직 ...
} catch (err) {
GmailApp.sendEmail(Session.getActiveUser().getEmail(),
"주간 리포트 실패", String(err));
throw err;
}
}
정리
리포트 자동화는 화려할 필요가 없습니다. 수집을 한 형태로 모으고, 출력 형식을 고정하고, 실패를 알 수 있게 하면 충분합니다. 남는 시간은 숫자를 해석하는 데 씁니다.