import functions_framework import vertexai from vertexai.generative_models import GenerativeModel, ChatSession from google.cloud import storage from google.cloud import secretmanager import json import requests import os from datetime import datetime, timezone, timedelta import gzip # Storage クライアントを作成 storage_client = storage.Client() sm_client = secretmanager.SecretManagerServiceClient() @functions_framework.http def handle_request(request): # POSTリクエストの処理 if request.method != 'POST': return ({'error': 'Method not allowed'}, 405, {'Content-Type': 'application/json'}) try: request_json = request.get_json() print(request_json) project_id = os.getenv("PROJECT_ID") miitel_url = os.getenv("MIITEL_URL") video_info = request_json["video"] access_permission = video_info["access_permission"] video_id = video_info["id"] # 会議履歴ID host_name = video_info["host"]["user_name"] # ホストユーザー名 host_id = video_info["host"]["login_id"] # ホストユーザーID starts_at = video_info["starts_at"] # 開始日時 ends_at = video_info["ends_at"] # 終了日時 video_url = miitel_url + "app/video/" + video_id # 会議履歴URL title = video_info["title"] # 会議タイトル print("会議タイトル",title) # 閲覧制限のない会議のみ生成 if access_permission != "EVERYONE": return (json.dumps({"status": "end"}, ensure_ascii=False), 200, {"Content-Type": "application/json"}) # 社外ミーティングのみ議事録作成 if "様" not in title or "社内" in title: return (json.dumps({"status": "end"}, ensure_ascii=False), 200, {"Content-Type": "application/json"}) # 議事録ファイル名 jst_date_str = generate_jst_date(starts_at) # 開始日時をJSTに変換 file_name = f"{jst_date_str} {title} {host_name}" print(file_name) # 議事録作成 speech_recognition = video_info["speech_recognition"]["raw"] # 文字起こしデータ minutes_text = create_minutes(project_id,speech_recognition) print("議事録作成完了") # テキスト内容をセット minutes = f"会議履歴URL:{video_url}\n" minutes += f"担当者:{host_name}\n\n" minutes += minutes_text response_data = { "status": "next", # ステータス "title": title, # 会議タイトル "host_id": host_id, # ホストユーザーID "host_name": host_name, # ホストユーザー名 "video_url": video_url, # 会議履歴URL "starts_at": starts_at, # 開始日時 "ends_at": ends_at, # 終了日時 "file_name": file_name, # 議事録ファイル名 "minutes": minutes, # 議事録内容 } return (json.dumps(response_data, ensure_ascii=False), 200, {"Content-Type": "application/json"}) except Exception as e: # エラー error_response = { "error": str(e) #エラー内容 } print(str(e)) return json.dumps(error_response), 500, {'Content-Type': 'application/json'} #エラー def generate_jst_date(starts_at): # UTCの文字列をdatetimeオブジェクトに変換 utc_datetime = datetime.fromisoformat(starts_at) # JSTへの変換 jst_timezone = timezone(timedelta(hours=9)) # JSTはUTC+9 jst_datetime = utc_datetime.astimezone(jst_timezone) # yyyy-MM-dd形式にフォーマット jst_date_str = jst_datetime.strftime("%Y年%m月%d日") return jst_date_str def create_minutes(project_id,speech_recognition): location = "us-central1" model_id = os.getenv("MODEL_ID") # print("モデルID:", model_id) vertexai.init(project=project_id, location=location) model = GenerativeModel(model_id) # print("モデル初期化完了") prompt = f""" あなたは議事録作成のプロフェッショナルです。以下の「文字起こし結果」は営業マンが録音した商談の文字起こしです。以下の制約条件に従い、最高の商談報告の議事録を作成してください。 制約条件: 1. 文字起こし結果にはAIによる書き起こしミスがある可能性を考慮してください。 2. 冒頭に主要な「決定事項」と「アクションアイテム」をまとめてください。 3. 議論のポイントを議題ごとに要約してください。 4. 見出しや箇条書きを用いて、情報が探しやすい構造で簡潔かつ明瞭に記述してください。 5. 要約は500文字以内に収めてください。 6. 箇条書き形式で簡潔にまとめてください。 7. マークダウン記法は使わず、各項目を「■」や「・」等を使って見やすくしてください。 文字起こし結果: {speech_recognition} """ # print("-------------プロンプト-------------") # print(prompt[:1000]) # print("-------------議事録作成-------------") response = model.generate_content(prompt) # print(response.text) return response.text