API로 Gmail 연결하기
Google API 클라이언트 라이브러리, OAuth2 동의, Gmail scope 선택을 다룹니다.
API로 Gmail 연결하기은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
SMTP 대신 Gmail API를 사용하는 이유
기존 이메일 자동화에서는 SMTP/IMAP을 사용하지만, Gmail API는 스레드 읽기, 검색어를 이용한 검색, 라벨 관리, 완전한 인증을 통한 전송 등 훨씬 더 많은 기능을 제공합니다. 또한 OAuth 2.0을 지원하므로 에이전트가 비밀번호를 저장하지 않고, 권한 범위가 제한된 액세스 토큰만 저장하면 됩니다.
Gmail API는 Google Workspace API의 일부이며 google-api-python-client 라이브러리를 통해 접근합니다.
# Install required libraries:
# pip install google-api-python-client google-auth google-auth-oauthlib
# The Gmail API lets agents:
# - List and search messages (labels, queries)
# - Read full message content and attachments
# - Send messages via OAuth (no password needed)
# - Manage labels and threads
# - Watch for new messages via push notifications
print('Gmail API is part of Google Workspace APIs')인증: 서비스 계정과 사용자 인증 비교
Gmail API에는 두 가지 인증 방식이 있습니다:
- 서비스 계정: 도메인 전체 위임을 사용하는 워크스페이스/조직용으로 적합하며 사용자 상호작용이 필요하지 않음
- 사용자 OAuth(OAuth2 동의 화면 사용): 개인 Gmail 계정에 필요하며, 사용자가 한 번 접근을 허용하면 에이전트가 갱신 토큰을 사용함
대부분의 에이전트 자동화에서는 안정성이 높은 서비스 계정을 권장합니다.
# Service Account approach:
# 1. Go to Google Cloud Console -> APIs & Services -> Credentials
# 2. Create a Service Account
# 3. Download the JSON key file
# 4. In Google Workspace Admin: enable domain-wide delegation
# 5. Grant required scopes to the service account
# User OAuth approach:
# 1. Create OAuth 2.0 Client ID (Desktop or Web App type)
# 2. Download credentials.json
# 3. First run: user sees consent screen and grants access
# 4. Agent stores token.json with refresh token for subsequent runs
print('Choose service account for org automation, OAuth for personal Gmail')OAuth2 인증 정보 JSON 구조
Google은 에이전트가 인증을 위해 불러오는 인증 정보를 JSON 파일로 제공합니다. 사용자 OAuth에서는 Google Cloud Console에서 다운로드한 credentials.json 파일을 사용합니다. 이 파일에는 클라이언트 ID, 비밀 키, 리디렉션 URI가 포함되므로 버전 관리 시스템에 절대 커밋하지 마십시오.
# credentials.json structure (User OAuth — Desktop app type):
# {
# "installed": {
# "client_id": "123456789.apps.googleusercontent.com",
# "client_secret": "GOCSPX-abc123xyz",
# "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"],
# "auth_uri": "https://accounts.google.com/o/oauth2/auth",
# "token_uri": "https://oauth2.googleapis.com/token"
# }
# }
# service-account.json structure:
# {
# "type": "service_account",
# "project_id": "my-project",
# "private_key_id": "abc123",
# "private_key": "-----BEGIN PRIVATE KEY-----\n...",
# "client_email": "agent@my-project.iam.gserviceaccount.com",
# "client_id": "..."
# }
print('Store credential files outside your git repository')Gmail API 권한 범위
OAuth 권한 범위는 에이전트가 정확히 무엇에 접근할 수 있는지 정의합니다. 필요한 권한 범위만 요청하십시오. 이것이 최소 권한 원칙입니다. Gmail 권한 범위는 읽기 전용부터 전체 접근까지 다양합니다.
gmail.readonly— 모든 메일 읽기gmail.send— 읽기 없이 전송만gmail.modify— 읽기, 전송, 라벨 수정gmail.compose— 초안만 작성
# Gmail API scope constants
SCOPE_READONLY = 'https://www.googleapis.com/auth/gmail.readonly'
SCOPE_SEND = 'https://www.googleapis.com/auth/gmail.send'
SCOPE_MODIFY = 'https://www.googleapis.com/auth/gmail.modify'
SCOPE_COMPOSE = 'https://www.googleapis.com/auth/gmail.compose'
# Calendar scopes (often used alongside Gmail)
SCOPE_CALENDAR_READ = 'https://www.googleapis.com/auth/calendar.readonly'
SCOPE_CALENDAR_EVENTS = 'https://www.googleapis.com/auth/calendar.events'
# Combine scopes your agent actually needs
AGENT_SCOPES = [
SCOPE_READONLY,
SCOPE_SEND,
SCOPE_CALENDAR_EVENTS
]
print(f'Using {len(AGENT_SCOPES)} scopes')사용자 OAuth: 최초 인증 흐름
사용자가 에이전트를 처음 실행하면 권한을 허용할 수 있도록 브라우저가 열립니다. 에이전트는 그 결과로 생성된 토큰을 token.json에 저장합니다. 이후 실행에서는 저장된 토큰을 불러와 자동으로 갱신하므로 브라우저와 상호작용할 필요가 없습니다.
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
import os
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
def get_credentials(token_file='token.json', creds_file='credentials.json'):
creds = None
# Load existing token if available
if os.path.exists(token_file):
creds = Credentials.from_authorized_user_file(token_file, SCOPES)
# Refresh or re-authenticate if needed
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request()) # auto-refresh
else:
# Opens browser for user consent (first time only)
flow = InstalledAppFlow.from_client_secrets_file(
creds_file, SCOPES
)
creds = flow.run_local_server(port=0)
# Save token for next run
with open(token_file, 'w') as f:
f.write(creds.to_json())
return creds서비스 계정 인증
사용자 상호작용 없이 실행되는 자동화 에이전트에는 서비스 계정이 적합합니다. 에이전트는 비공개 키로 인증한 다음 도메인 전체 위임을 통해 Google Workspace 사용자를 대신하여 인증합니다. 동의 화면이나 브라우저 없이 JSON 키 파일만 사용하면 됩니다.
from google.oauth2 import service_account
import os
SCOPES = [
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.send'
]
def get_service_account_credentials(impersonate_user):
service_account_file = os.environ.get(
'GOOGLE_SERVICE_ACCOUNT_JSON',
'service-account.json'
)
credentials = service_account.Credentials.from_service_account_file(
service_account_file,
scopes=SCOPES
)
# Impersonate a real user (requires domain-wide delegation in Admin)
delegated = credentials.with_subject(impersonate_user)
return delegated
creds = get_service_account_credentials('agent@yourcompany.com')
print('Service account credentials ready')Gmail 서비스 객체 생성
인증 정보를 준비한 후 googleapiclient.discovery.build()를 사용하여 Gmail 서비스 객체를 생성합니다. 이 객체는 모든 Gmail API 호출을 위한 주요 인터페이스입니다. 서비스 이름 'gmail'과 버전 'v1'을 전달하십시오.
from googleapiclient.discovery import build
def build_gmail_service(credentials):
service = build(
'gmail',
'v1',
credentials=credentials,
cache_discovery=False # avoid file warnings in some environments
)
return service
# Full setup: credentials -> service
creds = get_credentials() # or get_service_account_credentials()
gmail = build_gmail_service(creds)
# Test: get user profile
profile = gmail.users().getProfile(userId='me').execute()
print('Email:', profile['emailAddress'])
print('Total messages:', profile['messagesTotal'])Calendar 서비스 객체 생성
Google Calendar에도 동일한 인증 정보 설정을 사용할 수 있습니다. 'calendar'와 'v3'으로 빌드하기만 하면 됩니다. 하나의 에이전트에서 Gmail과 Calendar를 모두 사용해야 한다면 동일한 인증 정보 객체로 두 서비스를 모두 생성하십시오.
from googleapiclient.discovery import build
def build_google_services(credentials):
gmail = build(
'gmail', 'v1',
credentials=credentials,
cache_discovery=False
)
calendar = build(
'calendar', 'v3',
credentials=credentials,
cache_discovery=False
)
return gmail, calendar
# Use both in one agent
creds = get_credentials()
gmail_service, calendar_service = build_google_services(creds)
# Test calendar access
cal_list = calendar_service.calendarList().list().execute()
for cal in cal_list.get('items', []):
print(f'Calendar: {cal["summary"]}')Google API 오류 처리
Google API 오류는 googleapiclient.errors.HttpError로 발생합니다. 오류에는 HTTP 상태 코드와 세부 오류 정보가 담긴 JSON 본문이 포함됩니다. 디버깅할 수 있도록 항상 이를 처리하고 상태와 메시지를 기록하십시오.
from googleapiclient.errors import HttpError
import json
def safe_gmail_call(service, user_id='me'):
try:
profile = service.users().getProfile(userId=user_id).execute()
return profile
except HttpError as e:
status = e.resp.status
try:
error_body = json.loads(e.content.decode())
message = error_body.get('error', {}).get('message', str(e))
except Exception:
message = str(e)
if status == 401:
print('AUTH ERROR: Credentials invalid or expired')
elif status == 403:
print(f'PERMISSION ERROR: {message}')
print('Check scopes and domain-wide delegation settings')
elif status == 429:
print('QUOTA EXCEEDED: Gmail API rate limit hit')
else:
print(f'Gmail API error {status}: {message}')
return NoneGoogle API 할당량 및 요청 빈도 제한
Gmail API에는 사용량 할당량이 있습니다. 기본적으로 하루 10억 할당량 단위가 제공되며, 각 호출에는 작업에 따라 1~100단위가 사용됩니다. 메시지 읽기는 목록 조회보다 비용이 많이 듭니다. 제한을 초과하지 않도록 일괄 요청과 429/503 오류에 대한 지수 백오프를 사용하십시오.
import time
from googleapiclient.errors import HttpError
def gmail_call_with_retry(func, max_retries=5):
for attempt in range(max_retries):
try:
return func()
except HttpError as e:
if e.resp.status in (429, 500, 503):
wait = (2 ** attempt) + 1
print(f'Quota/server error. Waiting {wait}s (attempt {attempt+1})')
time.sleep(wait)
elif e.resp.status == 403:
# Check if it's a quota exceeded vs permission error
import json
body = json.loads(e.content.decode())
reason = body.get('error', {}).get('errors', [{}])[0].get('reason', '')
if reason == 'rateLimitExceeded':
time.sleep(2 ** attempt)
else:
raise # real permission error, don't retry
else:
raise
raise Exception(f'Gmail API call failed after {max_retries} attempts')인증 정보 안전하게 저장하기
token.json, credentials.json 또는 service-account.json을 버전 관리 시스템에 절대 커밋하지 마십시오. 이 파일들을 .gitignore에 추가하십시오. 운영 환경에서는 서비스 계정 JSON을 환경 변수나 비밀 관리 시스템에 저장하고 실행 중에 불러오십시오.
import json
import os
from google.oauth2 import service_account
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
def get_credentials_from_env():
# Load service account JSON from environment variable
sa_json = os.environ.get('GOOGLE_SERVICE_ACCOUNT_JSON')
if not sa_json:
raise EnvironmentError(
'GOOGLE_SERVICE_ACCOUNT_JSON env var not set. '
'Set it to the contents of your service-account.json'
)
sa_info = json.loads(sa_json)
credentials = service_account.Credentials.from_service_account_info(
sa_info,
scopes=SCOPES
)
return credentials
# In production: export GOOGLE_SERVICE_ACCOUNT_JSON=$(cat service-account.json)
creds = get_credentials_from_env()
print('Service account loaded from env var')빠른 확인: 서비스 계정과 사용자 OAuth 비교
Gmail API 인증 방식에 대한 이해도를 확인해 보십시오.
Gmail API 연결 요약
이제 에이전트를 Gmail에 연결할 수 있습니다:
- 사용자 OAuth:
InstalledAppFlow를 사용하고token.json을 저장하며, 이후 실행에서 자동 갱신 - 서비스 계정: JSON 키를 불러오고 위임을 위해
.with_subject(user_email)호출 - 권한 범위: 필요한 최소 범위 요청(
gmail.readonly,gmail.send,calendar.events) build('gmail', 'v1', credentials=creds)로 서비스 생성- API 오류에는
HttpError를 처리하고 429/503에서는 재시도 - 인증 정보 파일은 절대 커밋하지 말고 운영 환경에서는 환경 변수 사용
자주 묻는 질문
“API로 Gmail 연결하기” 강의는 무료인가요?
네 — “API로 Gmail 연결하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
“API로 Gmail 연결하기”에서 뭘 배우나요?
Google API 클라이언트 라이브러리, OAuth2 동의, Gmail scope 선택을 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Agents을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“API로 Gmail 연결하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- API로 Gmail 연결하기
- 프로그래밍으로 이메일 읽기 및 보내기
- 캘린더 일정 생성 및 조회
- 간단한 이메일 도우미 에이전트 만들기