267 lines
No EOL
10 KiB
Python
Executable file
267 lines
No EOL
10 KiB
Python
Executable file
import functions_framework
|
||
from google.cloud import secretmanager
|
||
from google.oauth2 import service_account
|
||
from googleapiclient.discovery import build
|
||
from googleapiclient.errors import HttpError
|
||
import json
|
||
import os
|
||
from datetime import datetime, timezone, timedelta
|
||
|
||
|
||
sm_client = secretmanager.SecretManagerServiceClient()
|
||
|
||
|
||
SCOPES = ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/drive.file"]
|
||
HEADER_VALUES = ["タイムスタンプ","商談日", "タイトル", "登録先企業","担当者", "ミーティングURL", "議事録URL", "HubSpot会社概要URL"]
|
||
|
||
@functions_framework.http
|
||
def handle_request(request):
|
||
# POSTリクエストの処理
|
||
if request.method != 'POST':
|
||
return ('', 405, {'Allow': 'POST', 'Content-Type': 'application/json'}) # メソッドがPOSTでない場合は405エラーを返す
|
||
|
||
"""Shows basic usage of the Drive Activity API.
|
||
|
||
Prints information about the last 10 events that occured the user's Drive.
|
||
"""
|
||
try:
|
||
request_json = request.get_json()
|
||
print(request_json)
|
||
title = request_json['title'] # 会議タイトル
|
||
document_id = request_json['document_id'] # 議事録ファイルのID
|
||
matched_company_id = request_json['matched_company_id'] # マッチした会社ID
|
||
matched_company_name = request_json['matched_company_name'] # マッチした会社名
|
||
host_name = request_json['host_name'] # ホストユーザー名
|
||
video_url = request_json['video_url'] # 会議履歴URL
|
||
starts_at = request_json['starts_at'] # 開始日時
|
||
|
||
log_folder_id = os.getenv("LOG_FOLDER_ID") # 共有ドライブID
|
||
meeting_folder_id = os.getenv("MEETING_FOLDER_ID") # ミーティングフォルダID
|
||
hubspot_company_url = os.getenv("HUBSPOT_COMPANY_URL") # HubSpotの会社情報URL
|
||
mode = os.getenv("MODE") # モード(devまたはprod)
|
||
|
||
service_account_info = get_service_account_info()
|
||
# 認証
|
||
credentials = get_credentials(service_account_info)
|
||
|
||
# APIクライアントの構築
|
||
drive_service = build("drive", "v3", credentials=credentials)
|
||
sheet_service = build("sheets", "v4", credentials=credentials)
|
||
|
||
|
||
# 現在日時をJSTに変換
|
||
jst_now = datetime.now(timezone.utc).astimezone(timezone(timedelta(hours=9)))
|
||
# JSTの現在日時を文字列に変換
|
||
ym_str = jst_now.strftime("%Y%m")
|
||
y_str = jst_now.strftime("%Y")
|
||
|
||
|
||
# 年別のフォルダを検索
|
||
target_folder = get_directory_files_dev(drive_service, log_folder_id, y_str) if mode == "dev" else get_directory_files_prod(drive_service, meeting_folder_id, log_folder_id, y_str)
|
||
print("target_folder", target_folder)
|
||
|
||
year_folder_id = None
|
||
if not target_folder:
|
||
# フォルダが存在しない場合は新規作成
|
||
year_folder_id = create_new_folder(drive_service, log_folder_id, y_str)
|
||
else:
|
||
# フォルダが存在する場合はそのIDを使用
|
||
year_folder_id = target_folder[0]['id']
|
||
print("年別のフォルダID:", year_folder_id)
|
||
|
||
# スプレッドシートを検索
|
||
target_files = get_directory_files_dev(drive_service, year_folder_id, ym_str) if mode == "dev" else get_directory_files_prod(drive_service, meeting_folder_id, year_folder_id, ym_str)
|
||
print("スプレッドシート", target_files)
|
||
|
||
if not target_files:
|
||
print('not found')
|
||
|
||
# スプレッドシートを作成
|
||
spreadsheet_id = create_new_spreadsheet(drive_service, year_folder_id, ym_str)
|
||
print("スプレッドシートID:", spreadsheet_id)
|
||
# 注意事項追加
|
||
append_log_to_sheet(sheet_service, spreadsheet_id, ["※シート名変更厳禁"])
|
||
# ヘッダーを追加
|
||
append_log_to_sheet(sheet_service, spreadsheet_id, HEADER_VALUES)
|
||
|
||
else:
|
||
print('found')
|
||
# ファイルIDを取得
|
||
spreadsheet_id = target_files[0]['id']
|
||
|
||
documnet_url = f"https://docs.google.com/document/d/{document_id}/edit" if document_id else ""
|
||
hubspot_url = f"{hubspot_company_url}/{matched_company_id}" if matched_company_id else ""
|
||
# テストログを追加
|
||
row_data = [jst_now.strftime("%Y-%m-%d %H:%M:%S"),
|
||
convert_to_jst_ymd(starts_at),
|
||
title,
|
||
matched_company_name,
|
||
host_name,
|
||
video_url,
|
||
documnet_url,
|
||
hubspot_url
|
||
]
|
||
append_log_to_sheet(sheet_service, spreadsheet_id, row_data)
|
||
print("ログを追加しました:", row_data)
|
||
|
||
return (json.dumps({"status": "success"}, ensure_ascii=False), 200, {"Content-Type": "application/json"})
|
||
|
||
except HttpError as error:
|
||
# TODO(developer) - Handleerrors from drive activity API.
|
||
print(f"An error occurred: {error}")
|
||
|
||
|
||
#
|
||
# SecretManagerから秘密鍵を取得
|
||
#
|
||
def get_service_account_info():
|
||
key_path = os.getenv('KEY_PATH') + "/versions/1"
|
||
# 秘密鍵取得
|
||
response = sm_client.access_secret_version(name=key_path)
|
||
# 秘密鍵の値をデコード
|
||
secret_key = response.payload.data.decode("UTF-8")
|
||
return json.loads(secret_key)
|
||
|
||
# Google Drive認証
|
||
def get_credentials(service_account_info):
|
||
credentials = service_account.Credentials.from_service_account_info(
|
||
service_account_info,
|
||
scopes=SCOPES
|
||
)
|
||
return credentials
|
||
|
||
|
||
# 開発用マイドライブからのファイルを取得
|
||
def get_directory_files_dev(service,shared_folder_id, filename):
|
||
"""
|
||
対象のディレクトリ配下からファイル名で検索した結果を配列で返す
|
||
:param filename: ファイル名
|
||
:param directory_id: ディレクトリID
|
||
:param pages_max: 最大ページ探索数
|
||
:return: ファイルリスト
|
||
"""
|
||
items = []
|
||
page = 0
|
||
pages_max = 10 # 最大ページ数
|
||
while True:
|
||
page += 1
|
||
if page == pages_max:
|
||
break
|
||
results = service.files().list(
|
||
corpora="user",
|
||
includeItemsFromAllDrives=True,
|
||
includeTeamDriveItems=True,
|
||
q=f"'{shared_folder_id}' in parents and name = '{filename}' and trashed = false",
|
||
supportsAllDrives=True,
|
||
pageSize=10,
|
||
fields="nextPageToken, files(id, name)").execute()
|
||
items += results.get("files", [])
|
||
|
||
page_token = results.get('nextPageToken', None)
|
||
if page_token is None:
|
||
break
|
||
return items
|
||
|
||
# 本番用共有ドライブからのファイルを取得
|
||
def get_directory_files_prod(service,shared_folder_id,sub_folder_id,filename):
|
||
"""
|
||
対象のディレクトリ配下からファイル名で検索した結果を配列で返す
|
||
:param filename: ファイル名
|
||
:param directory_id: ディレクトリID
|
||
:param pages_max: 最大ページ探索数
|
||
:return: ファイルリスト
|
||
"""
|
||
items = []
|
||
page = 0
|
||
pages_max = 10 # 最大ページ数
|
||
while True:
|
||
page += 1
|
||
if page == pages_max:
|
||
break
|
||
results = service.files().list(
|
||
corpora="drive",
|
||
driveId=shared_folder_id,
|
||
includeItemsFromAllDrives=True,
|
||
includeTeamDriveItems=True,
|
||
q=f"'{sub_folder_id}' in parents and name = '{filename}' and trashed = false",
|
||
supportsAllDrives=True,
|
||
pageSize=10,
|
||
fields="nextPageToken, files(id, name, parents)").execute()
|
||
items += results.get("files", [])
|
||
|
||
page_token = results.get('nextPageToken', None)
|
||
if page_token is None:
|
||
break
|
||
return items
|
||
|
||
def create_new_folder(service, sub_folder_id, title):
|
||
"""
|
||
Google Drive APIを使用して新しいフォルダを作成する
|
||
:param service: Google Drive APIのサービスオブジェクト
|
||
:param title: フォルダのタイトル
|
||
:return: 作成したフォルダのID
|
||
"""
|
||
file_metadata = {
|
||
"name": title,
|
||
"parents": [sub_folder_id], # 共有ドライブのIDを指定
|
||
"mimeType": "application/vnd.google-apps.folder",
|
||
}
|
||
|
||
result = service.files().create(body=file_metadata, fields="id", supportsAllDrives=True).execute()
|
||
return result.get('id')
|
||
|
||
|
||
def create_new_spreadsheet(service,folder_id,title):
|
||
"""
|
||
Google Sheets APIを使用して新しいスプレッドシートを作成する
|
||
:param service: Google Sheets APIのサービスオブジェクト
|
||
:param title: スプレッドシートのタイトル
|
||
:return: 作成したスプレッドシートのID
|
||
"""
|
||
file_metadata = {
|
||
'name': title,
|
||
'parents': [folder_id], # 作成したフォルダのIDを指定
|
||
'mimeType': 'application/vnd.google-apps.spreadsheet',
|
||
}
|
||
result = (
|
||
service.files()
|
||
.create(body=file_metadata, fields="id", supportsAllDrives=True)
|
||
.execute()
|
||
)
|
||
return result.get("id")
|
||
|
||
|
||
def append_log_to_sheet(service, spreadsheet_id, row_data):
|
||
"""
|
||
Google Sheets APIを使用してスプレッドシートにログを追加する
|
||
:param service: Google Sheets APIのサービスオブジェクト
|
||
:param spreadsheet_id: スプレッドシートのID
|
||
:param row_data: 追加するログデータ(リスト形式)
|
||
"""
|
||
body = {
|
||
'values': [row_data]
|
||
}
|
||
|
||
# スプレッドシートにログを追加
|
||
result = service.spreadsheets().values().append(
|
||
spreadsheetId=spreadsheet_id,
|
||
range='Sheet1',
|
||
valueInputOption="USER_ENTERED",
|
||
insertDataOption='INSERT_ROWS',
|
||
body=body,
|
||
).execute()
|
||
print(f"{result.get('updates').get('updatedCells')} cells appended.")
|
||
|
||
|
||
|
||
|
||
def convert_to_jst_ymd(starts_at):
|
||
"""
|
||
開始日時をYYYY年MM月DD日形式に変換する
|
||
:param starts_at: 開始日時の文字列
|
||
:return: YYYY年MM月DD日形式の文字列
|
||
"""
|
||
# 開始日時をUTCからJSTに変換
|
||
dt = datetime.fromisoformat(starts_at.replace("Z", "+00:00")).astimezone(timezone(timedelta(hours=9)))
|
||
# YYYY年MM月DD日形式に変換
|
||
return dt.strftime("%Y年%m月%d日") |