2020/06/19

【Python】Google People API でGoogle連絡先を取得する


Google連絡先の取得、追加、削除などを行うにはGoogle Contacts APIGoolge People APIが利用できます。
しかし、Contacts APIは、People APIに置き換わっていくそうなので、これからGoogle連絡先と連携するアプリケーションを作成する際はPeople APIの方を用いると良いかも知れません。
個人的な経験ですが、G SuiteのGoogle連絡先を更新する時Contacts APIでは上手く行きませんでしたが、People APIでは更新できました。ですが、今のところ、People APIではContacts APIの機能を全て互換出来ている訳ではない様です…

PythonからPeople APIを使う

Google People APIをPythonから使うためのサンプルコードとしては、公式ドキュメントに記載してあるPython Quickstartがあります。

本サイトでは、会社のデータベースや年賀状作成ソフトから出力した住所録のcsvをGoogle連絡先に同期させることを目標として、プログラムを作成しようと思います。
本記事では、Python Quickstart内のquickstart.pyを元にGoogle連絡先のデータを取得・表示するコードを作成したものを公開します。

People APIの有効化と必要なライブラリのインストール

まずは、Python Quickstartの内容に従って、サンプルコードquickstart.pyが動く状態にします。
下記のコードでは、ここでダウンロードしたcredentials.jsonをそのまま利用します。
また、People APIは、現時点ではPython 2.6以上に対応していますが、Python 2系統はサポートが終了し、Python 3系への移行が推奨されることから、
本サイト記載のコードは、Python 3系環境で実行することを想定しています。

問題点:people.connections.listのpageSizeの上限

公式ドキュメントによると、記事作成時(2019.06.19)時点では、pageSizeは1~1000の間しか設定出来ない様です。(少し前まで上限は2000だった様な…?)
この上限を超える件数の連絡先を取得したい場合は、nextPageTokenを利用すると良い様です。


作成したコード

必要なファイル:credentials.json

import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/contacts']
CLIENT_SECRET_FILE = 'credentials.json'
class QuickstartMod(object):
def __init__(self):
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
creds = creds
self.service = build('people', 'v1', credentials=creds)
def get_all_contacts(self):
# Keep getting 1000 connections until the nextPageToken becomes None
connections_list = []
next_page_token = ''
while True:
if not (next_page_token is None):
# Call the People API
results = self.service.people().connections().list(
resourceName = 'people/me',
pageSize = 1000,
personFields = 'names,emailAddresses',
pageToken = next_page_token
).execute()
connections_list = connections_list + results.get('connections', [])
next_page_token = results.get('nextPageToken')
else:
break
return connections_list
def print_all_contacts(self):
connections_list = self.get_all_contacts()
if connections_list:
for i, person in enumerate(connections_list):
resource_name = person.get('resourceName', [])
names = person.get('names', [])
if names:
display_name = names[0].get('displayName')
else:
display_name = None
print('no.%s %s %s' % (i+1, display_name, resource_name))
else:
print('No connections found.')
def main():
sync_contacts = QuickstartMod()
sync_contacts.print_all_contacts()
if __name__ == '__main__':
main()
以下のページにAPIの仕様がまとまっているので開発の上で役に立つかと思います。

続き

0 件のコメント:

コメントを投稿