잔디 날씨 알림 봇 개발기
안녕하세요. R&D부 백엔드팀 서민수입니다. 저희 백엔드팀에는 신규 입사자가 들어왔을 때 기본적인 입사 가이드를 진행하고 나서 마지막으로 사내 템플릿을 이용해 간단한 토이 프로젝트를 직접 만들어보는 시간이 있습니다. 이 시간에 제가 개발한 날씨 알림 봇 개발과정에 대해 알아보겠습니다.
주제 선정
비브로스에서는 사내 업무용 메신저로 잔디를 사용합니다. 잔디에는 다른 서비스를 잔디에 연결해서 메시지 알림을 받거나 명령어를 입력하여 외부 서버에 메시지를 전달하고 그에 따른 응답을 받을 수 있는 잔디 커넥트라는 기능이 있습니다. 잔디 커넥트를 이용하면 알림봇이나 검색봇, 번역봇같은 봇들을 만들어서 업무에 유용하게 사용할 수 있습니다.
비브로스 잔디 팀 대화방에는 이미 Github, JIRA, AWS CloudWatch, 개발 일정 알림, 똑닥 통계 및 병원 검색 등을 제공하는 봇들이 존재합니다. 저는 그 중에 기본적인 날씨를 알려주는 봇이 존재하지 않다는 것을 발견하고 날씨 알림 봇을 만들어보기로 했습니다. 날씨는 외출 전에 하루에 한번씩은 찾아보는 정보이기도 하고 기상청에서 제공하는 Open API가 있기 때문에 토이 프로젝트의 주제로 적합할 것 같다고 생각하였습니다. 그리고 얼마 지나지 않아 오늘 뭐먹을지 알려주는 봇을 만들걸이라고 후회하게 됩니다.
기상청 API
기상청에서 제공하는 날씨 API는 약 34개의 여러가지 API가 있는데 이 중에서 저는 동네예보 조회서비스
와 중기예보 조회서비스
를 이용하여 날씨 정보를 조회해보기로 했습니다.
동네예보 조회서비스는 최근 1일간 특정 시간의 날씨 정보를 알려주는 초단기 실황 조회 서비스
와 1~4시간 이후의 예보 정보를 알려주는 초단기 예보 서비스
, 최대 3일까지의 날씨 예보를 조회할 수 있는 동네예보조회 서비스
등으로 구성되어있습니다.
중기예보 조회서비스는 3일~10일 후까지의 강수확률과 날씨 예보를 알려주는 중기 육상 예보조회 서비스
와 최저/최고 기온을 알려주는 중기 기온조회 서비스
등으로 구성되어있습니다.
날씨 조회를 어떤식으로 할까 생각을 하다 현재 날씨 조회
, 오늘의 날씨 조회
, 한주간의 날씨 조회
기능을 만들기로 결정을 했는데 기능 구현을 위해 여러가지 기상청 API로 테스트를 하다보니 몇가지 불편사항이 발생하였습니다.
우선, 기상청의 중기 육상 예보조회 서비스와 중기 기온조회 서비스는 3일부터 10일까지의 예보를 조회할 수 있기 때문에 내일, 모레의 기상정보를 조회하려면 동네예보조회 서비스를 이용하고 3일 이후의 기상정보를 조회하려면 중기 육상 예보조회와 중기 기온조회를 조회해야하여 뒤에서 설명할 Geocoding과 미세먼지 API 등까지 포함하면 한번 호출할 때 5번 이상의 API가 호출되어 미리 조회를 하지 않고 실시간으로 조회하는 방식에서는 속도가 너무 느리다는 문제가 존재하였습니다.
또한 기상청 API만의 특징인 장소조회 시 다른 API들에서 많이 사용하는 위, 경도 방식 조회가 아니라 기상청에서만 사용하는 X좌표 Y좌표가 따로 존재하여 추가 데이터베이스를 구축해 장소 매칭을 해줘야 한다는 단점이 있었습니다.
결국 기상청 API 대신 다른 API를 찾은 결과 OpenWeather
라는 API를 찾게 되었습니다.
OpenWeather
OpenWeather는 IT전문가와 데이터 사이언티스트로 구성된 영국의 팀입니다. OpenWeather에서는 전세계의 날씨 정보를 제공하고 있으며 이 데이터를 유/무료 API를 통해 개발자에게 제공하고 있습니다. 무료 플랜에서는 현재 날씨, 1시간의 분당 예보, 2일의 시간당 예보, 7일의 일간 예보, 주요 국가 기상 경보 알림, 지난 5일간의 날씨 조회, 공기 질 조회, Geocoding등의 서비스를 제공합니다. 그리고 One Call API
가 존재하여 한번의 호출로 현재 날씨, 분당/시간당/일당 날씨 조회를 한번에 할 수 있다는 장점이 있습니다.
Geocoding?
Geocoding
은 지역의 명칭으로 위도와 경도의 좌표값을 얻는 것입니다. 반대로 위경도에서 지역의 명칭을 얻는 것을Reverse Geocoding
이라고 합니다. Geocoding API는 크게 Google, Naver, Kakao 등 지도를 제공하는 서비스 회사에서 주로 제공되고 있습니다.
보통 날씨 관련 서비스를 만들 때 Google의 Geocoding 서비스를 많이 이용하지만 저는 OpenWeather에서도 Geocoding 서비스를 제공하는 것을 보고 기왕이면 하나의 서비스로 해보자는 생각에 OpenWeather의 서비스를 사용하였습니다. 하지만 OpenWeather의 Geocoding API는 다른 서비스와 다르게 도시 이름, 지역 코드, 나라 코드를 전부 입력해야하는 방식이고 해당 코드들을 ISO 3166형식으로 입력하는 방식이라서 실사용이 곤란하였습니다.
결국 다른 API를 찾다가 OpenWeather의 Current Weather data API에서 날씨 검색을 할 때 도시 이름으로 검색을 한 다음 위도, 경도 정보를 반환한다는 것을 발견하고 해당 API를 이용하기로 했습니다.
그리고 반환된 위도와 경도를 가지고 One Call API에서 오늘의 날씨, 7일간의 날씨 정보만 추출해서 사용하고 Air Pollution API를 사용해 초미세먼지(PM 2.5)와 미세먼지(PM10)의 농도를 가져오도록 하였습니다.
잔디 Outgoing Webhook
잔디 커넥트의 Webhook 발신(Outgoing Webhook)은 잔디 메신저에 키워드를 입력하여 외부 서버를 호출하고 그 응답을 전달받아 메신저에 출력할 수 있도록 하는 기능입니다. 봇을 추가할 때 등록한 키워드를 잔디에 입력하면 봇에 등록된 서버에 아래와 같은 메시지가 전송됩니다.
HTTP/1.1 POST
{
"token" : "YE1ronbbuoZkq7h3J5KMI4Tn",
"teamName" : "Toss Lab, Inc.",
"roomName" : "토스랩 코리아",
"writerName" : "김잔디",
"text" : "/날씨 내일 대전 날씨 어때?",
"keyword" : "날씨",
"data": "내일 대전 날씨 어때?",
"platform": "web",
"ip": "127.0.0.1",
"createdAt" : "2017-05-15T11:34:11.266Z"
}
여기에서 keyword
필드는 잔디에서 보낸 키워드 명령어이고 data
필드는 메시지에서 키워드를 제외한 부분입니다. 이 두가지의 필드를 사용해 텍스트를 파싱하여 서버로 요청을 보낼 수 있습니다.
요청을 처리한 서버가 응답 메시지를 보내고 싶은 경우에는 아래와 같은 형식으로 응답하면 잔디 메신저에 응답이 출력됩니다.
{
"body" : "[[PizzaHouse]](http://url_to_text) You have a new Pizza order.",
"connectColor" : "#FAC11B",
"connectInfo" : [{
"title" : "Topping",
"description" : "Pepperoni"
},
{
"title": "Location",
"description": "Empire State Building, 5th Ave, New York",
"imageUrl": "http://www.esbnyc.com/top_deck.png"
}]
}