공정 엔지니어의 AI 엔지니어로의 성장 기록

비전공자의 바이브 코딩/일상 & 기초

클로드코드(Claude Code)로 주식 분석 웹 서비스 만들기 : #5. 카카오톡 연동하기

ai-process-engineer 2026. 5. 5. 21:03

 

클로드코드(Claude Code)로
주식 분석 웹 서비스 만들기
— #5. 카카오톡 연동하기

분석 기능까지 완성됐으니 이제 매수 신호가 발생했을 때 카카오톡으로 알림을 받는 기능을 붙일 차례다. 카카오 비즈니스 채널 없이 무료로 구현할 수 있고, 본인뿐 아니라 친구에게도 알림을 보낼 수 있다. 설정 과정에서 마주친 에러들과 해결 방법도 함께 정리했다.

01 사용한 프롬프트 모음

아래 프롬프트를 순서대로 입력하면 이 글의 카카오톡 연동 기능 전체를 재현할 수 있다.

Prompt 01 — 카카오 OAuth 토큰 발급 백엔드
# FastAPI로 카카오 OAuth 2.0 로그인 흐름을 구현해줘.
# GET /api/kakao/auth-url : scope=talk_message,friends 인가 URL 반환
# GET /api/kakao/callback : 인가 코드 → 토큰 교환, kakao_tokens.json에 저장
# 토큰 교환 시 client_secret 필수 포함, prompt=consent로 동의 화면 강제 표시
# 콜백 응답은 HTMLResponse + charset utf-8로 처리해줘 (한글 깨짐 방지)
Prompt 02 — 토큰 저장 및 자동 갱신
# 카카오 토큰을 서버의 kakao_tokens.json 파일에 저장하고
# access_token 만료(401) 시 refresh_token으로 자동 갱신하는 로직을 만들어줘.
# refresh_token도 새로 발급되면 함께 갱신 저장.
# access_token ~6시간, refresh_token ~2개월 만료 주기 고려.
Prompt 03 — 나에게 보내기 + 친구에게 보내기
# 카카오톡 메시지 발송 함수 2개를 구현해줘.
#
# 1. send_to_me(title, description)
#    POST https://kapi.kakao.com/v2/api/talk/memo/default/send
#    text 타입 템플릿, "확인하기" 버튼 포함
#
# 2. send_to_friends(friend_uuids, title, description)
#    POST https://kapi.kakao.com/v1/api/talk/friends/message/default/send
#    receiver_uuids 파라미터로 발송 대상 지정
#
# 3. send_alert() — 위 두 함수를 묶어 나에게 + 동의한 친구 전체에게 동시 발송
Prompt 04 — 친구 초대 콜백 및 친구 목록 조회
# 친구가 앱에 동의할 수 있는 별도 콜백 엔드포인트를 만들어줘.
# GET /api/kakao/friend-callback : 토큰 교환 후 저장하지 않고 동의만 등록
# GET /api/kakao/friends : 친구 목록 조회 (앱 심사 전 팀원만 노출)
# GET /api/kakao/status : 연동 상태 확인 (토큰 유무)
Prompt 05 — 프론트엔드 카카오 연동 UI
# Next.js 14 + TypeScript + Tailwind CSS로 카카오 연동 UI를 만들어줘.
# - "카카오 계정 연동하기" 버튼: auth-url 호출 → 새 창(500×600)으로 열기
# - 연동 상태 표시 (연동됨 / 미연동)
# - 친구 목록 새로고침 버튼
# - 테스트 발송 버튼: POST /api/kakao/test 호출
# next.config.js에 /api/* → http://localhost:8005/api/* 프록시 설정도 포함해줘.
팁 — Prompt 01 실행 전에 카카오 Developers에서 앱 생성, REST API 키 발급, Redirect URI 등록, 로그인 활성화, 동의항목 설정을 먼저 완료해야 한다. 아래 섹션에서 순서대로 안내한다.

02 사용하는 카카오 API 개요

카카오 비즈니스 채널 없이 개인 프로젝트 수준에서 사용할 수 있는 API만 활용한다. 모두 무료다.

API 용도 제약
카카오 로그인 (OAuth 2.0) access_token / refresh_token 발급 무료, 제한 없음
나에게 보내기 본인 카카오톡으로 알림 무료, 제한 없음
친구 목록 조회 발송 대상 UUID 조회 앱 심사 전: 팀원만 조회 가능
친구에게 보내기 친구 카카오톡으로 알림 친구도 앱에 OAuth 로그인 + 동의 필요
카카오 OAuth
인가 코드 발급
토큰 교환
access + refresh
kakao_tokens.json
서버 저장
메시지 발송
나에게 + 친구에게

