Gemini の Canbas 機能を使って、Webページ埋め込み用の、AIアシスタンス(相談窓口)を作ってみましょう。
① プロンプト入力してGeminiに生成を依頼する。
「HTMLでWebページに埋め込むAIコンテンツ生成ツールを作って下さい」
[Canbas]をオンにする
② 生成される
生成されたHTMLコード
HTMLコードをプレビューしてWebページにどのように表示されるかを確認する
生成されたHTMLコードの内容
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AIコンテンツ生成ツール</title>
<!-- Tailwind CSSのCDN -->
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* Interフォントのインポート */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
background-color: #f0f2f5; /* 背景色を少しグレーに */
}
/* カスタムスクロールバーのスタイル */
textarea::-webkit-scrollbar {
width: 8px;
}
textarea::-webkit-scrollbar-track {
background: #e0e0e0;
border-radius: 10px;
}
textarea::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}
textarea::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
</head>
<body class="flex items-center justify-center min-h-screen p-4">
<div class="bg-white p-8 rounded-xl shadow-lg w-full max-w-2xl border border-gray-200">
<h1 class="text-3xl font-bold text-gray-800 mb-6 text-center">AIコンテンツ生成ツール</h1>
<div class="mb-6">
<label for="promptInput" class="block text-gray-700 text-sm font-medium mb-2">
生成したいコンテンツのプロンプトを入力してください:
</label>
<textarea
id="promptInput"
class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition duration-200 ease-in-out resize-y min-h-[100px] max-h-[300px]"
placeholder="例: 「未来の都市生活についての短い物語」"
></textarea>
</div>
<button
id="generateButton"
class="w-full bg-blue-600 text-white py-3 px-4 rounded-lg font-semibold hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition duration-200 ease-in-out shadow-md"
>
コンテンツを生成
</button>
<div id="loadingIndicator" class="hidden text-center mt-6">
<div class="inline-block animate-spin rounded-full h-8 w-8 border-4 border-t-4 border-blue-500 border-gray-200"></div>
<p class="text-gray-600 mt-2">生成中...</p>
</div>
<div id="errorMessage" class="hidden bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg relative mt-6" role="alert">
<strong class="font-bold">エラー:</strong>
<span class="block sm:inline" id="errorText"></span>
</div>
<div class="mt-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">生成されたコンテンツ:</h2>
<div
id="contentOutput"
class="bg-gray-50 p-4 border border-gray-200 rounded-lg min-h-[150px] text-gray-800 whitespace-pre-wrap break-words overflow-auto max-h-[400px]"
>
ここに生成されたコンテンツが表示されます。
</div>
</div>
</div>
<script type="module">
const promptInput = document.getElementById('promptInput');
const generateButton = document.getElementById('generateButton');
const loadingIndicator = document.getElementById('loadingIndicator');
const contentOutput = document.getElementById('contentOutput');
const errorMessage = document.getElementById('errorMessage');
const errorText = document.getElementById('errorText');
generateButton.addEventListener('click', async () => {
const prompt = promptInput.value.trim();
if (!prompt) {
showError('プロンプトを入力してください。');
return;
}
// エラーメッセージを非表示にする
errorMessage.classList.add('hidden');
// 以前のコンテンツをクリア
contentOutput.textContent = '生成中...';
// ローディングインジケーターを表示
loadingIndicator.classList.remove('hidden');
generateButton.disabled = true; // ボタンを無効化
try {
let chatHistory = [];
chatHistory.push({ role: "user", parts: [{ text: prompt }] });
const payload = { contents: chatHistory };
const apiKey = ""; // APIキーはCanvasによって自動的に提供されます
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`;
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`APIエラー: ${response.status} ${response.statusText} - ${errorData.error.message || '不明なエラー'}`);
}
const result = await response.json();
if (result.candidates && result.candidates.length > 0 &&
result.candidates[0].content && result.candidates[0].content.parts &&
result.candidates[0].content.parts.length > 0) {
const text = result.candidates[0].content.parts[0].text;
contentOutput.textContent = text;
} else {
showError('AIからの応答がありませんでした。');
contentOutput.textContent = 'コンテンツを生成できませんでした。';
}
} catch (error) {
console.error('コンテンツ生成中にエラーが発生しました:', error);
showError(`コンテンツ生成に失敗しました: ${error.message}`);
contentOutput.textContent = 'コンテンツを生成できませんでした。';
} finally {
// ローディングインジケーターを非表示にする
loadingIndicator.classList.add('hidden');
generateButton.disabled = false; // ボタンを有効化
}
});
function showError(message) {
errorText.textContent = message;
errorMessage.classList.remove('hidden');
}
</script>
</body>
</html>
③ Geminiに修正を依頼する
HTMLコードを直接手直しすることができる。しかし、コードの知識のない方は難しい。この例では、Geminiにプロンプトで修正を依頼した。
「「タイトル」を「あなたのAIアシスタンス」に修正して、説明もタイトルに合わせた語調にして下さい。」
④ タイトル以外の言葉が直っていないので再度、修正を依頼しました。
「「コンテンツ」は「回答」に変更して 下さい。」
希望通りにデザインを修正することができました
生成されたHTMLコードの内容
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>あなたのAIアシスタンス</title>
<!-- Tailwind CSSのCDN -->
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* Interフォントのインポート */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
background-color: #f0f2f5; /* 背景色を少しグレーに */
}
/* カスタムスクロールバーのスタイル */
textarea::-webkit-scrollbar {
width: 8px;
}
textarea::-webkit-scrollbar-track {
background: #e0e0e0;
border-radius: 10px;
}
textarea::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}
textarea::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
</head>
<body class="flex items-center justify-center min-h-screen p-4">
<div class="bg-white p-8 rounded-xl shadow-lg w-full max-w-2xl border border-gray-200">
<h1 class="text-3xl font-bold text-gray-800 mb-6 text-center">あなたのAIアシスタンス</h1>
<div class="mb-6">
<label for="promptInput" class="block text-gray-700 text-sm font-medium mb-2">
AIに何をお手伝いさせたいですか?プロンプトを入力してください:
</label>
<textarea
id="promptInput"
class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition duration-200 ease-in-out resize-y min-h-[100px] max-h-[300px]"
placeholder="例: 「未来の都市生活についての短い物語」"
></textarea>
</div>
<button
id="generateButton"
class="w-full bg-blue-600 text-white py-3 px-4 rounded-lg font-semibold hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition duration-200 ease-in-out shadow-md"
>
回答を生成
</button>
<div id="loadingIndicator" class="hidden text-center mt-6">
<div class="inline-block animate-spin rounded-full h-8 w-8 border-4 border-t-4 border-blue-500 border-gray-200"></div>
<p class="text-gray-600 mt-2">生成中...</p>
</div>
<div id="errorMessage" class="hidden bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg relative mt-6" role="alert">
<strong class="font-bold">エラー:</strong>
<span class="block sm:inline" id="errorText"></span>
</div>
<div class="mt-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">生成された回答:</h2>
<div
id="contentOutput"
class="bg-gray-50 p-4 border border-gray-200 rounded-lg min-h-[150px] text-gray-800 whitespace-pre-wrap break-words overflow-auto max-h-[400px]"
>
ここに生成された回答が表示されます。
</div>
</div>
</div>
<script type="module">
const promptInput = document.getElementById('promptInput');
const generateButton = document.getElementById('generateButton');
const loadingIndicator = document.getElementById('loadingIndicator');
const contentOutput = document.getElementById('contentOutput');
const errorMessage = document.getElementById('errorMessage');
const errorText = document.getElementById('errorText');
generateButton.addEventListener('click', async () => {
const prompt = promptInput.value.trim();
if (!prompt) {
showError('プロンプトを入力してください。');
return;
}
// エラーメッセージを非表示にする
errorMessage.classList.add('hidden');
// 以前のコンテンツをクリア
contentOutput.textContent = '生成中...';
// ローディングインジケーターを表示
loadingIndicator.classList.remove('hidden');
generateButton.disabled = true; // ボタンを無効化
try {
let chatHistory = [];
chatHistory.push({ role: "user", parts: [{ text: prompt }] });
const payload = { contents: chatHistory };
const apiKey = ""; // APIキーはCanvasによって自動的に提供されます
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`;
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`APIエラー: ${response.status} ${response.statusText} - ${errorData.error.message || '不明なエラー'}`);
}
const result = await response.json();
if (result.candidates && result.candidates.length > 0 &&
result.candidates[0].content && result.candidates[0].content.parts &&
result.candidates[0].content.parts.length > 0) {
const text = result.candidates[0].content.parts[0].text;
contentOutput.textContent = text;
} else {
showError('AIからの応答がありませんでした。');
contentOutput.textContent = '回答を生成できませんでした。';
}
} catch (error) {
console.error('コンテンツ生成中にエラーが発生しました:', error);
showError(`回答生成に失敗しました: ${error.message}`);
contentOutput.textContent = '回答を生成できませんでした。';
} finally {
// ローディングインジケーターを非表示にする
loadingIndicator.classList.add('hidden');
generateButton.disabled = false; // ボタンを有効化
}
});
function showError(message) {
errorText.textContent = message;
errorMessage.classList.remove('hidden');
}
</script>
</body>
</html>
⑤ 修正後のHTMLコードをWebページ埋め込んで実行したところ、APIキーのエラーとなりました。原因は、作成済みのAPIキーが記入されていなかったためです。
「APIキーは自動的に提供され・・・」と書いてありますが、実際には記入しないとAPIエラーになりました。
改めて、HTMLに取得したAPIキーを入力して実行したら正常に動作しました。
⑥ 正しいAPIキーを記入して実行したところ正しく動作しました。
以下は実際に埋め込んだものです。お試しください。