CONTENT
ここから
目的
第2章では、ドラフト状況をデータとして整理しました。この章では、そのデータをGemini APIへ送り、次に選ぶべきキャラクターをAIに提案させます。
学ぶこと
- APIキー
- fetch
- JSON
- プロンプト設計
- AIの回答を画面に表示する方法
APIとは
APIとは、アプリ同士が情報をやり取りするための仕組みです。
今回のアプリでは、JavaScriptからGemini APIへデータを送ります。
Gemini APIは、そのデータをもとに分析結果を返します。
流れは以下の通りです。
画面でキャラクターを選ぶ
↓
JavaScriptでデータを整理する
↓
Gemini APIへ送る
↓
おすすめキャラクターが返る
↓
画面に表示する
APIキーを入力する
Gemini APIを使うにはAPIキーが必要です。
HTMLには、APIキーを入力する欄を用意します。
<input
id="geminiApiKeyInput"
type="password"
placeholder="Gemini APIキーを入力"
/>
type="password" にしているため、入力した文字は画面上では隠れます。
ただし、ブラウザ上で直接APIキーを使うため、授業・試作用の作り方です。
公開用アプリでは、サーバーやGASを経由する方が安全です。
Gemini APIへ送る関数
Gemini APIへ通信する中心の関数です。
async function requestGeminiAnalyze(apiKey, payload) {
const endpoint = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${apiKey}`;
const prompt = `
あなたはeスポーツチームのドラフト分析担当です。
以下の5vs5ドラフト状況を分析してください。
ゲーム:
${payload.game}
相手チーム:
${payload.enemyTeam.map((item) => `${item.name} / ${item.role}`).join('\n')}
自分チーム:
${payload.allyTeam.map((item) => `${item.name} / ${item.role}`).join('\n')}
選択可能キャラクター:
${payload.availableCharacters.map((item) => `${item.name} / ${item.role}`).join('\n')}
条件:
- 選択可能キャラクターの中から、次に選ぶべきキャラクターを3体提案してください。
- 相手チームへの対策だけでなく、自分チームに不足している役割も考慮してください。
- 初心者にもわかる言葉で説明してください。
- 必ずJSONだけで返してください。
- Markdownやコードブロックは使わないでください。
返答形式:
{
"recommended": [
{
"name": "キャラクター名",
"reason": "理由"
}
],
"missingRole": "不足している役割",
"summary": "全体の分析まとめ"
}
`;
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
contents: [
{
parts: [
{
text: prompt,
},
],
},
],
}),
});
if (!response.ok) {
throw new Error('Gemini APIの通信に失敗しました。APIキーを確認してください。');
}
const data = await response.json();
const text = data.candidates?.[0]?.content?.parts?.[0]?.text;
if (!text) {
throw new Error('Gemini APIから分析結果を取得できませんでした。');
}
return JSON.parse(text);
}
fetchとは
fetch は、JavaScriptで外部のAPIへ通信するための命令です。
今回の場合は、Gemini APIへPOST通信をしています。
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
contents: [
{
parts: [
{
text: prompt,
},
],
},
],
}),
});
method: 'POST' は、データを送る通信です。
Content-Type: application/json は、JSON形式で送るという意味です。
body には、Geminiへ渡す内容を入れます。
プロンプト設計
Gemini APIへ送っているのは、ただの文字列ではありません。
AIが迷わないように、次の情報を整理して渡しています。
ゲーム名。
相手チーム。
自分チーム。
選択可能キャラクター。
出力してほしい形式。
特に重要なのは、この部分です。
必ずJSONだけで返してください。
Markdownやコードブロックは使わないでください。
これを書いておくと、JavaScriptで結果を扱いやすくなります。
AIの回答を画面に表示する
Gemini APIから返ってきたデータを画面に表示します。
function applyAnalyzeResult(data) {
const recommended = Array.isArray(data.recommended)
? data.recommended
: [];
state.recommendedNames = recommended.map((item) => item.name);
const resultText = [
`不足している役割: ${data.missingRole || '未指定'}`,
'',
'おすすめ候補:',
...recommended.map(
(item, index) =>
`${index + 1}. ${item.name}\n理由: ${item.reason || '理由なし'}`
),
'',
`まとめ:\n${data.summary || '分析結果がありません。'}`,
].join('\n');
document.getElementById('result').textContent = resultText;
renderCharacters();
}
ここでは、AIから返ってきたおすすめキャラクターを文章として表示しています。
さらに、
state.recommendedNames = recommended.map((item) => item.name);
によって、おすすめキャラクター名を保存しています。
この情報を使って、キャラクターカードを強調表示できます。
おすすめカードを光らせる
第1章で作ったカード表示に、次の条件を加えます。
const isRecommended = state.recommendedNames.includes(character.name);
おすすめに含まれているキャラクターなら、recommended クラスを付けます。
<article class="card recommended">
CSSではこうします。
.card.recommended {
border-color: #22c55e;
box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.35);
}
これで、AIがすすめたキャラクターが緑色に光ります。
分析ボタンを作る
ユーザーがボタンを押したら、分析を始めます。
async function analyzeDraft() {
const apiKey = document
.getElementById('geminiApiKeyInput')
.value.trim();
const button = document.getElementById('analyzeButton');
const result = document.getElementById('result');
if (!apiKey) {
result.textContent = 'Gemini APIキーを入力してください。';
return;
}
const enemyCount = state.enemyTeam.filter(Boolean).length;
const allyCount = state.allyTeam.filter(Boolean).length;
if (enemyCount === 0 && allyCount === 0) {
result.textContent =
'相手チームまたは自分チームのキャラクターを1体以上選択してください。';
return;
}
try {
button.disabled = true;
result.textContent = '現在のドラフト状況を分析中です...';
const payload = createAnalyzePayload();
const data = await requestGeminiAnalyze(apiKey, payload);
applyAnalyzeResult(data);
} catch (error) {
result.textContent = error.message;
} finally {
button.disabled = false;
}
}
エラー処理
APIを使うと、必ずエラーが起きる可能性があります。
例えば、
APIキーが間違っている。
通信に失敗する。
AIの返答がJSON形式になっていない。
選択キャラクターが空のまま分析している。
そのため、try...catch を使います。
try {
const data = await requestGeminiAnalyze(apiKey, payload);
applyAnalyzeResult(data);
} catch (error) {
result.textContent = error.message;
}
エラーが起きても画面が壊れず、ユーザーに理由を表示できます。
この章の完成条件
Gemini APIキーを入力できる。
分析ボタンを押すとAPI通信できる。
現在のドラフト状況をGeminiへ送信できる。
おすすめキャラクターが3体表示される。
おすすめ理由が表示される。
おすすめカードが強調表示される。
エラー時にメッセージが表示される。
チャレンジしてみよう
課題1
おすすめキャラクターを3体ではなく、5体表示できるようにしてください。
ヒント。
プロンプト内の
3体提案してください
を変更します。
課題2
分析結果に「攻め向き」「守り向き」を追加してください。
返答形式に次を追加します。
{
"style": "攻め向き"
}
課題3
おすすめキャラクターの理由を短くしてください。
例。
理由は50文字以内で説明してください。
課題4
おすすめカードを緑ではなく、金色にしてください。
.card.recommended {
border-color: #facc15;
}
課題5
AIの分析結果を見たあと、自分なら誰を選ぶかを記録してください。
例。
AIのおすすめ: Omen
自分の選択: Viper
理由: 味方に合わせやすいと思ったから
まとめ
この章では、Gemini APIを使ってドラフト状況を分析しました。
大切なのは、AIにただ質問することではありません。
相手チーム。
自分チーム。
選択可能キャラクター。
出力形式。
この4つを整理して渡すことです。
AIに考えさせるためには、まず人間側が情報をきれいに整える必要があります。