"""카카오 챗봇 Event API 테스트 발송 — 규격을 실제로 한 번 확인하는 1회성 스크립트. cd solution/backend && .venv/bin/python scripts/kakao_event_send_test.py --key ★ 무엇을 확인하나: 콘솔 설정(채널 연결·월렛·이벤트 블록·배포)이 제대로 끝났는지, 그리고 요청/응답 모양이 문서와 같은지. 성공하면 카톡에 이벤트 블록의 말풍선이 뜬다. ★ botUserKey 는 그 사장님이 채널에 연결 코드를 보낸 뒤 owner_kakao_links.channel_user_key 에 저장된 값이다. 아직 연결 전이면 발송할 대상이 없다. SELECT channel_user_key FROM owner_kakao_links WHERE status='LINKED' AND deleted=false; ★ 필요한 설정(.env): KAKAO_BOT_ID · KAKAO_BOT_REST_API_KEY (개발 채널이면 KAKAO_EVENT_DEV=1). 키·발화자 ID 는 출력하지 않는다. """ import argparse import asyncio import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) os.environ.setdefault("APP_ENV", "local") import httpx # noqa: E402 from services.external import kakao_event # noqa: E402 async def main(key: str, event: str, text: str) -> int: if not kakao_event.is_configured(): print("KAKAO_BOT_ID · KAKAO_BOT_REST_API_KEY 가 .env 에 없습니다.") return 1 async with httpx.AsyncClient(timeout=10.0) as client: try: task_id = await kakao_event.send( key, event, data={"text": text}, params={"test": "1"}, client=client ) except kakao_event.KakaoEventError as ex: print(f"실패 — {ex}") print(f"카카오 응답: {ex.detail}") return 1 print(f"요청 성공 — taskId={task_id}") print("카톡에 메시지가 왔는지 확인하세요. 안 오면 이벤트 블록 연결·배포·채널 친구 여부를 봅니다.") return 0 if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--key", required=True, help="수신자 botUserKey") parser.add_argument("--event", default="post_approval", help="오픈빌더에 정의한 이벤트 이름") parser.add_argument("--text", default="Event API 테스트입니다.", help="event.data.text 로 실려 갈 문구") args = parser.parse_args() raise SystemExit(asyncio.run(main(args.key, args.event, args.text)))