티스토리 뷰

개요

 

Slack 에서 다른 timezone 팀원과 대화를 나누는 경우,

업무시간이 지났는데 말을 거는건 아닌가 싶어서 팀원의 현재시간이 궁금할때가 많았다.

이때 간단한 Slack Slash Command 해당 timezone 현재시간을 확인할 있도록 구현해 본다.

 

목표

 

1./tz [zoneName or Time] 입력을 받으면 정규식으로 변환해서 찾아내기

- 예를 들어 시드니의 현재 시간을 알고 싶으면 /tz syd 치면 되도록 한다.

2./tzn, /tzs 뉴욕시간, 서울시간 바로 나타내기

3. - 업무시간인지 여부를 색깔로 표시하기

- 국가별 공휴일과 근무시간까지 체크하는 너무 오버인듯 하여 -, 9 to 6 체크한다.

 

 

참고 링크

 

Timezone database name: https://www.wikiwand.com/en/List_of_tz_database_time_zones

GitHub 구현코드 링크: https://github.com/nicewook/slack-timezone-current-time

 

* 기존에 구현했던 Slack Slash Command - 영한 번역

: 대부분의 내용은 아래 링크와 중복되는 부분이 있어서, 가능한 개념 위주로 정리하려

https://jusths.tistory.com/136

https://jusths.tistory.com/137

https://jusths.tistory.com/138

 

구현 개념도

 

1) https://api.slack.com/apps/new 에서 slack slash command 만들어준다.

- 원하는 명령어와, 명령이 실행되었을때에 이를 처리해줄 HTTP Server 위치를 설정해준다.

- 이렇게 만든 Slack App 명령이 실행되면 HTTP Request 생성해서, 설정해준 HTTP Server 보내고, 결과를 돌려받는다.

 

2) 생성이 완료되었으며 slack Workspace install 해준다.

- 1) 에서 만든 Slack APP 설치되었으므로

- Workspace 에서 명령이 실행되면 HTTP Request 지정한 HTTP Server 날아가게 된다.

 

3) HTTP Server 구현하고 돌려놓는다.

- 우선은 Local PC 에도 동작하도록 하지만 이후 구글의 Cloud function 사용한다.

- 수신한 Slack HTTP request 처리하여 결과를 Slack App에게 response 한다.

 

Slack Slash Command 만들어보자.

 

자세한 사항은 링크를 참고한다 https://jusths.tistory.com/136

 

1) App Name   TimeZoneCurrentTime 으로 정하고 Slack Slash Command 3개를 만들었다.

- https://api.slack.com/apps/new 에서 만들 있다.

- /tz: 뒤에 timezone name 넣으면 해당 timezone 현재시간을 회신해준다.

- /tzn: 협업 엔지니어는 현재 뉴저지에 있으며 timezone "America/New_York" 이다.

- /tzs: 나의 현재 위치는 한국이므로 timezone "Asia/Seoul" 현재시간을 리턴해준다.

 

2) Command 실행되었을때에 HTTP Request 보낼 HTTP Server Request URL 설정해준다.

- serveo.net 이라는 사이트의 포트포워딩 서비스를 이용하면, 개발중인 로컬 PC 사용할 있다.

- $ssh -o ServerAliveInterval=60 -R 80:localhost:8080 serveo.net 라고만 치면 된다.

- 이때 자동 할당되는 url Request URL 설정하면 된다.

- xxx.serveo.net 이라고 생성되는데 각각의 Slack Slash Command 대해서 endpoint 설정해주면 된다.

예를 들어 alpha.serveo.net 이라고 생성되었다면

- /tz 경우: alpha.serveo.net/tz

- /tzn 경우: alpha.serveo.net/tzn

- /tns 경우: alpha.serveo.net/tzs

 

3) 원하는 Slack Workspace 생성한 App install 하면 Slack 에서 HTTP Request 보낼 준비는 끝이다.

- Workspace 없다면 하나 만들어두면 된다.

 

4) 마지막으로 App Signing Secret 메모해두자.

- Slack App 통해 HTTP Request 보낼때에 Signing Secret 으로 (말그대로) 싸인을 한다.

- 우리가 만드는 HTTP Server 정보를 가지고 실제 우리의 Slack App 보낸 메시지가 맞는지 검증한다.

 

로컬에서 동작할 HTTP Server 만들어보자.

 

자세한 사항은 링크를 참고한다 https://jusths.tistory.com/136

실제 구현은 GitHub 참고한다 https://github.com/nicewook/slack-timezone-current-time

 

환경변수 설정

 

환경변수 SLACK_SIGNING_SECRET 위에서 메모해둔 App Signing Secret 설정해준다.

 

- 윈도우라면 $set SLACK_SIGNING_SECRET=<Signing Secret of your Slack App> 라고 해주거나,

- 아예 윈도우 설정에서 환경변수로 설정할 있겠다.

- 설정된 값은$set SLACK_SIGNING_SECRET  으로 확인할 있다.

 

verifySlackSignature()

 

timezone-calc.go verify 관련 부분부터 보자

 

Slack App 에서 생성한 HTTP Request signature 가지고 있는데

SLACK_SIGNING_SECRET 이용하면 우리의 Slack App 에서 보내온 것인지를 검증할 있다.

자세한 설명은 링크를 참고하고https://jusths.tistory.com/136 ) 이와 관련한 함수들은 아래와 같다.

 

init()

verifySlackSignature()

checkMAC()

abs64()

 

Web Server Mux

 

main.go 보자

 

