미니블로그 승인 알림을 메일에 더해 연결된 카카오톡으로도 보내기 위한 첫 단계.
승인 방식은 인라인 버튼 + 연결된 계정 신원 확인으로 정했고(링크가 없어 메신저
미리보기가 먼저 열어 승인되는 문제가 없다), 이 커밋은 발송 통로와 규격 확인까지다.
- services/external/kakao_event.py: POST bot-api.kakao.com/v2/bots/{botId}/talk.
예외 문구(str)에는 키·발화자 ID·응답 원문을 넣지 않고 진단용은 detail 에만 둔다
- KAKAO_BOT_REST_API_KEY 를 기존 KAKAO_REST_API_KEY(카카오 로컬 API)와 갈랐다 —
Event API 는 채널을 연결한 비즈니스 인증 앱의 키를 써야 해서 앱이 다를 수 있다
- KAKAO_EVENT_DEV=1 이면 봇 ID 뒤에 "!"(개발 채널). KAKAO_BOT_ID 자체는 웹훅이
bot.id 대조에 쓰므로 고쳐 쓰지 않는다
- scripts/kakao_event_send_test.py: 실제 카톡으로 한 건 보내 규격을 확인하는 스크립트
실제 발송으로 확인함(요청 성공 + 카톡 수신). 이벤트 미배포 시 "Invalid Event name" 404 를
돌려주는 것도 확인했다.
test_kakao_event.py 7건, 카카오·설정 관련 스위트 75 passed
52 lines
2.4 KiB
Python
52 lines
2.4 KiB
Python
"""카카오 챗봇 Event API 테스트 발송 — 규격을 실제로 한 번 확인하는 1회성 스크립트.
|
|
|
|
cd solution/backend && .venv/bin/python scripts/kakao_event_send_test.py --key <botUserKey>
|
|
|
|
★ 무엇을 확인하나: 콘솔 설정(채널 연결·월렛·이벤트 블록·배포)이 제대로 끝났는지, 그리고
|
|
요청/응답 모양이 문서와 같은지. 성공하면 카톡에 이벤트 블록의 말풍선이 뜬다.
|
|
★ 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)))
|