# 오늘 일정을 매일 이메일로 받기

개인 Google 계정의 기본 캘린더를 읽어 같은 계정의 메일로 보냅니다. 기본값은 **매일 한국 시간 오전 7~8시 사이**, 체크리스트 세 문장입니다. 정확한 분 단위 예약은 아니며, 처음 설정한 뒤에는 시트와 AI 채팅을 닫아도 Google Apps Script가 실행합니다.

## Google 시트에서 사용하기

강좌에 연결된 원본 파일을 **내 드라이브에 복사**하고 PC 브라우저로 엽니다. 복사된 시트에는 자동화 코드가 함께 들어 있으므로 코드 편집기를 열 필요가 없습니다. 원본을 보기만 하거나 공유받은 원본에서 실행하는 방식은 아닙니다.

1. 위쪽 **일정 메일 → 시작하기**를 누릅니다. 메뉴가 바로 보이지 않으면 잠시 기다리거나 시트를 새로고침합니다.
2. Google이 요청하는 권한을 확인하고 승인합니다. 승인을 마친 뒤 실행이 이어지지 않았다면 같은 메뉴를 다시 눌러도 됩니다. 회사·학교 계정에서 관리자 정책으로 막히면 해당 계정에서는 사용할 수 없습니다.
3. **자동 발송 중**이 표시되면 받은편지함 또는 스팸함에서 `[테스트] [오늘 일정]` 메일을 확인합니다.

일정이 없어도 시작할 수 있습니다. 이때 메일에는 “오늘 등록된 일정은 없습니다.”와 체크리스트가 표시됩니다. 받는 주소와 시간대는 입력하지 않습니다. 실행 계정 본인에게만 보내며 기본 캘린더 외의 공유·구독·공휴일 캘린더는 읽지 않습니다.

### 바꾸거나 멈추기

- **받을 시각(B8)**: 0~23의 정수. 8이면 한국 시간 오전 8~9시 사이입니다.
- **받을 요일(B9)**: `매일` 또는 `평일만`. 평일만이면 토·일 예약 발송을 생략합니다.
- **체크리스트(B13:B22)**: 200자 이내의 문장을 1~10개 입력합니다. 사용하지 않는 줄은 비워 둡니다.
- 셀을 바꾼 뒤 **일정 메일 → 설정 적용**을 누릅니다. 이미 시작했다면 다음 예약부터 반영하고, 중지 상태라면 설정만 저장합니다. 설정 적용으로 테스트 메일을 보내거나 멈춘 예약을 다시 시작하지 않습니다.
- **중지하기**는 이 파일의 자동 메일 예약만 중지합니다. 설정과 캘린더 일정은 남으며, 다시 시작할 때는 **시작하기**를 누릅니다.
- **상태 확인**은 위쪽 상태와 아래 테스트 발송·예약·자동 발송 기록을 새로 불러옵니다. 시트의 기록은 메뉴를 사용할 때 갱신하며, 메일이 실제로 받은편지함에 도착했는지는 읽지 않습니다.

파일을 열기만 해서는 메일을 보내거나 예약하지 않습니다. 반복해서 시작해도 설정용 테스트 메일과 예약을 계속 추가하지 않습니다. 테스트 발송 후 예약 생성만 실패했다면 다시 시작하기를 눌러 예약 설정을 이어 갈 수 있습니다. 재시작해도 이전 설정용 테스트는 다시 보내지 않습니다.

## 파일 구성과 권한

배포용 파일은 `일정 메일` 탭과 연결된 `Code.gs`, `appsscript.json`으로 구성합니다. 시트 설정은 실행 시점에 검증해 해당 스크립트의 설정 저장소로 저장합니다. 예약 실행은 이 저장된 값만 읽고 활성 시트에 의존하지 않습니다.

명시한 권한은 **현재 시트 수정**, **캘린더 읽기 전용**, **메일 보내기**, **실행 계정 이메일 확인**, **시간 예약 관리**입니다. 다른 스프레드시트 전체에 접근하거나 받은편지함을 읽는 권한은 사용하지 않습니다. 일정을 생성·수정·삭제하지 않으며 개인 일정 내용을 AI에 전달하지 않습니다. 필요한 권한을 일부만 허용한 경우 시작·예약 등록 전에 누락된 범위를 확인합니다.

