-
카카오톡채널 AI챗봇 콜백API를 사용방법 간단 정리 (Express)Nodejs 2023. 8. 31. 08:03
콜백API?
카카오톡채널의 챗봇을 이용할 때 요청한 스킬의 응답시간이 5초를 넘어가면 요청시간 초과로 타임아웃이 나버린다. 대부분의 경우에는 API 응답 시간이 5초를 넘어가지 않겠지만, 생성AI처럼 요청의 결과를 얻기까지 지연시간이 길게 발생하는 경우에는 5초 안에 응답을 만들기가 쉽지가 않다.
다행히 카카오에서는 이런 경우를 대비하 "콜백API"라는 기능을 제공하며, 이는 별도로 AI챗봇 사용허가를 받은 이후에 사용이 가능하다.
챗봇 관리자센터 개요 · 도움말 - 챗봇 관리자센터
<h2><a class="anchor" aria-hidden="true" id="챗봇-관리자센터-소개"></a><a href="#챗봇-관리자센터-소개" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width
i.kakao.com
사용방법
공식문서에 어느정도 큰 틀에서의 사용방법이 잘 나와있기는하나, 실제 코드를 작성할 때 다소 애매모호한 부분들이 있다고 생각되어 따로 간단하게 정리해보기로 한다.
1. 블록 설정
먼저, 블록에서 콜백API 설정을 해준다.
Callback 설정 안의 문구는 타임아웃에 걸리는 진짜 응답을 받아오기 전에 먼저 띄워주는 메세지다. 직접 메세지를 입력해도 되고 위 예시처럼 웹훅 변수를 넣어줘도 된다. 여기서 설정한 웹훅 변수는 챗봇 스킬에서 응답을 보낼 때 작성할 수 있다.
2. 챗봇 스킬 작성
콜백API가 설정된 블록에서 사용되는 스킬은 스킬의 요청바디에
callbackUrl
이라는 필드가 추가된다. 이 URL을 통해 진짜 응답을 보내줄 것이기 때문에 본요청을 처리하는 곳에서 callbackUrl을 갖고 있을 수 있게 잘 전달한다.router.post('/prompt', async (req, res) => { const { action, userRequest } = req.body; const { callbackUrl, user } = userRequest; // do stuff const url = `${KAKAO_PROMPT}/${userId}`; const data = createPromptBody(userData, callbackUrl); const response = await fetch(url, { method: 'POST', headers: JSON_HEADER, body: JSON.stringify(data), }); if (!response.ok) { const errorResponse = { version: '2.0', // 필요에 맞게 skill response 작성 } res.status(response.status).send(errorResponse); return; } const { result }: ApiResponseDto<string> = await response.json(); const responseMessage = result ? '이미지를 생성중입니다. 잠시만 기다려주세요⏳' : '이미지 생성에 실패했습니다. 다시 시도해주세요.'; const callbackResponse = { version: '2.0', useCallback: true, data: { text: responseMessage, }, }; res.status(201).send(callbackResponse); });
마지막에
callbackResponse
에서useCallback: true
를 설정해야지만 1번에서 설정한 예비문구가 카카오톡채널에 출력이 된다. 또,{{#webhook.text}}
처럼 웹훅 변수를 썼다면,data
필드 아래에 필요한 값들을 전달할 수 있다.3. 처리서버에서 callbackUrl 사용
이제 처리서버에서는 처리가 끝나면
callbackUrl
로 POST 요청을 skill response에 담아서 보낸다. 이때, 처리 결과를 기다리느라 2번에서 작성한 스킬의 지연시간이 5초를 초과하면 안되기 때문에 비동기 처리에 적절히 주의를하며 작성한다.회사 서비스에서는 생성AI 서버에 요청을 보내기전에 Nestjs 서버를 거치고 있으며, Nestia라는 라이브러리를 validation에 쓰고 있어 데코레이터가 조금 다른 점을 참고 바란다.
@IgnoreAuth() @TypedRoute.Post('/text/image/kakao/:userId') async generateImageKakao( @Res() res: Response, @TypedBody() body: PromptFormKakaoDto, @TypedParam('userId') userId: string, ) { // 요청 예외처리 const promptForm: PromptImageForm = { // 이미지 생성요청 보내는 폼 }; const queueId = await this.promptQueue.add(promptForm, { userId }); // 큐 예외처리 const interval = setInterval(async () => { const result = await this.promptQueue.retrieve(queueId); if (result.type !== 'complete') return; const image = await this.sdImageService.create({ userId }, result); if (is<PromptImage>(image)) { await kakaoCallback(body.callbackUrl, image.file); } clearInterval(interval); }, 3000); setTimeout(() => { clearInterval(interval); }, 58000); // callback과는 별개로 처리서버가 받은 요청은 일찌감치 응답을 보낸다. res.json(createHttpResponse<string>('prompt generating...')); }
거듭 이야기하지만, 실제 생성AI 혹은 본작업의 처리가 끝나지 않았더라도 스킬에서 보낸 요청에 대해서는 일단 응답을 5초 이내에 보내야한다. 만약 코드를 다 완성한 이후에 의도한대로 카카오톡채널에 메세지가 발생하지 않는다면 높은 확률로 스킬서버나 처리서버에서 비동기 처리를 잘못하고 있을 가능성이 높다.
4. 스킬 연계 설정
마지막으로 콜백API가 설정된 블록에 콜백API 처리를 하고 있는 스킬을 연동해주고 필요한 파라미터가 있다면 함께 지정해준다.
공식문서에서도 언급하지만 2023년 8월 기준으로 AI챗봇의 기능은 봇테스트에서는 동작하지 않는다. 따라서, 아직 배포를 안했다면 배포를 하는 것을 잊지 말자.
'Nodejs' 카테고리의 다른 글
ESM에서 alias path 사용하기 (module-alias) (0) 2023.08.13