저희 챗봇은 사용자의 식사일기를 저장하는 특성상 스킬 사용 및 DB 구축이 필요했습니다.
하지만 서버비를 내고 싶지는 않았고 서버를 켜고 끄는 것도 귀찮았기 때문에...
뒷단은 전부 서버리스 아키텍처로 구성했습니다.
챗봇 사용 중 특정 발화를 통해 스킬이 발동되면, 카카오i가 스킬에 연결된 API Endpoint를 호출하게 됩니다. 이때 API Gateway를 트리거로 Lambda가 동작하면서 챗봇에 필요한 로직을 처리하고, 적절한 응답을 돌려주게 됩니다.
Lambda는 작성한 함수의 실행 시간 및 실행 횟수, 메모리 사용량을 통해 요금을 결정하기 때문에, 함수가 호출되는 짧은 시간 동안에만 과금이 일어나도록 되어 있습니다. 이로써 서버를 켜두는 것에 비해서 상당한 양의 요금을 절약할 수 있습니다.
이너푸드에서는 유저의 발화가 이미지를 전송한 것인지 아닌지, Lambda를 통해 검증하고 있습니다.
<aside> 💡 이미지 보안 전송 플러그인을 쓰면 되지 않나요?
물론 플러그인을 쓰면 깔끔하게 이미지 URL을 받아올 수 있지만, 일단 유저가 보내는 이미지 개수를 제한할 방법이 없고(저희는 1개만 필요했습니다), 개인정보 수집 및 이용 약관도 만들어야 하고, 이미지의 보관 기간도 정해야 하는 등 복잡한 절차가 많습니다. 이너푸드는 개인정보를 다루는 이미지를 전송받는 게 아니어서 좀 더 캐주얼한 방식으로 풀어보고 싶었습니다.
</aside>
구체적으로는 블록에서 파라미터를 생성해서, 유저 발화 전체(sys.text)를 파라미터값으로 받고,
Lambda의 HTTP Endpoint를 검증 API로 사용함으로써 이미지 URL을 추출하고 있습니다.
이렇게 설정해 두면 유저가 앨범에서 이미지를 보냈을 때, 검증 API로 요청이 들어옵니다.
보통 텍스트 메시지를 보내게 되면 빈약한 params가 들어오지만...
{
"bot": {
"id": "[ID]",
"name": "이너푸드"
},
"utterance": "<http://naver.com>",
"params": {
"surface": "Kakaotalk.plusfriend"
}
/* 생략 */
}
앨범에서 이미지를 올리게 되면 이렇게, params.media
필드를 통해 이미지 URL이 들어오게 됩니다.
{
"bot": {
"id": "[ID]",
"name": "이너푸드"
},
"utterance": "<http://dn-m.talk.kakao.com/talkm/foo/bar.jpeg>",
"params": {
"surface": "Kakaotalk.plusfriend",
"media": {
"type": "image",
"url": "<http://dn-m.talk.kakao.com/talkm/foo/bar.jpeg>"
}
},
/* 생략 */
}