2018年8月16日木曜日

お盆休みに Python スクリプトをいじる (2)

前回の続きで Slack に投稿された 1 日前のメッセージをすべて削除するスクリプトを作りましたが、スターをつけたメッセージは削除せずに残す機能を追加します。スターをつけるとメッセージに is_starred という属性が追加されて True の値が入っています。

# True だったら削除せず次へ
if m["is_starred"]:
    continue

なのでこんな処理を書いたんですが、スターがついているメッセージはこれで良いんですが、スターがないメッセージはそもそも is_starred という属性がなく参照エラーになってしまいました。わざわざ try ~ catch 書かなきゃならんのか?と思ったけど、ググったら色々でてきました。

pythonのdictionaryでKeyErrorを出さないようにする
https://qiita.com/sue71/items/b7f5c9373d0af587e256
辞書型のKeyError対策
https://qiita.com/mas9612/items/403fac796757ccf4e102

get() でその属性があるかどうかがわかるらしいです。今回の場合だと is_starred という属性があれば、スター付きだよねってわかるので get() で None が返ってこなかったらスター付きという風にしまいました。

#coding: utf-8
import urllib.request
import urllib.parse
import json
import time
import datetime

hist_url = "https://slack.com/api/channels.history"
delete_url = "https://slack.com/api/chat.delete"

token = 'トークン'
# チャネルID配列
channels = ["チャネルID","チャネルID","チャネルID"]

# 本日 0 時の unixtime 取得
today = datetime.date.today()
msects = time.mktime(today.timetuple())
#print(msects)

for channel in channels:
    hist_params = {
        'channel' : channel,
        'token' : token,
        'count' : '200'
    }

    req = urllib.request.Request(hist_url)
    hist_params = urllib.parse.urlencode(hist_params).encode('ascii')
    req.data = hist_params

    res = urllib.request.urlopen(req)

    body = res.read()
    data = json.loads(body)

    for m in data['messages']:
        print(m)

        # スターのついたメッセージは消さない
        if m.get("is_starred") != None:
            continue

        # 前日より前のメッセージは削除
        if float(m["ts"]) < msects:
            delete_params = {
                'channel' : channel,
                'token' : token,
                'ts' :  m["ts"]
            }
            req = urllib.request.Request(delete_url)
            delete_params = urllib.parse.urlencode(delete_params).encode('ascii')
            req.data = delete_params

            res = urllib.request.urlopen(req)
            body = res.read()

            print(body)

            time.sleep(2)