### 제작·관리 메모

- 원본 파일은 실행하지 않은 깨끗한 상태로 배포합니다. 실제 Google 실행은 별도 복사본에서 확인합니다.
- 시트의 A26/A27/A28 라벨은 각각 `최근 시험 발송` / `자동 발송 예약` / `최근 자동 발송`이며, 값은 B26/B27/B28입니다. B5에는 전체 상태를 표시합니다. 각 값 칸이 D열까지 병합되어 있어도 왼쪽 첫 셀만 갱신합니다.
- 복사본의 파일 ID가 저장된 ID와 다르면 이전 사용자의 계정·예약·발송 기록과 저장된 설정을 초기화합니다. 파일 안의 설정 셀은 보존하며 새 사용자가 명시적으로 시작해야 합니다. 같은 파일을 공유받은 다른 계정은 이미 시작한 사용자의 설정을 덮어쓸 수 없습니다.
- 중지는 발송 비활성 상태를 먼저 기록합니다. Google의 예약 삭제가 일시 실패하더라도 다음 시간 예약에서 메일을 보내지 않으며 중지 메뉴를 다시 눌러 정리할 수 있습니다.
- 다른 함수의 예약과 다른 프로젝트는 수정하지 않습니다. 예전에 별도 프로젝트로 만든 자동화가 있다면 그 프로젝트에서 별도로 중지해야 합니다.
- 시트 메뉴는 PC 웹 사용을 기준으로 합니다. Google Sheets 모바일 앱에 동일한 메뉴가 제공된다고 가정하지 않습니다.

## 직접 코드를 사용하는 경우

이 부분은 배포 파일 제작·코드 수정용입니다. 일반 독자의 기본 진행에는 필요하지 않습니다.

독립 Apps Script 프로젝트에서도 `Code.gs`의 기본 설정으로 사용할 수 있습니다. 코드와 명시 권한 파일을 넣고 `setupDailyMail`을 실행하면 본인에게 테스트를 요청하고 매일 예약 하나를 만듭니다. 시트의 연결 코드가 있어도 독립 실행은 시트를 요구하지 않습니다. 승인 요청을 줄이려면 독립 프로젝트의 권한 목록에서 `spreadsheets.currentonly`를 제외할 수 있습니다.

| 함수 | 용도 |
| --- | --- |
| `setupDailyMail` | 독립 프로젝트의 처음 설정·재시도. 테스트 요청 후 예약 하나를 확인합니다. |
| `previewDailyMail` | 발송 없이 로그로 내용을 확인합니다. |
| `sendTestMail` | 명시적으로 실행할 때마다 테스트 한 통을 요청합니다. 예약은 만들지 않습니다. |
| `installDailyTrigger` | 발송 없이 예약만 만들거나 변경합니다. |
| `sendDailyMail` | 시간 예약용. 한국 날짜 기준 같은 날 중복 실행을 건너뜁니다. |
| `stopDailyMail` | 해당 프로젝트에서 실행 계정이 만든 이 메일 예약만 중지합니다. |

## 검증 범위

로컬 테스트는 가상 Google 서비스로 복사본 초기화, 시트 설정 검증, 반복 시작·중지, 설정 변경, 누락 권한, 부분 실패 재시도, 활성 시트 없는 예약 실행, 한국 날짜 경계, 메일 본문과 중복 방지를 검증합니다. 실제 Google 계정의 승인 화면, 실제 메일 도착, 다음 예약 실행은 별도로 확인해야 하며 이 로컬 테스트의 통과와 구분합니다.

메일 발송 요청과 기록 저장 사이에 실행이 강제 중단되는 상황까지 완벽한 중복 방지를 보장하지는 않습니다. 발송 요청 시각은 실제 수신 시각과 다릅니다.

## 공식 자료

- [시트에 연결된 스크립트와 복사](https://developers.google.com/apps-script/guides/bound)
- [사용자 메뉴](https://developers.google.com/apps-script/guides/menus)
- [시간 기반 예약](https://developers.google.com/apps-script/guides/triggers/installable)
- [권한 범위와 누락 권한 확인](https://developers.google.com/apps-script/concepts/scopes)
