This commit is contained in:
kosukesuenaga 2025-11-17 14:21:29 +09:00
commit 922fa0e77a
62 changed files with 2586 additions and 0 deletions

View file

@ -0,0 +1,90 @@
import functions_framework
from google.cloud import storage, secretmanager
import os
import hubspot
from hubspot.crm.objects.meetings import ApiException
import csv
import io
import json
cs_client = storage.Client()
sm_client = secretmanager.SecretManagerServiceClient()
@functions_framework.http
def handle_request(request):
try:
# 会社一覧取得
owners = fetch_all_owners()
# メモリ上で CSV を生成
csv_buffer = io.StringIO()
writer = csv.writer(csv_buffer)
# ヘッダー行
writer.writerow(["id", "email"])
# 各行を書き込み
for row in owners:
user_id = row['id']
email = row['email']
writer.writerow([user_id, email])
# Cloud Storage にアップロード
upload_to_gcs(csv_buffer)
return (json.dumps('', ensure_ascii=False), 200, {"Content-Type": "application/json"})
except ApiException as e:
print("Exception when calling basic_api->create: %s\n" % e)
return (json.dumps("", ensure_ascii=False), 200, {"Content-Type": "application/json"})
def fetch_all_owners():
"""
Companies API get_page をページネーション付きで呼び出し
全オブジェクトをリストで返す
"""
access_key = get_access_key() # Secret Manager からアクセストークンを取得
hs_client = hubspot.Client.create(access_token=access_key)
all_owners = []
after = None
limit = 100 # 1 回あたりの取得件数(最大 100
while True:
# get_page の基本呼び出し
response = hs_client.crm.owners.owners_api.get_page(
limit=limit,
archived=False,
after=after
)
# レスポンスから companies の配列を追加
if response.results:
all_owners.extend([c.to_dict() for c in response.results])
# 次ページがない場合はループ終了
paging = response.paging
if not paging or not paging.next or not paging.next.after:
break
# next.after をセットして次ループへ
after = paging.next.after
return all_owners
def upload_to_gcs(data):
"""
メモリ上の CSV データを Cloud Storage にアップロード
"""
bucket = cs_client.bucket(os.getenv("BUCKET"))
blob = bucket.blob(os.getenv("OBJECT"))
blob.upload_from_string(data.getvalue(), content_type='text/csv')
#
# SecretManagerからアクセストークンを取得
#
def get_access_key():
key_path = os.getenv('KEY_PATH') + "/versions/1"
# アクセストークン取得
response = sm_client.access_secret_version(name=key_path)
# アクセストークンをデコード
access_token = response.payload.data.decode("UTF-8")
return access_token