LINE WORKS の監査ログを Google スプレッドシートに投入する

LINE と違い、LINE WORKS には様々なユーザー管理用 API があります。
https://developers.worksmobile.com/jp/document?lang=ja

今回は python を使って監査ログ API を使ってトークログを抽出し、分析しやすいように Google スプレッドシートに投入してみました。
https://developers.worksmobile.com/jp/document/30014002?lang=ja
*エラー処理もしていないので、実際に使う際にはご注意ください。
Python のバージョンは 3.6 で行なっています。

# 下準備
## LINE WORKS API 認証の準備
LINE WORKS の監査 API を使うにはサーバー認証が必要です。
https://developers.worksmobile.com/jp/document/1002002?lang=ja
固定 IP による認証とサーバー ID (JWT) 方式による認証が選択できるので、今回は取り回しのしやすいサーバー ID 方式を選択しました。

まず、[LINE WORKS Developer Console] にログインし、下記の値を取得します。
- API ID
- Server API Consumer Key
- Server ID と認証キー
- Tenant ID
- Domain ID
取得方法は公式の[マニュアル](https://developers.worksmobile.com/jp/document/1002002?lang=ja)を参照しました。Tenant ID / Domain ID は画面左下に記載があります。
認証キーは任意の名前で保存してください。

### OAuth 認証まわりの下準備
JWT は既存のライブラリ PyJWT を使っています。GCE ではインストール時に注意が必要です。
https://github.com/jpadilla/pyjwt
実際の API 操作は Requests で行っています。

```python:init
pip install cryptgraph
pip install pyjwt
pip install requests
```

## Server ID 方式を使った token 発行
とりあえず認証トークンを取得する関数を用意します。必要な情報を JWT encoding したのちに LINE WORKS の認証用 API に投げて、JSON でトークンとタイムスタンプ等を受け取ります。

```python:token.py

import json
import requests
import jwt
import cryptography
import os
import datetime

#JWT から server token の生成。成功すると dict で token/expire date/token type を返す。失敗すると 0 を返す。
def gettoken(APIId,ServerId,PrivateKey):
        # claimset 生成時間及び 終了時間 (30分設定)
        crnttime = int(datetime.datetime.now().strftime('%s'))
        exptime = crnttime + 1800

        # claimset
        claimset = {
                "iss":ServerId,
                "iat":crnttime,
                "exp":exptime
                }
        #RSA秘密鍵
        key = open(PrivateKey).read()
        #JWT生成
        lw_jwt = jwt.encode(claimset,key,algorithm='RS256')

        # Token 発行
        url = 'https://authapi.worksmobile.com/b/' +APIId +'/server/token'
        header = {
                'Content-Type': 'application/x-www-form-urlencoded',
                'charset': 'utf-8'
                }
        payload = {
                'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                'assertion' : lw_jwt.decode('utf-8')
                }
        r = requests.post(url, headers=header, params=payload)
        if r.status_code == 200:
                return r.json()
        else:
                return 0
```

実際にトークンを取得する場合にはこんな感じです。

```python
from token.py import gettoken
#テナント情報
APIID = '取得したAPI ID'
SERVERID = '登録した Server ID'
PRIVKEY = '認証キーの値'

#トークン発行
tkn = gettoken(APIID,SERVERID,PRIVKEY)
#トークン
TOKEN = tkn['access_token']
#トークンの有効期限
TOKEN_EXPIREDATE = tkn['expires_in']

```
これで認証の準備は整いました。

# LINE WORKS 監査ログの抽出

作成したトークンを使って、監査ログを抽出します。今回はとりあえずテキストで書き出すところまで。

```python:getaudit.py
#テナント情報
TENANTID = 'テナント ID'
DOMAINID = 'ドメイン ID'
SERVER_CKEY = 'Server Consumer Key'

def getauditlog(Servicecode,StartDate,EndDate,ServerTOKEN):
            #リクエスト URL の作成
            #Servicecode はadmin, auth, home, drive, calendar, contact, form, share, note, received-mail, message, sent-mail
        url = 'http://jp1-audit.worksmobile.com/works/audit/log/' + Servicecode + '/logs.csv'

        header = {
                'consumerKey': SERVER_CKEY,
                'Authorization': 'Bearer ' + ServerTOKEN
                }

        parameter = {
                "apiId": 'downCsvLog',
                "serviceId": 'audit',
                "version": 'v1',
                "_startDate": StartDate,
                "_endDate": EndDate,
                "_tenantId": TENANTID,
                "_domainId": DOMAINID,
                "rangeName": 'domain',
                "language": 'ja-JP'
                }
        r = requests.get(url, headers = header, params = parameter)
        return r.text
```
とりあえず出力を一時ファイルの CSV (test.csv) に書き出すとこのようになります。パフォーマンスを考えると、大体1、2日程度で期間を指定するのが良さそうです。

```python

import sys

#ログ取得期間を引数で指定するイメージ。 20180101 20180103 のように指定。

args = sys.argv

#監査ログ取得
with open('test.csv','w') as f:
   f.write(auditlogdl('message',args[1],args[2],TOKEN))
```


# Google スプレッドシートの準備
[こちら](https://qiita.com/Hidekazu-Karino/items/5201fce7249693357602)　の記事を参照して、サービス ID の作成、spreadsheet の用意、アクセス権限設定を行いました。

# Google スプレッドシートへの書き込み
先ほどの一時ファイルから読み出して1行ずつgoogle spread sheet に書き出します。

```python
from oauth2client.service_account import ServiceAccountCredentials
import gspread
import csv

#Spreadsheet 取得
scopes = ['https://www.googleapis.com/auth/spreadsheets']
json_file = 'OAuth用クライアント用 jsonファイル'
credentials = ServiceAccountCredentials.from_json_keyfile_name(json_file, scopes=scopes)

# スプレッドシート用クライアントの準備
doc_id = 'スプレッドシートのID'
client = gspread.authorize(credentials)
gfile   = client.open_by_key(doc_id)#読み書きするgoogle spreadsheet
ws  = gfile.sheet1


#監査ログの書き出し
with open('test.csv','r') as f:
    reader = csv.reader(f)
    #最後の行に追加して書き込みを繰り返す
    for row in reader:
        ws.append_row(row)
```


これで指定した spreadsheet に監査ログの内容が書き込まれます。
あとは監査ログの分析など自由に加工するのがいいかな、と考えています。