Python + RequestsでGaroon User APIからユーザーを取得してvCardを作る

###はじめに

・社用のスマートフォンに社員の情報を入れたいが、
　社員情報がまとまったCSVはない。
・弊社、garoon上に他社員の電話番号やメールなどの情報が掲載されている。
・User APIで全社員の情報取得してCard作ったれ
　
という、自分向けのとてもニッチな記事です。（変数名は気にしないで）
一般権限ユーザーでも取得できます。

ちなみに先日投稿した

Python + RequestsでGaroon REST APIから組織に所属するユーザーの取得
https://qiita.com/yamashi6/items/3a6fe96a6a2efb8a52e1
でもユーザー情報の取得は可能ですが、
User APIだとお名前の読み方も含まれているので今回はこちらを使用しました。

###参考にしたところ

cybozu developer network　ユーザーエクスポートAPI
https://developer.cybozu.io/hc/ja/articles/202363040

カタカナをひらがなにするコードの詳細を知りたい
https://teratail.com/questions/153806

###ソース
```python
import requests

URL = 'https://(サブドメイン名).cybozu.com/v1/users.json'

# 出力名など指定
OUTPUT_FILE_PATH = "test.vcf"

headers = {
    'Host': '(サブドメイン名).cybozu.com:443', 
     # 'Content-Type': 'application/json',
     # 「ログイン名:パスワード」をBASE64エンコードしたものを値に指定。
     # xxxxxxxxxを書き換えること
    'X-Cybozu-Authorization': 'xxxxxxxxx',
    'Authorization': 'Basic xxxxxxxxx'
}
    
def main():

    user_list = output_user()
    data_list = []

    for user in user_list:

        # Adminユーザーは飛ばす
        if 'test' in user['code']:
            continue

        # 削除済みユーザーは飛ばす
        if user['valid'] == False:
            continue
        
        # 組織のIDを指定すること
        if user['primaryOrganization'] != '1':
            continue

        # 最近登録されたアカウントの判定は、ctimeをみてやればOK
        # ctimeはYYYY-MM-DDThh:mm:ssZ → ISO 8601の拡張形式

        sur_name = user['surName']
        given_name = user['givenName']
        full_name = user['name']

        # ひらがなで登録されているので、カナにしたい場合は変換が必要
        sur_name_r = hira_to_kana(user['surNameReading'])
        given_name_r = hira_to_kana(user['givenNameReading'])

        email = user['email']
        # ハイフンを取り除く
        tel = user['phone'].replace("-","")
        rev = '2019-12-19T12:12:12Z'

        data = f"""BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//iOS 11.2.6//EN
N:{sur_name};{given_name};;;
FN:{full_name}
X-PHONETIC-FIRST-NAME:{given_name_r}
X-PHONETIC-LAST-NAME:{sur_name_r}
EMAIL;type=INTERNET;type=WORK;type=pref:{email}
item1.TEL;type=pref:{tel}
REV:{rev}
END:VCARD
"""

        data_list.append(data)

    with open(OUTPUT_FILE_PATH, "w", encoding="UTF-8") as f:
        for d in data_list:
            f.write(d)

def hira_to_kana(strj):

    # https://teratail.com/questions/153806　を参考に
    return "".join([chr(ord(ch) + 96) if ("ぁ" <= ch <= "ん") else ch for ch in strj])

def output_user():

    offset_cnt = 0
    user_list =[] 

    while True:

        response = get_user(offset_cnt)

        if response == None:
            break

        downloadData = response.json()

        if not('users' in downloadData):
            break

        user_list += downloadData['users']
        
        if len(downloadData['users']) < 100:
            break
        
        offset_cnt += 100
    
    return user_list


def get_user(offset):

    params = {
        'offset': offset,
        'size':'100'
    }

    response = None

    try :
        response = requests.get(URL, headers=headers, params=params)
    except Exception as e:
        print(e)

    return response

if __name__ == "__main__":
    main()
```

###出力結果

特に何もエラーが出なければファイルができているはず

```text
BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//iOS 11.2.6//EN
N:山田;太郎;;;
FN:山田 太郎
X-PHONETIC-FIRST-NAME:タロウ
X-PHONETIC-LAST-NAME:ヤマダ
EMAIL;type=INTERNET;type=WORK;type=pref:yamada_tarou@company.co.jp
item1.TEL;type=pref:00000000000
REV:2019-12-19T12:12:12Z
END:VCARD
BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//iOS 11.2.6//EN
N:山田;花子;;;
FN:山田 花子
X-PHONETIC-FIRST-NAME:ハナコ
X-PHONETIC-LAST-NAME:ヤマダ
EMAIL;type=INTERNET;type=WORK;type=pref:yamada_hanako@company.co.jp
item1.TEL;type=pref:00000000000
REV:2019-12-19T12:12:12Z
END:VCARD
```