ken_nogi/pleasanter/develop/留守電変換/convertAudioToMessage.js
Kenichiro NOGI 88a402ce0f up
2026-07-10 18:13:30 +09:00

142 lines
5.4 KiB
JavaScript
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.

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);
// GoogleAIGemini 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;
}
}
}
}