Golang 유명한 HTTP Router 로는 gorilla/mux 또는 httprouter 등이 있는데

어짜피 우리 구현은 단순하므로 Standard library net/http 이용하도록 한다.

- Golang 쓰다보니 무리가 없으면 순정을 사용하는게 좋다고 ... (근거없음)

 

내용이 없다.

 

1) http.NewServerMux() 핸들러를 생성한 다음

2) /tz, /tzn, /tzs 각각의 endpoint 들어오는 HTTP request 대해

- 각각의 함수가 handle 하도록 설정하는 것이 전부이다.

 

3) 그리고 http.ListenAndServer() 돌려서 수신  준비 완료

 

*참고 링크: https://gist.github.com/reagent/043da4661d2984e9ecb1ccb5343bf438

참고로, go.mod 자동 생성한 다음 왼쪽과 같이 replace 먹여서

api 패키지의 상대 주소를 가리키게 하였다

 

Timezone Database Name

 

api 폴더의 timezone-name.go 파일에  Timezone Database Name 정보를 미리 넣어두었다.

 

데이터는 여기에서 추출하였다.

- https://www.wikiwand.com/en/List_of_tz_database_time_zones

 

문자열을 Golang time.LoadLocation() 함수에 넣어주면 *Location 타입의 리턴값을 얻을 있고,

이것을 Time 리시버인 In() 함수에 넣어주면 해당 Timezone 시간으로 변환해준다.

 

 

Timezone Current Time

 

이제 가장 핵심인 원하는 Timezone 현재시간을 얻어내는 방법을 알아보자.

timezone-calc.go 에서 /tz 핸들링하는 부분만 보자.

- /tzn, /tzs 더욱 간결하다.

 

1) verifySlackSignature()

 

- 우리의 Slack App에서 보내온 HTTP Request 인지를 verify 한다.

 

2) slack.SlashCommandParse()

 

- github.com/nlopes/slack 패키지를 이용하여

- Slack 보내온 메시지를 parsing 한다.

- 우리에게 필요한 것은 s.Text 이다. 사용자가 원하는 timezone 정보이다.

 

3) Timezone database name 얻기

 

- 우리가 가진 데이터인 timezoneNameArray 값들이

- Slack App 보내온 s.Text 포함하고 있는지를 regexpMatchString() 으로 찾아내어

- 이때 ToLower() 이용하여 대소문자를 무시하고 찾도록 해준다.

- 우리가 만든 makeResponse() 이용하여 양식에 맞춰 Timezone Current time 리턴하도록 한다.

- regexp 만족하는 Timezone Database Name 여럿이면 계속 이어붙이도록 한다.

 

4) Response

 

- Slack App 회신할 response 보내느 부분이다.

- 만약 만족하는 timezone 하나도 없을 경우의 처리도 구현하고

- &slack.Msg 응답을 작성한 다음, json.Marshal() 직렬화하여 보내면 된다.

 

* makeResponse() checkTime() 네이밍에 너무 성의가 없는것 같긴 하다.  

 

1) time.LoadLocation() 으로 *Location 타입을 loc 리턴 받으면

 

2) time.Now().In(loc) 현재시간을 loc 시간으로 바꿔준다.

 

3) 그리고 checkTime() 함수를 통해 업무시간인지를 확인한다.

- -, 9 to 6 인지의 체크

 

4) 업무시간에 따라 response message 내용을 다르게 구성하고

5) time.Time 리시버 함수인 Format() 함수를 이용하여 포맷을 다듬는다.

 

checkTime()  없다.

 

- time.Time Weekday(), Hour() 리시버 함수를 이용하여

- - , 9 to 6 인지를 확인하여 bool 값을 회신해준다.

 

 

구현을 확인하기

 

1) $ssh -o ServerAliveInterval=60 -R 80:localhost:8080 serveo.net 실행된 상황에서

- Local PC Port Forwarding 이다.

 

2) go run main.go Http Server 구동시킨다.

 

3) Slack App install Workspace 에서 Slack Slash Command 실행해본다.

 

각각 /tzn, /tzs 실행된 결과이다

/tz syd 실행한 결과이다

 

- "Australia/Sydney" 찾아낸 것이 보인다.

/tz mos 실행한 결과이다

 

- mos 포함하는 시간대의 현재시간이 출력된다.

 

To be Continued on "Slack Slash Command - timezone current time 2/2"

 

다음에는 간략히 Google Cloud Functions 올려보겠다.

 

Google Cloud Functions 경우 endpoint 하나당 하나의 Cloud Function 실행해야 하는 부분이 마음에 안들어서

Heroku 올리고, 겸사겸사 Travis CI 까지 복습할까 했지만 (toy project 로는) 일이 너무 커지고 곁가지로 빠지는 같고,

Heroku 무료 사용인 경우 일정시간 sleep 빠지는 것이 마음에 들지 않아 Cloud functions 선택하였다.

 

개인적으로 작은 Workspace 에서 그리 자주 쓰지 않는 Slack app 대응해주는 경우라면 비용은 거의 들지 않는다.

 

반응형

'golang' 카테고리의 다른 글

Go Slice Tricks  (0) 2019.12.27
Slack Slash Command - timezone current time 2/2  (0) 2019.09.19
xid: golang GUID 생성 package 둘러보기  (0) 2019.08.16
Go runtime AND goroutine  (0) 2019.07.23
Golang 의 동시성을 이용한 소수 찾기  (0) 2019.07.22
반응형
잡학툰 뱃지
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함