142 lines
5.4 KiB
JavaScript
142 lines
5.4 KiB
JavaScript
const googleApiKey = 'AIzaSyCvzONFjEO-O_SvLZD1KJ0jm5WD_tQaKlw';
|
||
const endpoint = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${googleApiKey}`;
|
||
|
||
// モーダル表示用の関数を追加
|
||
function showModal(message) {
|
||
if ($('#analyze-modal').length === 0) {
|
||
const modalHtml = `
|
||
<div id="analyze-modal" style="position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.5);z-index:9999;display:flex;align-items:center;justify-content:center;">
|
||
<div style="background:#fff;padding:40px 60px;border-radius:8px;font-size:1.5em;text-align:center;box-shadow:0 2px 10px #0003;">
|
||
<span id="analyze-modal-message">${message}</span>
|
||
</div>
|
||
</div>`;
|
||
$('body').append(modalHtml);
|
||
} else {
|
||
$('#analyze-modal-message').text(message);
|
||
$('#analyze-modal').show();
|
||
}
|
||
}
|
||
|
||
function hideModal() {
|
||
$('#analyze-modal').hide();
|
||
}
|
||
|
||
// Pleasanter添付WAVファイルをGoogleAIでメッセージに変換
|
||
async function convertAudioToMessage() {
|
||
try {
|
||
showModal('音声解析中です。しばらくお待ちください...');
|
||
// Pleasanterから添付ファイルを取得
|
||
const attachmentsA = JSON.parse($('#Results_AttachmentsA').val());
|
||
const wavFile = attachmentsA[0]; // 最初の添付ファイルを使用
|
||
|
||
// Base64に変換
|
||
const base64Audio = await $p.ex.getBinalyFileByGuid(wavFile.Guid);
|
||
|
||
// GoogleAI(Gemini API)を呼び出し
|
||
const analysisResult = await $p.ex.ganalyzeAudioWithGoogle(base64Audio);
|
||
|
||
// 結果をPleasanterの本文フィールドに保存
|
||
$p.set($('#Results_DescriptionA'), analysisResult);
|
||
|
||
console.log('分析完了し保存されました');
|
||
hideModal();
|
||
} catch (error) {
|
||
console.error('エラー:', error);
|
||
hideModal();
|
||
return false;
|
||
} finally {
|
||
hideModal();
|
||
$('#UpdateCommand').click(); // 更新ボタンをクリックして保存
|
||
return true;
|
||
}
|
||
}
|
||
|
||
$p.ex.getBinalyFileByGuid = async function (guid) {
|
||
const pleasanterApiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
|
||
|
||
const jsonReq = {
|
||
"ApiVersion": 1.1,
|
||
"ApiKey": pleasanterApiKey
|
||
};
|
||
try {
|
||
const response = await axios.post("https://nextoffice.next-hd.co.jp/pleasanter/api/binaries/" + guid + "/get", jsonReq);
|
||
let base64Audio = response.data.Response.Base64;
|
||
return base64Audio;
|
||
} catch (error) {
|
||
console.log(error);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// GoogleAIで音声を分析
|
||
$p.ex.ganalyzeAudioWithGoogle = async function (base64Audio) {
|
||
//Google GeminiへのAPIリクエスト部
|
||
|
||
const prompt = `
|
||
この音声データは電話の通話録音です。
|
||
この会話を次の分析項目の通り分析して回答してください。
|
||
|
||
【分析項目】
|
||
・本会話のタイトル(50文字以内)
|
||
・会話の内容をすべて残らず文字起こし
|
||
|
||
【制約事項】
|
||
回答は必ず以下のJSON形式のみを出力してください。Markdown記法(code block)は含めないでください。
|
||
発言時刻は記録しないでください。
|
||
|
||
{ "用件": "...", "会話内容": "..." }
|
||
`;
|
||
|
||
let lastError = null;
|
||
for (let attempt = 1; attempt <= 3; attempt++) {
|
||
try {
|
||
const response = await fetch(endpoint, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
contents: [{
|
||
parts: [
|
||
{ text: prompt },
|
||
{
|
||
inline_data: {
|
||
mime_type: 'audio/x-wav',
|
||
data: base64Audio
|
||
}
|
||
}
|
||
]
|
||
}],
|
||
generationConfig: {
|
||
responseMimeType: 'application/json'
|
||
}
|
||
})
|
||
});
|
||
|
||
if (response.status === 429) {
|
||
// 429: Too Many Requests
|
||
if (attempt < 3) {
|
||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||
continue;
|
||
} else {
|
||
showModal('Googleへのリクエストが集中しているため、しばらくしてから再度お試しください。');
|
||
throw new Error('Google API 429エラー: 3回リトライしても失敗');
|
||
}
|
||
}
|
||
|
||
if (!response.ok) {
|
||
lastError = new Error('Google APIエラー: ' + response.status + ' ' + response.statusText);
|
||
throw lastError;
|
||
}
|
||
|
||
const data = await response.json();
|
||
return data.candidates[0].content.parts[0].text;
|
||
} catch (error) {
|
||
lastError = error;
|
||
if (attempt < 3) {
|
||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||
} else {
|
||
showModal('Googleへのリクエストに3回失敗しました。しばらくしてから再度お試しください。');
|
||
throw lastError;
|
||
}
|
||
}
|
||
}
|
||
} |