03 카카오 Developers 앱 설정

developers.kakao.com 에 접속해 아래 순서대로 설정한다. 코드 작성 전에 이 과정을 먼저 완료해야 한다.

  1. 01 앱 추가 — 앱 이름, 회사명, 카테고리(금융) 입력. 앱 대표 도메인은 http://192.168.x.x 형식의 사설 IP 입력 (localhost 불가)
  2. 02 REST API 키 발급 — [플랫폼 키] → [REST API 키 추가]. Client Secret도 이 단계에서 함께 발급되니 반드시 저장
  3. 03 Redirect URI 등록http://192.168.x.x:3002/api/kakao/callback/friend-callback 두 개 모두 등록. URI가 1자라도 다르면 KOE006 에러 발생
  4. 04 카카오 로그인 활성화 — [제품 설정] → [카카오 로그인] → 상태 ON. 이 설정이 OFF면 KOE004 에러
  5. 05 동의항목 설정talk_message: 선택 동의 / friends: 이용 중 동의 (선택 동의는 API 검수 필요라 비활성). 동의 목적 텍스트도 입력 필요
  6. 06 팀원(테스터) 등록 — [앱] → [팀 관리]. 앱 심사 전에는 팀원으로 등록된 사용자만 친구 API 대상이 됨
주의 — 사설 IP는 ipconfig(Windows) 또는 ifconfig(Mac/Linux) 명령어로 확인한다. 공유기 환경에서 IP가 바뀌면 Redirect URI도 다시 등록해야 한다.

발급된 키는 바로 .env 파일에 저장한다.

.env
KAKAO_REST_API_KEY=your_rest_api_key_here
KAKAO_CLIENT_SECRET=your_client_secret_here
KAKAO_REDIRECT_URI=http://192.168.x.x:3002/api/kakao/callback

04 백엔드 구현 (FastAPI)

OAuth 콜백, 토큰 저장/갱신, 메시지 발송 세 부분으로 나뉜다.

OAuth 콜백prompt=consent 파라미터를 넣어 이미 동의한 사용자도 동의 화면을 다시 표시하도록 강제한다. "이용 중 동의" 항목의 권한을 얻기 위해 필요하다.

Python — OAuth 인가 URL 생성
@router.get("/api/kakao/auth-url")
def get_auth_url():
    scope = "talk_message,friends"
    url = (
        f"https://kauth.kakao.com/oauth/authorize"
        f"?client_id={settings.KAKAO_REST_API_KEY}"
        f"&redirect_uri={settings.KAKAO_REDIRECT_URI}"
        f"&response_type=code"
        f"&scope={scope}"
        f"&prompt=consent"  # 동의 화면 강제 표시
    )
    return {"url": url}

토큰 저장 — access_token은 약 6시간, refresh_token은 약 2개월 후 만료된다. 서버의 kakao_tokens.json에 저장해두면 서버 재시작 후에도 유지된다.

토큰 자동 갱신 — 메시지 발송 시 401 응답이 오면 refresh_token으로 재발급을 시도한다. 새 refresh_token이 응답에 포함될 경우 함께 갱신한다.

Python — 토큰 자동 갱신
async def refresh_access_token() -> str | None:
    tokens = _load_tokens()
    async with httpx.AsyncClient() as client:
        resp = await client.post(
            "https://kauth.kakao.com/oauth/token",
            data={
                "grant_type": "refresh_token",
                "client_id": settings.KAKAO_REST_API_KEY,
                "client_secret": settings.KAKAO_CLIENT_SECRET,
                "refresh_token": tokens.get("refresh_token"),
            },
        )
    data = resp.json()
    tokens["access_token"] = data["access_token"]
    if "refresh_token" in data:  # 새 refresh_token 발급 시 갱신
        tokens["refresh_token"] = data["refresh_token"]
    _save_tokens(tokens)
    return data["access_token"]

통합 발송 함수 — 나에게 보내기와 친구에게 보내기를 하나의 함수로 묶었다. APScheduler에서 매매 조건 충족 시 이 함수 하나만 호출하면 된다.

Python — 통합 알림 발송
async def send_alert(title: str, description: str):
    # 나에게 보내기
    await send_to_me(title, description)
    # 동의한 친구 전원에게 보내기
    friends = await get_friends()
    if friends:
        uuids = [f["uuid"] for f in friends]
        await send_to_friends(uuids, title, description)

