アプトポッドのソリューションアーキテクト尾澤です。
当社のソリューションアーキテクトは、社内の技術開発メンバーと連携してお客様視点に立った技術仕様を取りまとめ、案件の提案活動から関わっています。案件がめでたくお仕事につながれば、プロジェクトを推進するPM役も兼務していきます。当社は、取引相手の企業様のなかでも未来を見据えた先進的な取り組みを担っていらっしゃるセクションにクライアントが多く、どの案件もとても興味深くエキサイティングな環境です。プロジェクトマネージャやエンジニアとしてより刺激的な仕事に携わりたい!と思っている方は、ぜひ当社の採用ページやWantedlyを覗いてみてください。
さて、そんな私もエンジニア出身なのですが、最近はなかなかコードを書く機会がなく、折に触れいわゆるゴミプログラムを書いて楽しんでいます。今回はそんなゴミプログラムのうち、もっとも実用的だったものをご紹介します。
ここ数ヶ月、私が入社してからアーキテクトが少し増えてきたので、定例会を設けて各自が担当しているプロジェクトの共有をすることにしているのですが、時間の都合上すべてのプロジェクトを追うわけにもいかず、動きが活発なプロジェクトを優先して議題に取り上げています。この「動きが活発なプロジェクト」を自動的に判別したいと考えました。当社ではコミュニケーションツールにSlackを使っており、プロジェクトごとに「pj_xxxxx」といった命名ルールでチャンネルを設けています。以下のコードでは、プロジェクト関連のチャンネルを対象に発言数を集計しています。
main.py
import os
import re
import time
import datetime
import json
import urllib.parse
import urllib.request
import numpy as np
import pandas as pd
API_URL_BASE = "https://slack.com/api/search.messages?token=%s&query=%s&count=100&page=%d&sort=timestamp&sort_dir=desc"
SLACK_API_TOKEN = os.environ['SLACK_API_TOKEN']
SEARCH_PERIOD = 7 # days
REQUEST_INTERVAL = 5 # seconds
# CHANNEL_PATTERN = "^.*$" # default all channels
CHANNEL_PATTERN = "^pj_.*$"
channels = []
re_ptn = re.compile(CHANNEL_PATTERN)
base_d = datetime.date.today() - datetime.timedelta(SEARCH_PERIOD)
q = urllib.parse.quote("after:%s" % base_d.strftime("%Y-%m-%d"))
p = 1
while True:
url = API_URL_BASE % (SLACK_API_TOKEN, q, p)
res = urllib.request.urlopen(url)
json_res = json.loads(res.read().decode('utf8'))
paging = json_res['messages']['paging']
print("%d/%d" % (paging['page'], paging['pages']))
for message in json_res['messages']['matches']:
ch_name = message['channel']['name']
if (re_ptn.match(ch_name)):
channels.append(ch_name)
if (p >= paging['pages']):
break
p = p + 1
time.sleep(REQUEST_INTERVAL)
ch_np = np.array(channels)
ch_df = pd.DataFrame({'channels': ch_np})
print(ch_df['channels'].value_counts())
- API TOKENは環境変数から取るようにしました
- SEARCH_PERIODで集計期間を指定できます
- GETリクエストを乱発すると
HTTP 429 Too Many Requests
になるのでREQUEST_INTERVALを設けています - CHANNEL_PATTERNを
^.*$
にすれば全てのチャンネルが対象になるはずです
結果はこんな感じになります。
pj_poteto 244
pj_orange 160
pj_tomato 145
pj_carrot 72
pj_apple 43
pj_eggplant 28
pj_lemon 12
pj_mushroom 10
pj_onion 3
pj_pineapple 1
Name: channels, dtype: int64
今後はこれを定例会の前夜にアーキテクトチームのチャンネルにポストするようにしたいと思います。