sales_tool/functions/generate-meeting-minutes/source/main.py
2025-11-17 14:21:29 +09:00

132 lines
5.2 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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