한 일

카톡과 봇을 잇는 방식을 새로 도입했다. 지금까지 파퀘봇은 “메신저봇R"로 카톡과 이어져 있었다. 이건 안드로이드 폰에 깔아 쓰는 앱 스크립트다. 이번에 “Iris"라는 새 방식을 같이 쓸 수 있게 했다. Iris는 카톡 메시지를 가로채서 내 서버로 넘겨주고, 내 서버가 보낸 답을 카톡에 다시 띄워주는 다리 역할을 한다. 옛 방식을 바로 버리지 않고, 둘을 나란히 두고 골라 쓰는 식으로 만들었다.

큰 변화는, 봇의 “두뇌"와 “연결 통로"를 분리한 거다. 파티 만들기·참가 같은 핵심 로직(순수 함수 11개)을 따로 빼서, 옛 방식이든 새 방식이든 똑같이 쓰게 했다. 명령어를 읽는 파서도 서버와 폰이 같은 파일을 공유하게 묶었다. 한쪽만 바뀌어 어긋나는 일이 없게, 서버가 이 묶음 파일을 만들고 해시로 도장을 찍어 내려보낸다.

실제로 클라우드에 안드로이드 폰을 띄웠다. 전용 클라우드 VM을 만들고, 그 안에 redroid로 안드로이드를 돌렸다. redroid는 진짜 폰 대신 서버 안에서 안드로이드를 통째로 돌리는 방식이다. 거기에 카카오톡을 깔아 로그인하고, Iris를 올려서 내 서버 웹훅과 이었다.

올리기 전에 이게 클라우드에서 진짜 도는지 하나씩 쟀다. 카톡을 켜면 메모리를 약 1.58GB 쓰길래, 4GB짜리 VM이면 적당하다고 정했다. ARM 계열 VM도 보긴 했는데, 서울 지역에 없고 부팅도 실패해서 안 쓰기로 했다.

명령이 양쪽으로 오가는지 끝까지 확인했다. 테스트방에서 /생성 카나리아테스트를 쳐봤다. 그게 Iris → 내 서버 → 파싱 → 핸들러를 거쳐 DB에 파티가 실제로 만들어졌다(방 만든 사람이 1번 자리). 반대로, 서버에서 답을 보내면 Iris를 거쳐 테스트방에 메시지가 뜨는 것도 확인했다. 받는 쪽, 보내는 쪽 둘 다 한 바퀴 돌려본 거다.

운영방에 새 방식이 새어 들어가지 않게 막았다. 새 방식이 실수로 운영방에 답을 달면 큰일이다. 그래서 방 단위 허용목록을 넣었다. 허용한 방이 비어 있으면 아무 답도 안 하게(기본이 안전한 쪽으로) 만들었다. 또 클라우드 폰이 재부팅돼도 Iris가 알아서 다시 켜지도록 자동 시작도 붙였다. 이 둘을 PR로 올리고, 테스트방 A·B에서 자동응답을 한 번 더 돌려본 뒤, 운영 코드에도 반영했다(dev → main 승격). 운영 폰이 새 묶음 파일을 잘 받아오는 것까지 봤다.

막힌 것, 고친 것

한 군데서 막혔고, 원인을 짚어 고쳤다.

  • 새 방식 웹훅이 컨테이너에서 모듈을 못 찾고 죽었다. 내 PC에서 테스트할 땐 멀쩡한데, 컨테이너에 올리니 크래시가 났다. 원인은 폴더 위치였다. 컨테이너 안에선 서버 코드가 /app에 들어가 있어서, 코드가 찾던 상대 경로가 엉뚱한 곳을 가리켰다. 로컬에선 그 경로가 우연히 맞아떨어져서 안 보이던 버그였다. 실제로 있는 경로를 골라 쓰게 고쳐서, 양쪽 환경에서 다 돌게 했다.

돌아보며

설계 문서만 쓰고 “됐다"고 넘어갈 수도 있었다. 그런데 사용자가 못을 박았다. 받는 것만 말고 “응답 경로까지 켜라"고. 선행 단계가 있으면 그것부터 하라고도 했다. 그래서 진짜 폰을 클라우드에 띄워서, 카톡에 명령을 직접 쳐보고, 답이 돌아오는 걸 눈으로 봤다. “되겠지"가 아니라 “됐다"를 확인한 거다. 받는 쪽만이 아니라 보내는 쪽까지 한 바퀴를 돌려본 게 마음이 놓였다.

로컬에선 멀쩡한데 컨테이너에서만 죽는 버그를 만났다. 이런 게 제일 얄밉다. 내 눈앞에선 안 보이니까. 그래도 “왜 여기선 되고 저기선 안 되나"를 따라가니 폴더 위치 차이가 나왔다. 환경이 다르면 같은 코드도 다르게 본다. 이걸 다시 한 번 몸으로 느꼈다.

양방향이 다 도는 걸 확인하자 사용자가 “너가 머지해도 되지 않아?“라고 했다. 확인이 끝났으니 그 말이 맞았다. 새 방식을 들이면서도 옛 방식을 바로 안 버린 게 좋았다. 둘을 나란히 두니 마음이 편했다. 운영방엔 손 안 대고, 테스트방에서만 충분히 굴려본 뒤에 한 발씩 옮겼다. 지난번에 하루에 너무 많은 걸 몰아서 넘어졌던 게 생각났다. 이번엔 단계를 끊어서 갔다. 조금 더 차분해진 것 같다.