05 친구에게 보내기

친구에게 알림을 보내려면 친구도 앱에 OAuth 로그인 + 메시지 수신 동의를 완료해야 한다. 별도 콜백 엔드포인트를 만들어 친구가 직접 동의할 수 있는 링크를 제공하는 방식으로 구현했다.

  1. 01 본인이 웹 UI에서 "친구 초대 링크 복사" 클릭
  2. 02 생성된 URL을 카카오톡으로 친구에게 전달
  3. 03 친구가 링크 클릭 → 카카오 로그인 → 동의 완료
  4. 04 본인이 "친구 목록 새로고침" 클릭 → 친구가 목록에 나타남
앱 심사 전 제약 — 친구 API는 카카오 앱 심사를 받지 않은 상태에서 팀원(테스터)으로 등록된 사용자만 대상이 된다. 소규모 개인 프로젝트라면 팀원 등록만으로도 충분하다.

06 프론트엔드 연동 UI

Next.js에서 FastAPI 백엔드로 요청을 프록시하도록 next.config.js를 설정한다.

next.config.js — API 프록시
const nextConfig = {
  async rewrites() {
    return [{ source: "/api/:path*", destination: "http://localhost:8005/api/:path*" }];
  },
};

"카카오 계정 연동하기" 버튼 클릭 시 auth-url에서 받은 주소를 팝업 창으로 연다.

TypeScript — 연동 버튼 핸들러
const handleConnect = async () => {
  const { url } = await api.kakaoAuthUrl();
  window.open(url, "_blank", "width=500,height=600");
};
기능 API
GET /api/kakao/status 연동 상태 확인 (토큰 유무)
GET /api/kakao/auth-url OAuth 로그인 URL 반환
GET /api/kakao/friends 동의한 친구 목록 조회
POST /api/kakao/test 테스트 메시지 발송

07 트러블슈팅

설정 과정에서 자주 마주치는 에러들을 정리했다.

  • KOE006 — 등록하지 않은 리다이렉트 URI 카카오 Developers에 등록된 Redirect URI와 요청 URI가 1자라도 다를 때 발생한다. [플랫폼 키] → REST API 키의 "카카오 로그인 리다이렉트 URI"에 정확한 URI를 등록한다. "로그아웃 리다이렉트 URI"(카카오 로그인 → 고급)와 혼동하지 말 것.
  • KOE010 — Bad client credentials 토큰 교환 요청 body에 client_secret이 누락됐을 때 발생한다. REST API 키 생성 시 함께 발급된 Client Secret을 반드시 포함해야 한다.
  • KOE205 — 설정하지 않은 동의 항목 OAuth scope에 존재하지 않거나 미설정된 항목을 넣었을 때 발생한다. 유효한 scope는 talk_message, friends 두 가지다. talk_message_friends 같은 항목은 없다.
  • 403 insufficient scopes 동의항목 설정 전에 발급된 토큰을 사용하고 있을 때 발생한다. 서버의 kakao_tokens.json을 삭제하고 "카카오 계정 연동하기"를 다시 실행해 모든 항목에 재동의한다.
  • 친구 목록 code: -5 앱 심사 전 상태에서 팀원이 아닌 사용자를 친구 API로 조회할 때 발생한다. [앱] → [팀 관리]에서 해당 친구를 테스터로 등록하면 해결된다.
  • 친구 목록 elements: [] (빈 배열) API는 200이지만 결과가 비어 있는 경우. 친구가 friends 스코프에 동의하지 않았거나, 동의항목이 "이용 중 동의"가 아닌 경우다. 본인 토큰 삭제 후 prompt=consent로 재인증하고, 친구도 앱 연결 해제 후 재연동한다.
  • 콜백 페이지 한글 깨짐 JSON 응답으로 한글을 반환할 때 인코딩이 깨진다. 콜백 응답을 HTMLResponse로 바꾸고 <meta charset='utf-8'>를 포함하면 해결된다.
Summary

카카오 비즈니스 채널 없이 무료로 나에게 보내기 + 친구에게 보내기를 구현했다. 핵심은 세 가지다: Redirect URI 정확히 등록, 토큰 교환 시 client_secret 필수 포함, friends 동의항목을 "이용 중 동의"로 설정. 트러블슈팅 목록을 참고하면 대부분의 에러는 설정 문제임을 확인할 수 있다. 다음 편에서는 단타 매매 포지션 관리와 매도 알림 기능을 다룬다.