프로그래밍/회고

DASHI - 키워드 알림 업데이트

Lou Park 2024. 12. 26. 15:58

얼마전 뜨거운 순간 기능을 업데이트하면서, DB도 추가하고 채팅 처리 파이프라인을 따로 빼면서 평소 해보고 싶었던 기능을 추가해보기로 했다. 그건 바로 키워드 알림! 예를 들어서 내가 스트리머가 "발헤임"이라는 게임을 정말 해주길 기다리고있는데, 채팅에서 "발헤임"이라는 키워드가 나왔을 경우 정말 그것과 관련한 이야기를 하고 있을 확률이 높다. 이렇게 내가 방송을 보지 못하는 순간에도 관련된 키워드가 언급되었는지 확인 하기위한 용도로 <키워드 알림>은 유용하게 쓰일 수 있다.

 

Discord로 로그인

키워드 알림기능을 오랫동안 망설였던 이유 중의 80%는 이 서비스에 'DB가 없었다'였지만, 20%는 '로그인이 없었다'였다. 그렇다! 로그인을 추가해야한다. 단순히 유저 식별만 가능하면되므로, Discord OAuth2를 이용하기로 했다.

 

게임방송을 보는 사람들이라면 Discord 계정 하나쯤은 들고있으니까.

Discord Developer Portal

 

Discord OAuth2 연동 문서를 읽으며 느낀건데, Discord 문서는 정말 개발자 친화적이다. 읽으면서 정말 유용하고 이해하기 쉬워서 언젠가 API 문서를 작성하게 된다면 Discord 문서를 참고해야겠다는 생각이 들었다. iOS 개발자 문서 이후로 감명깊게 읽은(?) 개발자 문서.

 

Discord에서는 유저 식별과 UI를 표시하는 용도의 최소한의 정보만 들고온다.

UID, 사용자명, 아바타 3가지 항목이다.

DASHI의 로그인 상태 UI

 

키워드를 관리하고, 회원 탈퇴 기능까지 필요하므로 마이페이지도 따로 만들어주었다.

UI는 정말 귀찮군~

마이 페이지 화면

 

 

쏟아지는 채팅중에서 키워드를 어떻게 효율적으로 찾을까?

사용하는 유저도 별로 없고 유저당 10개의 키워드 등록을 제한하기는 했지만, 개발자라면 유저가 폭발했을때나 키워드가 엄청나게 많은 경우의 수를 생각하고 만들며 쉐도우 복싱을한다. 얼마전에 컨퍼런스에서 들었던 BloomFilter를 이용해볼까, 아니면 아호코라식 알고리즘으로 처리할까 고민했는데 BloomFilter를 적용해보려니 단어를 토큰별로 분리하는게 더 빡셀 것 같았다. 

 

그래서 회사에서 비속어 필터링을 처리할때 사용했던 방법인 아호코라식 알고리즘을 이용했다. 안드로이드에서 개발할땐 Trie 구조부터 전부다 손수만들어야 했었는데 Python에서는 왠만한 알고리즘은 다 편한 라이브러리가 있다. pyahocorasick 라이브러리를 이용하면 아주 쉽게 텍스트 패턴 매칭을 할 수 있다.

 

self.automation = ahocorasick.Automaton()
with DBHelper.session() as session:
    keywords = session.query(KeywordModel).filter(KeywordModel.count > 0).all()
    for keyword in keywords:
        self.automation.add_word(keyword.text, (keyword.id, keyword.text))
self.automation.make_automaton()

 

DB에 등록된 모든 키워드들을 Trie에 등록하고, 제공해주는 iterator를 통해 바로 매칭 결과를 얻어올 수 있다.

for end_index, (keyword_id, keyword_text) in self.automation.iter(message):
    if keyword_id not in found_keywords:
        logger.info(f"found keywords: {keyword_text}")
        found_keywords[keyword_id] = {
            'message': message,
            'keyword': keyword_text
        }

 

추가적으로, 키워드는 특정한 순간에 다수의 시청자가 채팅을 치는 경향이 있으므로 단시간에 반복적으로 키워드가 찍히는 현상을 막기위해 10초마다의 채팅을 묶어서 처리한다. 

 

키워드를 찾고 DB에 추가하는 과정을 celery로 할까했는데 ChatGPT가 그건 오바쎄바라고 했다. 백엔드 개발 경험이 부족해서 이게 오버 엔지니어링인지 감잡기가 어려운데 ChatGPT 선생님이 있어서 다행이다...asyncio로 I/O 작업은 따로 비동기로 돌리는 선에서 마무리했다.

 

 

키워드 알림 기능 살펴보기

키워드 알림 UI

처음에 키워드 알림 UI를 만들었을땐 <뜨거운 순간>과 비슷하게 생긴 버블차트로 표현했는데, 굳이 버블로 표현할 이유가 없었다. 그렇게 하려는 유일한 이유는 유저를 위한 선택이아니라 이미 개발된 UI를 재탕하려는 개발자의 안일한 마음뿐이다.

 

하루정도 더 고민해서, 어떤 채팅이었는지 한 눈에 볼 수 있으면서도 내가 구독하는 키워드가 무엇인지 보이는 Chip 형태로 바꾸었다.