[Slack] 비공개 채널 게시물 (POST)을 일괄 다운로드하는 스크립트를 작성했습니다.

슬랙 포스트 (POST) 정보



포스트 은 Slack의 기능의 하나로, 통상보다 긴 문장의 메시지나, 서식 첨부의 메세지를 투고하는 경우에 이용할 수 있습니다. 게시된 게시물은 여러 사람이 공유하고 편집할 수 있습니다.



한 프라이빗 채널에 많은 게시물이 있으며 과거를 일괄 다운로드하고 싶습니다. 가져오기 및 내보내기 설명 보였다.

요금 플랜 (을)를 보면 그 가격은¥1,600(액티브한 유저 1명당, 연불의 경우의 월액 비용). 스탠다드의 2배 미만이 되고 있어, 이 export를 위해서만 업그레이드 하는 것은 조금 어렵기 때문에, API를 사용해 일괄 다운로드하는 스크립트를 만들어 보았습니다.

처리 흐름 및 스크립트



API 사양 을 보면, 프라이빗 채널은 API에서는 "group"이 되고 있어 이하의 흐름으로 포스트의 취득을 실현할 수 있을 것 같습니다.

1) 투고한 메시지 일람의 취득에 채널의 ID(group id)가 필요하기 때문에, 우선 groups.list 메소드로 채널 일람을 취득
2) 목록에서 취득 대상 그룹을 사용자가 선택
3) 선택한 채널에 대해 게시된 메시지의 기록을 groups.history 메서드로 가져오기
4) 각 메시지에 대해 게시물이 있으면 로컬 파일로 다운로드
5) groups.history 메소드는 한 번에 최대 1000 건 밖에 얻을 수 없기 때문에, 계속이 있는 경우 (리스폰스에 "has_more": true 가 있으면), 3) 와 4)를 반복한다

이 중, 4) 의 「포스트가 있으면」의 판정입니다만, 포스트는 Slack 내부적으로는 「텍스트 형식의 첨부 파일」로 구현되고 있어 mimetype 가 'text/plain' 인 첨부 파일을 모두 취득하도록 했습니다. API 응답에서는 일반 공유 파일(텍스트 형식의 파일을 첨부한 경우)과 구별할 수 없기 때문에 공유 파일도 다운로드 됩니다.

작성한 스크립트는 다음과 같습니다.

getFilesFromPrivateChannel.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from slackclient import SlackClient
import urllib2
import re
import datetime, time

# Slackのトークン
slack_token = '<ここにトークンを設定>'

# プライベートチャンネル(チャンネルID)のリストを取得
def getPrivateChannelIdList(slack_client):
  result = []
  group_list = slack_client.api_call(
    'groups.list',          # プライベートチャンネル取得APIは groups.list
    exclude_archived=False, # レスポンスにアーカイブチャンネルを含めるか(含める場合にFalse)
    exclude_members=True    # レスポンスにユーザ一覧を含めるか(含める場合にFalse)
  )

  if group_list['ok'] == True: # 正常なレスポンス
    groups = group_list['groups']
    for i in range(len(groups)):
      group_name = groups[i]['name']
      print str(i) + ' : ' + group_name # グループ名を標準出力
      result.append(groups[i]['id'])    # グループIDをリストに追加
  else:
    print 'Error at groups.list API:',
    print group_list

  return result

# チャンネルに投稿されたメッセージを取得し、ポスト(テキスト形式の添付ファイル)があればファイル出力
def outputFilesFromChannel(slack_client, channel_id):

  latest_time = 9999999999.999999 # 厳密には現在時刻だがこれでもOK
  has_more = 1 # チャンネルに1000件を超える投稿があれば1000件ごとに繰り返す
  while has_more == 1:
    comment_list = slack_client.api_call(
      'groups.history',   # 投稿取得APIは groups.history
      channel=channel_id,
      latest=latest_time,
      count=1000          # 1度に取得できる件数は最大1000件
    )

    if comment_list['ok'] == True:
      for comment in comment_list['messages']: # 各投稿をチェック

        latest_time = comment['ts']
        if comment.has_key('subtype') and comment['subtype'] == 'file_share' and \
           comment.has_key('file') and comment['file'].has_key('mimetype') and \
           comment['file']['mimetype'] == 'text/plain':

          # ファイル共有があり、かつそのmimetypeがテキスト形式の場合のみ、添付ファイルを出力
          file_title = comment['file']['title']
          file_timestamp = datetime.datetime.fromtimestamp(comment['file']['timestamp'])
          out_file_name = file_timestamp.strftime('%Y-%m-%d_%H%M%S') + '_' + comment['file']['id'] + '.txt'

          # ダウンロードはAPIが無いので、ヘッダにtoken設定してurllib2で取得
          req = urllib2.Request(comment['file']['url_private_download'])
          req.add_header('Authorization', 'Bearer ' + slack_token)
          with open(out_file_name, 'wb') as myfile:
            myfile.write(urllib2.urlopen(req).read())
            print 'Output : ' + out_file_name + '(' + file_title + ')'

      if comment_list['has_more'] == False: # 1000件以下なら終了
        has_more = 0

    else:
      print 'Error at groups.history API:',
      print comment_list
      break

  return

if __name__ == '__main__':

  slack_client = SlackClient(slack_token)

  private_channel_list = getPrivateChannelIdList(slack_client) # チャンネル一覧取得

  if len(private_channel_list) > 0:
    print 'Select channel num(0-' + str(len(private_channel_list)-1) + '):',
    input = raw_input() # 標準入力から対象チャンネルを選択

    channel_id = private_channel_list[int(input)]
    outputFilesFromChannel(slack_client, channel_id) # 選択したチャンネルに対して、ファイル出力
  else:
    print 'private channel num is 0'

실행해보기



실행에는 토큰이 필요하므로, 이하로부터 취득합니다. 미발행의 경우는 「Create token」으로 발행해 주세요.
htps : // 아피. scck. 이 m / ku s와 m-in g 라치 온 s / ぇ가 cy-와 s

스크립트 10행의 <여기에 토큰 설정>으로 설정하고 스크립트를 실행합니다. slackclient이 설치되어 있지 않으면 먼저 설치하십시오.
pip install slackclient

실행 예:
$ python getFilesFromPrivateChannel.py
0 : team-general
1 : team-randam
2 : team-meeting
3 : test-a17
4 : test-a18
5 : test-a19
Select channel num(0-5): 1
Output : 2018-01-25_151642_F8ZCQA19V.txt(ポスト(POST))
Output : 2017-12-20_112936_F8GFXA4D9.txt(2017-12-21 - メモ)
Output : 2017-11-22_160327_F83BM9KEU.txt(2017-11-22 - メモ)
Output : 2017-10-25_143619_F7P27V5QE.txt(2017-10-26 - メモ)
$ cat 2018-01-25_151642_F8ZCQA19V.txt
{"version":100,"revision":139,"root":{"children":[{"type":"p","text":"・これが"},{"type":"p","text":"・ポスト"},
{"type":"p","text":"・POST"},{"type":"p","text":"・通常よりも"},{"type":"p","text":"・長めの"},{"type":"p","text"
:"・メッセージ"},{"type":"p","text":"・複数人で","formats":{"i":[0,5]}},{"type":"p","text":"・共有しての","formats
":{"i":[0,6]}},{"type":"p","text":"・編集も可能","formats":{"i":[0,6]}},{"type":"p","text":""}]}}

잘 다운로드 할 수 있었던 것 같습니다. 파일은 json 형식이므로 필요에 따라 성형하고 사용할 수 있습니다.

좋은 웹페이지 즐겨찾기