본문 바로가기

Toy Projects/Google Apps Script

Google Apps Script와 Slack API로 특정 채널 메시지 모두 추출하기

  • Google Apps Script와 Slack API를 이용하여 특정 슬랙 채널의 메시지를 추출하는 방법에 관한 글입니다.

문제

  • 회사 슬랙의 특정 채널에 올라오는 메시지들을 모두 추출하여 대시보드를 만들어야 했다.
  • 슬랙 어드민은 채널의 모든 메시지를 추출 할 수 있지만, 정기적으로 요청하기보다는 슬랙 API를 이용해서 자동화를 해두는 게 좋겠다고 판단했다.

Slack API 사용 전 준비 사항

  • 아래 준비사항들은 구글링하면, 너무도 많이 나오고 친절하게 설명되어 있어서 굳이 설명하지 않았다.
  • Slack API 페이지에서 Slack App을 생성해야 한다.
  • OAuth & Permissions 페이지에서 권한을 설정해야 한다.
    • 슬랙 채널에서 메시지들을 추출할 때 필요한 권한은 아래와 같다. 메소드별로 필요한 권한이 정리된 페이지가 있으니 참고하자. 나중에 권한을 수정할 경우 슬랙 앱을 재설치하고 어드민에게 다시 승인받아야 하는 매우 귀찮은 일이 벌어질 수 있으니 꼼꼼히 읽어보자.
      • channels:history
      • groups:history
      • im:history
      • mpim:history
  • 슬랙 워크스페이스에 앱을 설치해야 한다.
    • 슬랙 설정에 따라 어드민에게 승인 받아야 할 수도 있다.
  • 메시지를 추출하고 싶은 채널에 해당 앱이 설치되어 있어야 한다.

슬랙 채널 메시지 추출 방법(설명)

  • 아래와 같은 간단한 방법으로 채널의 모든 메시지를 JSON 형태로 가져왔다.
  • 특정 채널의 모든 메시지를 가져오기 위한 슬랙 API 기본 url은 "https://slack.com/api/conversations.history?channel=채널ID"이다.
    • 채널ID는 워크스페이스의 모든 채널을 추출하는 API로 확인하거나, 슬랙을 웹 버전으로 열어서 확인할 수 있다.
  • 한번의 API 호출로 많은 데이터를 가져오기 위해 url에 limit 파라미터를 넣었다.
  • 토큰은 슬랙 앱을 설치한 후 OAuth & Permissions에서 bot token을 사용하면 된다.
  • 만약 설정한 limit보다 메시지 개수가 많다면, pagination을 따라서 여러 번 호출해야 하는데, 그건 response.has_more 키의 값을 보면 알 수 있다.
    • response.has_more = True인 경우, 다음 페이지가 있다는 뜻이다.
    • 만약 다음 페이지의 데이터를 가져오고 싶다면, 기본 url에 cursor 파라미터를 추가로 넣어야 한다.
    • 이 커서는 첫 번째 호출했을 때 response.response_metadata.next_cursor 키의 값을 가져오면 된다.
    • 마지막 페이지까지 가면 에러가 발생하는데, 나는 try catch문을 이용하여 반복문을 break하는 방식으로 해결했다.

슬랙 채널 메세지 모두 추출

슬랙 채널 메시지 추출 방법(코드)

  • 나는 구글 스프레드시트에 데이터를 적재 후 가공하는 것까지 진행했지만, 여기서 간단히 소개하는 목적이므로 기본 코드만 작성했다.
// 필요한 정보들 모음
var obj = {
    url : 'https://slack.com/api/conversations.history?channel=<채널ID>&limit=1000',
    token : '<bot 토큰>'
}

// url과 token이 주어지면, API 호출 결과를 반환하는 함수 선언
function getResponse(url, token){
  var headers = {'Authorization' : 'Bearer ' + token};
  var params = {'method' : 'GET',
                'headers' : headers};
  var response = UrlFetchApp.fetch(url, params);
  var responseJson = JSON.parse(response.getContentText());
  return responseJson;
}


function init(){
  var response = getResponse(obj.url, obj.token);
  Logger.log(Object.keys(response));
}