웹페이지 배포 후 이메일 발송 시스템 구축 (Gmail OAuth에서 Resend로)

소개

시도하고자 했던 것과 그 이유를 알려주세요.

JSHA Master Course를 홍보하는 웹페이지를 만들면서
“신청하기"를 누르면 바로 메일이 날아가는 시스템을 만들고 싶었습니다.

https://www.jshamaster.com/

jsha

사용자 흐름은 단순했습니다.

  1. 웹페이지에서 이름/이메일/신청 내용을 적고

  2. 신청하기 버튼을 누르면

  3. 관리자 메일함과 신청자에게 메일이 보내지는 구조

처음엔 정말 쉽게 생각했다.

“어차피 내 Gmail 계정 있잖아. OAuth로 연결해서 보내면 끝이지 뭐.”

그리고 실제로, 로컬 환경에서는 정말 잘 됐습니다.

2. 배포 후 붕괴 – “로컬에서는 되는데 서버에서는 안 됩니다”

문제는 배포 이후에 발생했습니다.

  • 웹페이지를 Vercel에 배포하고

  • 백엔드는 Render에 구축했습니다.

  • 똑같은 코드인데 메일 서비스에 오류가 발생합니다.

로컬에서 잘 되던 이유는 단순했습니다.

  • 로컬은 내가 직접 브라우저로 로그인하고, OAuth 플로우도 내 PC 기준으로 깔끔하게 진행

하지만 배포된 서버는 브라우저를 열 수 있는 환경도 아니고,
OAuth 토큰을 갱신/관리하는 구조를 제대로 넣지 않으면 안정적으로 돌아갈 수가 없다고 Claude code와 GPT가 알려주네요.

결론적으로:

“Gmail OAuth는 데모 수준까지는 괜찮지만, 실제로는 안된다”

그래서 최종 결론:

실서비스용 이메일은 Gmail이 아니라, 다른 이메일 서비스로 가야 한다.

진행 방법

Resend로 방향 전환

그 시점에서 선택한 것이 Resend였습니다.

  • SMTP 고생 필요 없음 → 그냥 HTTP API

  • OAuth 필요 없음 → API Key 로 가능

실제 세팅 흐름도 간단해 보였습니다.

  1. Resend 가입

  2. 발신 도메인(jshamaster.com) 등록

  3. DNS에 TXT / MX / SPF / DKIM 값 추가

  4. API Key 발급

  5. 서버 코드에서 Resend API 호출

@ vs send 삽질 – “여기서 GPT의 실수”

텍스트 상자와 버튼이 있는 페이지의 스크린샷
dnf 레코드 페이지의 스크린샷

Resend에 있는 MX TXT 값들을 제 domain DNS에 입력을 해줘야합니다.

잘모르니까 AI에게 한번 더 물어보고 진행하는게 나을 것 같아서 GPT에게 물어보면서 진행을 했습니다.

문제의 핵심은 DNS Name 필드에 무엇을 넣느냐였다.

  • Resend 문서에는 send와 같은 서브도메인 예시가 있는데 GPT가 이 부분을 잘못 알려줬습니다.

✅ 실제로 벌어진 일

  • Resend가 보여주는 값은 대략 이런 느낌:

    • Name: send

    • Type: TXT / MX

    • Value: v=spf1 include:... 또는 feedback-smtp...

  • 그런데 GPT가 뭐라고 했냐면:

“여기 Name은 @로 넣으시면 됩니다.”

여기서 @, send 가 뭐냐하면

  • @루트 도메인: jshamaster.com

  • send발송용 서브도메인: send.jshamaster.com

즉, 서브도메인용 레코드를 루트 도메인에 넣으라고 안내한 것입니다.
이게 그대로 “삽질 모드”의 시작이었습니다.

💥 그 결과

  • DNS에 @ 기반 레코드가 쌓이고

  • send.jshamaster.com은 애초에 생기지도 않았고

  • Resend 대시보드는 계속 “Pending” 상태

  • DNS 전파는 오래 걸린다고 해서 괜히 오래 기다림

여기서 역할을 좀 나눠보면:

🧠 GPT의 실수

  • Resend의 서브도메인 기반 구조를 정확히 짚지 않고

  • “일반적인 루트 도메인 패턴(@)”에 끼워 맞춰 설명해버림

👨‍⚕️ 사용자인 나(owen)의 착각/집착

  • “일단 @로 넣었으니, 조금만 더 기다리면 되겠지”에 집착

  • 다른 AI에게 물어볼 생각을 안함

결과적으로, 필요 이상으로 시간을 낭비했다.

상황 정리 – “뭔가 잘못된 것 같다.”

결국, Gemini에게 다시 물어봄

Gemini의 답변

  • @send의 차이:

    • @루트 도메인(jshamaster.com) 그 자체를 의미합니다.

    • send하위 도메인(send.jshamaster.com)을 생성합니다.

  • Amazon SES는 발신용수신용 설정이 다릅니다. 현재 사용자는 발신용(Enable Sending) 설정을 하고 있으며, 이는 send 하위 도메인을 사용합니다.

  • 우리가 만들고자 한 것은:
    send.jshamaster.com 같은 발송 전용 서브도메인 따라서 DNS 설정은 이렇게

예시:

  • Type: TXT
    Name: send
    Value: v=spf1 include:...

  • Type: MX
    Name: send
    Value: feedback-smtp...
    Priority: 10

그리고 기존에 @로 잘못 넣어둔 Resend 관련 레코드들을 수정했습니다.

이 작업을 마치고 나서야,
Resend 대시보드에서 도메인이 Verified로 바뀌었습니다.

“아… 결국 처음에 Name에 send만 제대로 넣었으면,
이 모든 삽질은 없었겠구나.”

결과와 배운 점

보통은 넣으라고 하는데로 넣는데 처음이라 확인 받고 싶어서 AI에게 물어본 것이 삽질의 시작이 될 줄이야...

간단한 건 스스로 해결하자.

웹페이지 수정 작업도 간단한 건 스스로 하는게 시간도 절약되고 token도 아끼고 공부도 되고 1석 2조!!!

다음 사례부터는 ruby 사용 사례로 올리도록 하겠습니다.

1

뉴스레터 무료 구독

👉 이 게시글도 읽어보세요