1. 과제 예약 프로그램 완성

bot 복사본.gif

계기

회사에서 슬랙과 카카오톡을 통해 영어 교육 스터디를 진행하고 있다. 이 두가지 메신저를 통해 매일 아침 8시에 과제를 내주는데, 새벽까지 일하고 아침에 8시에 잠깐 일어나서 과제 업로드하는게 많이 힘들다는 말을 들었다.

카카오톡은 메세지 예약기능이 있어 전날에 편하게 등록할 수 있는데, 슬랙은 기본으로 reminder라는 기능이 있지만, 등록당시에 노출이 되버리는 단점이 있어 과제를 미리 해버리는 유저들이 있어 사용하기 힘들었다.

스크린샷 2019-03-25 오후 11.38.46.png

따라서, 등록한 시간에 예약된 과제를 등록해주는 봇이 필요했고 구글에 봇을 찾으러 나섰다..
몇일동안 찾아 해맸지만 예약 메시지 등록해주는 봇은 없었고 (Node 환경에서), 슬랙에서 제공하는 SDK와 웹 페이지를 만들필요 없이 desktop 앱을 만들어주는 Electron을 이용해 서브 프로젝트로 직접 만들고자 했다!!

지난달에 완성해서 동료에게 넘겨줬지만, 과제 등록할때 이미지가 같이 올라가면 좋겠다는 피드백을 듣고 업데이트를 진행했다.

이전 버전

  1. Slack SDK

Slack Node SDK는 Webhook, rtm(Real-time-messaging), Web API 이 세가지 api를 지원하는데, 어떤 봇을 만드느냐에 따라 api를 달리 설정해야한다.
채팅을 하거나 일정을 관리하는 등 소통이 필요한 봇이라면 rtm (web socket 기반)을 이용해야 하는데, 우리는 단순히 메시지 등록만 하면 되기 때문에 Webhook을 이용하기로 했다.

Webhook은 http기반으로 양방향 통신이 아닌 slack측으로 데이터 전송만 가능한 단방향 통신이며, message 기능만 제공해주는 담백한 API라 사용하기 매우 쉽다.

