##概要
表題の通り。
主にpythonでjsonを扱う際に何に気をつけるべきかをまとめる。
##やりたかったこと(下記の画像の通り。)
①slackのメンバーを取得(member_list.py)
②定時起動で出勤に合わせて、APIでメッセージを送信。(postMessage.py)
③メンバーがリアクション。
④APIで上記②にリアクションをした人を取得。(reac_result.py)
⑤リアクションを押下していないリストを作成。
⑥上記⑤で作成したリストに対してAPIでメンション。(postMessage_re.py)
#わかったこと抜粋(①、②、④、⑤、⑥)
##①でのコード抜粋、わかったこと
■辞書(dict型オブジェクト)の値はkeyで選択して抽出できること
下記のコードではgetしたresponseから名前を抜き出そうとしている。
r = requests.get(url, params=payload)
result_mem = [] # 結果を入れるリストを用意
json_data = r.json()
members = json_data["members"]
for i in members:
result_mem.append(i["real_name"])# 結果を追加
ppront.pprint(result_mem)#['Slackbot']
#json_dataには以下のようなデータが格納されている。
{"ok": true,
"members": [ {"id": "USLACKBOT","team_id": "T012YMJ67V1","real_name": "Slackbot"
d = {'key1': 'aaa', 'key2': 'bbb', 'key3': 'ccc'}
value = d['key1']
print(value) #aaa
つまり{"key" : value,}
なので、value("Slackbot")を取得したい場合は、key("real_name")を指定する。
##②でのコード抜粋、わかったこと
■関数から関数の呼び出し元へ任意の値を返す場合には returnを使用すればよいこと
下記のコードではgetしたresponseからタイムスタンプを抜き出そうとしている。
def postMessage():
r = requests.post(url, params=payload)
result_text = [] # 結果を入れるリストを用意
json_data = r.json()
ts = json_data['ts']
return (ts)
import datetime
import def_postMessage
a = def_postMessage.postMessage()
with open(str(datetime.date.today())+'_ts.txt', mode='a') as f:
print(a,file=f)
def_postMessage.pyで取得したts(タイムスタンプ)が戻り値で、それをpostMessage.pyが使用している。
slackではtsが一意なのでメッセージを特定することができる。
##④でのコード抜粋、わかったこと
■ネスト(入れ子)の時、値を取得したい場合は、JSONの構造を理解する必要があること
■参考はここのサイト
■returnでの戻り値には、変数を指定できること
下記のコードではgetしたresponseからリアクションをした人を抽出しようとしている。
def reaction():
r = requests.get(url, params=payload)
json_data = r.json()
reac_tmp1 = json_data['messages'][0]['reactions'][0]['users']
reac_tmp2 = json_data['messages'][0]['reactions'][1]['users']
reac_tmp3 = json_data['messages'][0]['reactions'][2]['users']
return(reac_tmp1,reac_tmp2,reac_tmp3)
{'channel_actions_count': 0,
'channel_actions_ts': None,
'messages': [{'bot_id': 'B012YMHEVJN',
'bot_profile': {'app_id': 'A0134SP1ZA8',
'id': 'B012YMHEVJN',
'name': 'test',
'team_id': 'T012YMJ67V1',
'reactions': [{'count': 3,
'name': 'syukkin',
'users': ['U012JDYRD2T',
'U013BQDLK6V',
'U012ZC8AQ8K']},
{'count': 2,
'name': 'tikoku',
'users': ['U012XQBE63X', 'U012JDYSN07']},
{'count': 1,
'name': 'kekkin',
'users': ['U012JDYSN07']}]
■やっていること(reac_tmp1 = json_data['messages'][0]['reactions'][0]['users']
の場合)
①変数名json_data を指定
②その中の'messages'プロパティへアクセスしたいので、["messages"]
と指定。
③messages にはオブジェクトの配列が格納。 ここでは、配列内の 1番目のオブジェクトへアクセスするので、[0]
を指定。(【'messages': [{'bot_id'】云々の以下すべてにアクセス)
④そのオブジェクト内で'reactions'プロパティへアクセスするため, ["reactions"]
と指定。
⑤その中の1番目が欲しいので、[0]
と記述。(2番目が欲しいときは[1]、3番目が欲しいときは[2])
⑥そのオブジェクト内で'users'プロパティへアクセスするため, ["users"]
と指定。
つまり
送信したメッセージのリアクション(reactions)をしたメンバー(users)がreac_tmpに格納されている。
(reac_tmp1-3まであるのは、【出勤】【遅刻】【欠勤】と3つあり、この3つのリアクションをした人が誰かを知りたいから。)
##⑤でのコード抜粋、わかったこと
別記事で投稿。
https://qiita.com/nonono_kita/items/588ad61431e97724deab
##⑥でのコード抜粋、わかったこと
別記事で投稿。
https://qiita.com/nonono_kita/items/e83a3b918aa572b69adf
##今後やりたいこと、できそうなこと
・エラー時のための条件分岐。
・DBを用意、リアクションを押下したメンバーの情報をもとに、更新をかける処理。
・更新処理後、リアクションを押下していない人に、メンションする処理。
##課題
■条件分岐を用意していない。そのため
・メッセージにリアクションがないとエラー
・メッセージにリアクションが少ないとエラー
・出力したファイルが存在しないとエラー
・出力したファイル名が異なるとエラー
##思ったこと
・jsonでデータを取得した際に、その関数や処理内でデータを加工するよりは一度データに出力した方がよさそう。
出力して、そのあとに必要なデータを加工。その方が関数を使いまわせそう。
・あと記事が長くなるので、項目ごとに記事を書いた方が良いかもしれない。