Blogger API와 OAuth 2.0으로 블로그 글 자동 발행하기
블로그 글을 코드로 자동 발행하려면 Blogger API와 OAuth 2.0 인증이 필요합니다. 실제로 이 블로그를 운영하는 자동화 서버가 사용하는 흐름을 기준으로, 액세스 토큰 발급부터 글 생성과 공개 전환까지 정리합니다.
이 글의 가정: Google 계정과 Blogger 블로그가 있고, Google Cloud에서 OAuth 클라이언트(client_id, client_secret)와 refresh token을 이미 발급받았다고 가정합니다. 발급 절차 자체는 Google 공식 인증 흐름을 따릅니다. 비밀값은 코드에 직접 쓰지 말고 환경변수로 관리합니다.
OAuth 2.0 refresh token 흐름
refresh token(장기 보관용 재발급 토큰)은 한 번 발급받아 두고, API를 호출할 때마다 짧은 수명의 access token(실제 요청에 쓰는 접근 토큰)으로 교환해서 사용합니다. 즉 "refresh token → access token → API 호출" 순서입니다.
액세스 토큰 발급
토큰 교환은 Google 토큰 엔드포인트에 grant_type=refresh_token으로 요청합니다. 아래는 비동기 HTTP 클라이언트 httpx를 사용한 예입니다.
import os, httpx
TOKEN_URL = "https://oauth2.googleapis.com/token"
API_BASE = "https://www.googleapis.com/blogger/v3"
async def get_access_token():
async with httpx.AsyncClient(timeout=10.0) as client:
resp = await client.post(TOKEN_URL, data={
"client_id": os.environ["BLOGGER_CLIENT_ID"],
"client_secret": os.environ["BLOGGER_CLIENT_SECRET"],
"refresh_token": os.environ["BLOGGER_REFRESH_TOKEN"],
"grant_type": "refresh_token",
})
resp.raise_for_status()
return resp.json()["access_token"]
여기서는 호출할 때마다 토큰을 새로 받는 단순한 방식을 씁니다. 토큰을 캐싱해 재사용하는 최적화는 별도로 추가할 수 있습니다.
글 생성 (초안 또는 공개)
글 생성은 posts 엔드포인트에 제목과 본문 HTML을 실어 보냅니다. isDraft 파라미터로 초안으로 만들지, 바로 공개할지 정합니다.
async def create_post(blog_id, title, html, as_draft=True):
token = await get_access_token()
params = {"isDraft": "true"} if as_draft else {}
url = f"{API_BASE}/blogs/{blog_id}/posts/"
async with httpx.AsyncClient(timeout=10.0) as client:
resp = await client.post(
url,
headers={"Authorization": f"Bearer {token}"},
json={"title": title, "content": html},
params=params,
)
resp.raise_for_status()
return resp.json()["id"]
초안을 공개로 전환
초안으로 만들어 둔 글은 별도의 publish 엔드포인트로 공개 상태로 바꿉니다.
async def publish_draft(blog_id, post_id):
token = await get_access_token()
url = f"{API_BASE}/blogs/{blog_id}/posts/{post_id}/publish"
async with httpx.AsyncClient(timeout=10.0) as client:
resp = await client.post(url, headers={"Authorization": f"Bearer {token}"})
resp.raise_for_status()
return resp.json().get("url")
정리하면 현재 흐름은 글 생성(create) + 발행(publish)으로 구성됩니다. 즉 새 글을 올리고 공개 상태로 전환하는 데까지가 이 코드의 범위입니다.
재시도 처리
외부 API는 일시적으로 실패할 수 있어, 어떤 오류는 다시 시도하고 어떤 오류는 즉시 멈추는 편이 안전합니다. 인증·권한·잘못된 요청 계열(400, 401, 403, 404)은 다시 보내도 결과가 같으므로 즉시 실패시키고, 서버 일시 오류(500, 502, 503)나 타임아웃만 몇 차례 재시도합니다.
NO_RETRY = {400, 401, 403, 404}
RETRY = {500, 502, 503}
마무리
refresh token으로 access token을 교환한 뒤 글을 생성하고 공개하는 것이 Blogger 자동 발행의 핵심 흐름입니다. 위 예제에서 반복적으로 쓰인 비동기 HTTP 호출 패턴은 httpx AsyncClient로 외부 API 비동기 호출하기에서 더 자세히 다룹니다. 발행 서버의 기반이 되는 FastAPI와 PostgreSQL 연동하기, 그리고 전체 자동화 그림은 유튜브 쇼츠를 Python으로 자동 생성하는 방법을 함께 보면 좋습니다.
이 글이 도움이 됐다면 구독과 공유 부탁드립니다.
댓글
댓글 쓰기