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,3 @@
MIITEL_URL=https://datacom.miitel.jp/
PROJECT_ID=datacom-poc
MODEL_ID=gemini-2.5-flash

View file

@ -0,0 +1,3 @@
MIITEL_URL: https://datacom.miitel.jp/
PROJECT_ID: datacom-poc
MODEL_ID: gemini-2.5-flash

View file

@ -0,0 +1,3 @@
MIITEL_URL: https://datacom.miitel.jp/
PROJECT_ID: rational-timing-443808-u0
MODEL_ID: gemini-2.5-flash

View file

@ -0,0 +1,35 @@
#!/bin/bash
# プロジェクトIDを設定
PROJECT_ID="datacom-poc"
# デプロイする関数名
FUNCTION_NAME="mrt-generate-meeting-minutes"
# 関数のエントリポイント
ENTRY_POINT="handle_request"
# ランタイム
RUNTIME="python312"
# リージョン
REGION="asia-northeast1"
# 環境変数ファイル
ENV_VARS_FILE=".env_dev"
gcloud auth application-default set-quota-project $PROJECT_ID
gcloud config set project $PROJECT_ID
# デプロイコマンド
gcloud functions deploy $FUNCTION_NAME \
--gen2 \
--region $REGION \
--runtime $RUNTIME \
--source=./source \
--trigger-http \
--cpu=0.5 \
--memory=1Gi \
--no-allow-unauthenticated \
--entry-point $ENTRY_POINT \
--env-vars-file $ENV_VARS_FILE

View file

@ -0,0 +1,132 @@
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

View file

@ -0,0 +1,5 @@
functions-framework==3.*
google-cloud-storage
google-cloud-aiplatform
google-cloud-secret-manager
pydrive2