글로벌 앱 CS 담당자가 전세계 유저들의 문의를 이해하는 방법
시작하며
나의 메일함이 전세계 수십 개 언어로 된 수백 개의 메일로 가득 차있다면 어떻게 하시겠나요?
무슨 말도 안 되는 말이야! 하실 수 있을 텐데요, 이는 딜라이트룸에서 유저와의 접점에 있는 POM(Product Operations Manager) 그룹이 매일 마주하는 상황입니다. 이에 대해 저희 POM 그룹은 기존에 사용하던 툴의 한계에서 벗어나 더 효율&효과적인 방법을 찾고자 노력해왔는데요, 유저들의 메세지를 번역하는 과정에서 있었던 여러 크고 작은 산들과 그걸 극복한 방법을 공유해보겠습니다.
반복 작업의 한계에 부딪히다
Product Operations Manager 그룹(이하 POM 그룹)은 유저와 딜라이트룸의 사이를 연결하는 다리 역할을 하는 그룹입니다. 대표적인 업무로 유저들이 보내는 문의와 피드백을 파악하고 응대하는 것이 있는데요, 글로벌 앱 서비스인만큼 수십개의 다양한 언어로 하루에도 수백 개의 문의와 버그 리포트가 들어옵니다. 딜라이트룸에서는 이렇게 수많은 피드백/문의를 통합 고객 지원 소프트웨어 Zendesk에서 관리하고 있습니다.
젠데스크에서는 유저가 보낸 피드백 하나하나를 “티켓”이라고 지칭합니다. 티켓 자동 번역이 갖춰져 있지 않았을 당시, 한국어/영어 외의 티켓 처리 절차는 다음과 같았습니다.
- 먼저 젠데스크에 접속하여 처리할 티켓이 모인 필터 뷰에 들어갑니다.
- 티켓 하나를 선택하여 뷰를 엽니다. (이 과정이 생각보다 로딩이 오래 걸립니다.)
- 한국어/영어가 아닐 경우 본문을 선택합니다. 한 줄로 되어있으면 3회 연속 클릭하여 한 번에 선택되고, 여러 줄이라면 클릭+드래그합니다.
- 본문을 선택하면 크롬 익스텐션에 설치한 구글 번역기를 통해 영문으로 번역됩니다.
- 번역된 영문을 다시 선택하여 젠데스크 메모란에 붙여넣고, 티켓을 업데이트하여 영문 버전을 저장합니다. (이렇게 저장하지 않으면 다시 읽을 때 또 번역해야 해서 불편하니까요.)
- 다음 티켓으로 넘어가서 위 과정을 반복합니다.
사람은 적응의 동물이라더니, 이 긴 과정도 습관화되더군요. 하지만 앞서 말씀드렸듯 수백 개의 티켓 중 약 40%는 번역이 필요했습니다. 하루에 티켓이 100개만 들어온다고 해도 위의 과정을 40회 반복해야 하는 것이었죠. 한 달이라면 최소 1200회! 게다가 젠데스크 UI에는 아주 많은 기능이 붙어있는데요, 이로 인해 다음 티켓으로 넘어가고 저장할 때마다 생기는 로딩 시간이 쌓여 생각보다 많은 리소스를 잡아먹었습니다. ‘적응했으니 시간 얼마 안 든다’라고 넘어가기엔 적지 않았어요.
기존 방식의 또다른 단점은, 사람이 번역하기 전까지는 어떤 내용이 많이 들어왔는지 미리 파악하는 것이 불가능하다는 점이었습니다. 예를 들어 갑자기 티켓이 평소의 3–4배 넘게 들어왔다면, 어떤 공통적인 내용이 포함되어있는지 알려면 모두(까지는 아니어도 대부분을) 번역해야 했습니다. 긴급 상황이라면 문제 파악이 느려지는 치명적인 문제이죠.
알라미 앱의 유저가 늘어나고 기능이 추가되면서 들어오는 피드백과 문의도 점점 늘어났습니다. POM 그룹이 담당하는 업무도 조금씩 확장되고 있었고요. 이에 따라 반복 작업에 드는 리소스를 최대한 절약하고 시스템화 할 필요가 커졌습니다. 한계에 부딪혀 목이 말랐던 저는 티켓 자동 번역을 위한 우물을 파기 시작했습니다.
내가 생각한 건 100% 남이 먼저 생각했다
당연하게도, 제가 생각한 “티켓 자동 번역”은 저만의 생각은 아니었습니다. 많은 비즈니스 파트너를 거느린 젠데스크의 마켓 플레이스에는 몇몇 티켓 번역 앱이 제공되고 있었습니다. 하지만 당시 평이 좋은 앱을 사용하면 딜라이트룸에 들어오는 티켓이 워낙 많아 가격이 비쌌고, 그 외에는 아직 품질 검증이 되지 않아 있었습니다. 미묘한 번역 오류 또는 앱 오류가 티켓 대응 프로세스를 복잡하게 만들어버릴 수 있었기에 고민이 컸죠.
그래서 이미 하고 있던 구글 번역기를 사용해보면 어떨까 생각했습니다. 없는 것 빼고 다 있는 구글은 번역 API를 제공하고 있었죠! 신이 나서 API 테스트 툴인 Postman을 사용하여 API request를 몇 번 날려보았습니다. 순식간에 어떤 언어인지 정보와 번역된 결과물이 리스폰스로 돌아왔습니다.
여기서 이런 생각이 들었습니다.
“구글 번역 API를 사용하면 복잡하게 앱을 사용하지 않고도 우리가 편한 방식에 딱! 맞추어 티켓을 번역할 수 있지 않을까?”
다행스럽게도, 구글 번역 기본 제품의 가격은 아주 저렴했습니다. 무려 매 달 50만 자까지는 무료!였어요. 그 간 들어온 티켓의 글자 수를 확인해보니 매 달 50만 자에는 미치지 않았기 때문에 이 API를 사용하면 비용을 전혀 들이지 않고 고품질의 번역 결과물을 받아볼 수 있겠다는 확신이 생겼습니다.
아름다운 End Picture
처음 시작하며 그렸던 최종 그림은 사람이 하던 것을 그대로 옮겨서 자동화하는 것이었습니다. 이를 아주아주 단순한 플로우 차트로 그리면 다음과 같았습니다.
두 번째 단계는 구글 번역을 통해 간단히 해결할 수 있을 것으로 보였습니다. 그렇다면 이제 유저가 보낸 티켓의 본문을 읽어오는 1단계(구글 번역의 input), 내부 메모를 붙여 업데이트하는 3단계(구글 번역의 output)가 필요했죠.
다행히도 그 전에 젠데스크의 API를 한두 번 사용해본 적이 있었기에 어렵지 않게 방법을 찾았습니다. 티켓 정보를 가져와서 본문을 읽어내는 API, 그리고 답변, 태그 등과 함께 티켓을 업데이트할 수 있는 API 2가지로 해결할 수 있어 보였어요.
말이 쉬운 것이었다
슬프게도… 간단해 보였던 End Picture와는 달리, 생각보다 자잘한 어려움들이 많았습니다. 하지만 뜻이 있으니 길이 있었죠. (사실 수많은 API들이 있어 길이 생겼습니다. )
하나, 어디에서 들어온 티켓인지에 따라 번역할 부분이 모두 달랐습니다. 앱 내에서 들어온 문의냐 스토어에 달린 리뷰이냐에 따라 본문 위치를 다르게 지정해야 했어요. 물론 본문 전체 다 번역해버려! 하면 편했겠지만, 이렇게 하면 번역기에 들어가는 글자 수가 폭증🌋해서 50만 자를 넘을 위험이 있었고, 스토어에서 들어오는 문의에는 영어가 섞여 있어서 원본 언어가 영어로 잘못 인식될 위험이 있었습니다. (그러면 번역기에 돌리는 의미가 사라지게 되죠. 흑흑)
그리하여 가장 첫 단계로 티켓을 들어온 소스에 따라 분류하도록 하였습니다. 어느 쪽으로 분류되었느냐에 따라 서로 다른 위치에서 본문을 긁어오도록 했죠. 이 안에서도 여러 변수가 있긴 했지만 다행히 몇 번의 수정을 거쳐 정확히 번역이 필요한 부분만 집어낼 수 있게 되었습니다.
둘, 번역이 불필요한 경우를 미리 걸러내야 했습니다. 이 또한 불필요하게 번역 API를 사용하여 비용을 낭비하는 경우를 막기 위함이었습니다. 그리고 완전한 자동화가 아닌 제 로컬 랩탑에서 스크립트를 돌리고 있었다 보니, 한국어/영어를 포함한 모든 티켓을 번역하면 시간이 배로 소요될 것이었어요.
다행스럽게도 앱 내에서 들어온 문의에는 유저가 설정한 언어 값이 전달되고 있었습니다. 이 정보를 사용하여 en-, ko-로 시작하는 경우를 걸러낼 수 있었습니다.
스토어 리뷰의 경우, 젠데스크로 티켓을 전달해주는 매개 서비스인 AppFollow를 통해 이미 번역되어 들어왔습니다. 해서 초반에는 번역 대상에 포함하지 않았는데요, 번역 품질이 그리 좋지 않아 부정확하게 (때론 아주 재미있고 요상하게^^) 번역되곤 했습니다. 결국 또 한 번 수동으로 번역해야 할 때가 자주 있었어요. 아주 다행스럽게도 AppFollow에서는 원본 언어가 무엇인지 감지해서 정보값을 전달해주고 있었습니다. 스토어 티켓에서는 이 정보를 활용하여 한국어/영어 티켓은 번역 대상에서 제외했습니다.
셋, 이미 번역이 되었는지 아닌지 확인할 방법을 만들어야 했어요. 혹시라도 스크립트가 돌아가던 중 에러가 발생해서 중지되거나 랩탑을 닫아버린다면…? 이미 번역한 것을 또 돌리면 비용이 X2가 되는 불상사를 막아야 했습니다.
방법은 이러합니다. 새로 생성되는 모오든 티켓에 “translation_needed”라는 태그를 달고, 이러한 티켓을 모은 필터 뷰(view)를 신규로 생성했습니다. 젠데스크에서 제공하는 수많은 API 중 특정 뷰 내의 티켓 정보를 모두 제공하는 것이 있었어요. 이를 활용하여 “translation_needed”가 태깅된 티켓만 스크립트에 돌리고, 번역을 마치면 “translation_done” 태그로 바꾸도록 하여 새로이 번역이 필요한 티켓만 걸러냈습니다.
티끌 모아 태산이 되다
이 모든 과정을 맘 잡고 한 번에 빡! 이루어낸 것은 당연히 아닙니다. 대학교 때 동아리나 학교 수업에서 배웠던 Python 기초 지식을 가지고 가장 단순한 것부터 만들어 나갔습니다. 만족하며 사용하다가도 ‘앗 이런 것도 필요하겠다!’ 싶으면 할 일 목록에 적어두고 30분씩 (때론 1시간) 투자해서 개선해 나간 결과 위의 과정이 차곡차곡 쌓인 것이죠.
인앱 피드백에서 시작하여 스토어 티켓, 심지어 지메일로 인입되는 (아주 불규칙한 패턴의) 티켓까지 커버하면서 POM 그룹이 관리하는 티켓 100%에 대한 (반)자동 번역 시스템이 완료되었습니다. 막판 단계에서는 중복되는 코드를 최소화하며 깔끔하게 정리하는 나름대로의 리팩토링까지 거쳐 지금은 코드를 거의 수정하지 않고 사용하고 있습니다. 이 뿌듯한 여정을 담아 타운홀 회의에서 딜라이터들에게 공유하기도 했죠.
이게 끝이 아닙니다
제가 짠 스크립트는 제가 처한 상황에서 만들어낸 방법일 뿐, 더 나은 방법이 있을 수 있습니다. 젠데스크 마켓 앱이 크게 발전하여 그 중 하나를 쓰는 게 훨씬 비용 효과적이어질 수도 있습니다. 지금은 상상할 수 없는, 또다른 방식의 티켓 번역 시스템이 나타날 수도 있고요. 이런 상황이 오면 제 스크립트를 떠나야 할 수도 있습니다.
그렇다고 해서 스크립트를 짠 과정이 헛되다고 느끼냐 하면, 절대 그렇지 않습니다. 이 과정을 통해 딜라이트룸에 들어오는 티켓의 속성, 젠데스크의 시스템을 훨씬 깊게 이해하게 되었으니까요. 이 경험을 바탕으로 사용하는 툴에 아쉬운 점이 있다면 극복할 방법을 찾을 수 있다는 자신감까지 얻었으니 어떤 상황이 와도 아까운 시간이 아니었다고 자부합니다. 수많은 검색을 통해 여러 API 서비스를 활용하는 경험을 쌓은 것은 덤이었고요.
미래 계획을 살짝 말씀드리자면, 만들어진 스크립트를 인프라 팀의 도움을 받아 서버에 올리는 것을 고려하고 있어요. 이렇게 되면 제가 로컬에서 스크립트를 실행하지 않아도 주말에도 휴일에도 제가 쉬는 날에도 항상 슝슝 번역기가 돌아가겠죠? 상상만으로도 즐거운 소름(?)이 돋습니다.
마치며
이 과정은 비단 “티켓을 쉽고 빠르게 번역해서 티켓 관리가 쉬워졌어요!”에 그치지 않습니다. 개발자의 힘을 빌리지 않고도 운영 그룹에서 자동화를 실천할 수 있다는 의미를 갖고 있습니다. 추가로 이러한 업무를 시간 낭비로 치부하지 않고 생산성 향상에 초점을 맞추어 권장하고 응원해주는 회사의 역할이 크다는 점도 내포하고 있고요. 이러한 점이 저희 POM 그룹을, 딜라이트룸을 특별한 조직으로 만들어준다고 생각합니다.
저희 POM 그룹은 유저와 딜라이트룸을 연결하는 다리로서 열심히 도로를 정비하고 교통 정리를 하고 있습니다. 티켓 자동 번역뿐만 아니라 정비할 수 있는 수많은 업무들이 기다리고 있으니, 앞으로의 이야기도 기대해주세요. :)
운영 그룹의 생산성 향상을 적극 후원해주는 딜라이트룸이 더 궁금하다면? 👉 딜라이트룸 구경하기