(message option 문서를 찾는데 힘들었었는데, https://api.slack.com/docs/message-formatting 참고)

  1. Electron

데스크탑 앱으론, React에 너무 익숙해진 나머지 jQuery와 바닐라로 코딩했던걸 다 까먹어서(ㅡ.ㅡ) Electron에 React를 적용하는데 너무 오래 걸릴것 같아 간단하게 바닐라JS로 만들어서 넘겨줬다.

사실 예약실행 시간과 메세지만 있으면 됬기 때문에 어렵지 않게 끝낼 수 있었는데, 여기서 규모가 더 커지게되면 어찌 할지 고민이었다. 이후에 업데이트가 필요하다고 생각될 때 찾아보기로 하고 넘어갔다.

  1. Cron

과제는 매일 바뀌기 때문에 원하는 특정 시간에 API가 단발성으로 한번 실행되야 한다.
이전에 알고 있었던건 cron-node 뿐이었고, 이를 이용한다면 기본적으로 cron은 주기적으로 실행하기 때문에 실행될 job을 DB에 저장하고 매 시간마다 호출해 실행 후 제거하는 로직이 필요했다.
무작정 짜기보다 먼저 위 로직이 구현된 라이브러리가 없나 찾아보다가 Agenda라는걸 발견했다!!!

이 라이브러리 덕분에 엄청난 시간을 벌었는데, Agenda는 우리 상황에 적절하게 쓰일만한 몇몇 장점들을 갖고 있었다.

  • 코드 두줄로 DB에 job을 보관해 유지성을 높여준다.
  • 단발성 실행이 가능하다.
  • Promise 기반이다.
  • 스케줄링 시간 주기가 human-readable하다. 자체적인 human-interval을 구현하여 사용
  • job에 우선권을 줄 수 있다.
  • 관리 페이지를 제공한다 Agendash

단발성 실행이 가능한것과 mongo conecct 라이브러리가 필요없이 collection까지 직접 연결이 가능하다는 이 두가지 특징 때문에 바로 선택하여 사용했다.

  1. UTC timezone 이슈

Agenda와 Mongo DB를 구축한 서버를 EC2로 구성했는데, 큰 문제가 생겼었다. 바로, 서버시간 이슈였다.
EC2 우분투는 UTC를 기준으로 돌고 있기 때문에 클라이언트에서 Agenda의 human-interval에 맞추어서 요청을 보내도 항상 우리나라 시간 기준 -9시간에 맞춰서 실행되는 것이었다.

이를 해결하기 위해 처음에는 시간 등록하는 로직에서 +9시간을 더하여 등록시키려고 했으나, 요일 문제가 생기게 되었다.
예를 들어 08:00AM에 등록되야하므로 실제로 등록할 때는 전일 23:00PM으로 등록해야되는데, 이렇게 등록하면 human-interval에 맞춘게 전부 꼬이게 되어 요일까지 고려하게 되는 상황에 이르렀다.

다른 방안이 없나 찾아보다가 한국시 기준의 Javascript Date 값을 반환해주는 라이브러리 flatpciker 를 찾았다.
이 라이브러리는 datetimepicker로 날짜, 시간을 모두 고려할 수 있기 때문에 도입할 수 있었다.

업데이트 버전

이번 업데이트에서 구현하고자 했던건 두가지로,

  • 작성 중인 과제가 바로 보면서 체크할 수 있는 컴포넌트 추가
  • 사진 등록

반나절 정도 걸렸던것 같다.

  1. 바닐라JS -> React

이전에 Electron에서 React를 연결하지 않고 바닐라로 만들었는데, 이번엔 CRA에서 eject 하지 않고(Webpack을 잘 모르기때문에) 연결할 수 있는 방법을 찾아보다 https://medium.freecodecamp.org/building-an-electron-application-with-create-react-app-97945861647c
이 블로그를 참고 삼아 작업할 수 있었다.

이 블로그에선 foreman이라는 프로세스 관리도구와 socket을 뚫어 react-dev server의 실행을 기다린후 실행된 URL(localhost 포트)을 Electorn이 실행하는 방식으로 CRA를 유지하고 있다.

  1. S3 버킷을 활용한 사진 업로드

사실 동료분께서 사진을 넣을 수 없냐고 물어봤을 때, S3에 대한 생각을 전혀 못하고 있었다.
AWS 스터디 때문에 공부 하던 도중 S3가 프리티어로 꽤 많이 지원을 해준다는 걸 보게 되었고, 또 이전 프로젝트에서 S3에 프로필 사진들을 넣었던 기억이 나서 S3를 활용하고자 했다.

이전과 동일하게 파일 업로드 툴인 multer와 aws-sdk를 사용하여 이미지 object의 endpoint를 부여하는 방식으로 진행했는데, 이번엔 aws-sdk에 등록하는 을 S3에 등록, 열람권한만 설정한 IAM user생성하여 추가로 적용해 봤다.

원래는 IAM role을 만들어서 EC2에 부여하려고 했는데, aws-sdk ACCESS 등록을 할 수 없어 user를 만들어서 적용했다.

최종 구조도

Untitled Diagram.png

2. AWS Elastic Beanstalk

우리 서비스는 모바일 어플이 중심인 서비스이다.
내가 오기전 마치 웹 서비스처럼 백엔드가 구축이 되어 있었고, 당장 모바일에 최적화된 백엔드 서비스를 구현할 능력이 아직 부족해서 구현하지 못하고 있다.

다만, 사용자 수가 아직 많지 않고 대형 서비스가 아닌지라 웹 서버처럼 구축해서 계속 사용하고 있는 중이며, 후에 amplify가 서울리전에서 서비스 되기 전까지 필요한것들을 배워가며 존버할 예정이다.

지난주에 EC2, ALB, ASG를 배우며 기본적인 Web 3-tier architecture를 배웠다.
이 구조를 이용하여 웹 서버를 구축하면서 몇가지 문제가 있다.

  1. 서버가 업데이트 된다면 ASG의 인스턴스에 반영하기 위해선 AMI를 다시 따서 교체해야한다.
  2. 동일한 구조의 또 다른 서버를 구축하려면 똑같은 구조 구축을 반복해야한다.

이러한 번거로움을 줄이기 위해 AWS에선 Elastic Beanstalk이란 플랫폼 서비스를 제공한다.

Elastic Beanstalk이란?

  • EC2, ASG, RDS등 AWS 리소스들을 조합하여 완성된 어플리케이션 플랫폼으로, PaaS(Platform as a Service)의 일종이다.
  • EB 콘솔이나 CLI로 로드 밸런싱, 오토 스케일링, 모니터링 관리, 인스턴스 설정 및 OS 설치를 지원한다.
  • 기본적으로 제공되는 어플리케이션은 Node, PHP, Java, Ruby, Go등 다양한 언어를 지원하며, git, Docker까지 지원가능하다.
  • 추가로 실제로 서비스를 제공하는 AWS 리소스가 아닌 플랫폼이기 때문에 사용요금은 사용되는 리소스만 부과한다.

Elastic Beanstalk의 장점

  • S3에 소스코드가 저장되고, git이나 Docker가 지원되어 버전 관리에 뛰어나다.(S3는 오브젝트의 기록이 남기 때문에)
  • 이 플랫폼안에서 로드 밸런싱, 오토 스케일링이 지원되어 편리하다.
  • 서버코드를 develop환경으로 배포하여 빠르게 테스트 할 수 있다.
  • 기타 등등..

이후 좀 더 학습해서 수요일에 업데이트 해야겠다.

3. 라즈베리파이

주말에 너무 피곤해서 아무것도 안해서 못봤다....
진짜진짜 내일부터 볼것이다.