Skip to content

Latest commit

 

History

History
102 lines (69 loc) · 4.6 KB

File metadata and controls

102 lines (69 loc) · 4.6 KB

Gmail D-day 이메일 알림 설정

이 문서는 이슈 #50의 백엔드 코드를 실제 Supabase 프로젝트와 Gmail 발송 계정에 연결하는 순서다. 비밀값은 GitHub, 문서, 채팅, 프론트엔드 환경 변수에 넣지 않는다.

1. Google Cloud 준비

  1. 알림 발송 전용 Gmail 계정을 만든다. 개인 메일 계정은 사용하지 않는다.
  2. Google Cloud Console에서 프로젝트를 만들고 Gmail API를 활성화한다.
  3. OAuth 동의 화면을 설정한다.
  4. OAuth Client ID와 Client Secret을 만든다.
  5. 전용 Gmail 계정으로 https://www.googleapis.com/auth/gmail.send 범위를 한 번 승인하고, 오프라인 발송에 사용할 refresh token을 발급한다.
  6. 테스트 상태의 OAuth 앱은 refresh token 만료 제한이 생길 수 있으므로 실제 운영 전 Production 전환과 Google 검증 필요 여부를 확인한다.

현재 탐라모아의 Google 로그인 Client ID와 Gmail 발송용 OAuth Client는 역할이 다르다. 로그인 사용자가 Gmail 발송 권한을 승인하는 것이 아니라 전용 발송 계정 한 개만 승인한다.

2. Supabase 데이터베이스 반영

Supabase CLI로 연결된 원격 DB에 새 마이그레이션을 순서대로 반영한다.

supabase db push --linked

반영 후 확인할 것:

  • user_settings.email_enabled가 기본값 false로 생성됨
  • bookmarksemail_sent_day_markers 등 이메일 상태 필드가 생성됨
  • claim_bookmark_email_notification, mark_bookmark_email_notification_sent, mark_bookmark_email_notification_failed 함수가 생성됨
  • Vault 준비 후 20260720091000_schedule_deadline_email_function.sql을 적용하면 send-deadline-emails-daily Cron이 생성됨
  • 20260720092000_grant_email_worker_access.sql로 서비스 역할에 북마크·설정 읽기 권한만 부여됨

3. Edge Function Secrets 등록

Supabase Dashboard → Edge Functions → Secrets에서 다음 값을 등록한다.

GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET
GOOGLE_REFRESH_TOKEN
GMAIL_SENDER_EMAIL
EMAIL_CRON_SECRET

EMAIL_CRON_SECRET은 다른 곳에서 사용하지 않는 충분히 긴 임의 문자열로 만든다. SUPABASE_URL과 Supabase secret/service role key는 배포된 Edge Function에 기본 제공되므로 별도로 코드에 넣지 않는다.

4. Edge Function 배포

Supabase CLI에서 프로젝트를 연결한 뒤 배포한다.

supabase functions deploy send-deadline-emails

supabase/config.toml에서 플랫폼 JWT 검사는 끄지만, 함수 자체가 x-cron-secret을 비교해 허용된 Cron 요청만 처리한다.

5. 수동 호출 확인

Supabase Dashboard의 Edge Function 테스트 기능 또는 HTTP 요청으로 POST 호출한다.

POST https://프로젝트주소.supabase.co/functions/v1/send-deadline-emails
x-cron-secret: Supabase Secrets에 등록한 EMAIL_CRON_SECRET

정상 응답 예:

{
  "candidates": 1,
  "sent": 1,
  "failed": 0,
  "skipped": 0,
  "deferred": 0
}

잘못된 시크릿이면 HTTP 401이어야 한다.

개인 Gmail의 일일 발송 제한을 보호하기 위해 한 번 실행할 때 마감이 가까운 순서로 최대 450통을 처리한다. deferred가 1 이상이면 처리하지 못한 후보가 있다는 뜻이므로 다음 실행 결과와 Gmail 발송 한도를 확인한다.

6. Supabase Cron 생성

프로젝트 Vault에 아래 두 값을 저장한다. 실제 시크릿은 문서나 SQL 마이그레이션 파일에 직접 쓰지 않는다.

  • email_function_url: https://프로젝트주소.supabase.co/functions/v1/send-deadline-emails
  • email_cron_secret: Edge Function Secrets의 EMAIL_CRON_SECRET과 같은 값

그다음 supabase/migrations/20260720091000_schedule_deadline_email_function.sql을 적용한다. 이 마이그레이션은 다음 Cron을 만든다.

  • 이름: send-deadline-emails-daily
  • 일정: 0 0 * * *
  • 의미: 매일 00:00 UTC, 한국 시간 오전 9시
  • 방식: Vault의 함수 URL로 POST
  • 헤더: Vault의 email_cron_secretx-cron-secret으로 전달

Supabase Dashboard → Integrations → Cron에서 생성 여부를 확인하고, Run now로 한 번 실행한 뒤 Cron 실행 기록과 Edge Function 로그를 확인한다.

7. 테스트 사용자 준비

프론트엔드 수신 동의 UI가 합쳐지기 전에는 Supabase Table Editor에서 테스트 사용자의 user_settings.email_enabledtrue로 바꾼다. 운영 사용자의 값을 동의 없이 바꾸면 안 된다.

테스트가 끝나면 docs/tasks.md의 “이슈 #50 Gmail 이메일 알림 완료 후 테스트 방법”을 순서대로 확인한다.