CONTENT
ここから
Gemini APIなどを使い、ボタン1つで文章を生成する
この教材では、Google Apps ScriptのWebアプリから Gemini API を呼び出して、ボタン1つで文章を生成するアプリを作ります。
前回は、Web画面から入力した企画情報をスプレッドシートに保存しました。
今回は、その入力内容をAIに送り、企画書の文章を自動生成します。
Webアプリに入力する
↓
ボタンを押す
↓
GASがGemini APIに送る
↓
AIが文章を作る
↓
画面に表示する
↓
スプレッドシートにも保存する
Apps ScriptのWebアプリは、doGet()でHTML画面を表示できます。また、HTML画面からApps Script側の関数を呼び出すときは、google.script.run を使います。
このページで完成するもの
今回作るのは、次のようなWebアプリです。
| 機能 | 内容 |
|---|---|
| 入力 | 企画タイトル、ターゲット、雰囲気などを入れる |
| 生成 | Gemini APIで企画書を作る |
| 表示 | 生成結果をWeb画面に表示する |
| 保存 | 生成結果をスプレッドシートに保存する |
今回のゴールはこれです。
入力した内容から、
AIが企画書を作ってくれる状態にする
1. 今回使うもの
| 使うもの | 役割 |
|---|---|
| Googleスプレッドシート | 生成履歴を保存する |
| Google Apps Script | WebアプリとAPI通信を作る |
| index.html | 入力画面を作る |
| Code.gs | Gemini APIを呼び出す |
| Gemini API | AI文章を生成する |
| Google AI Studio | APIキーを取得する |
Gemini APIを使うにはAPIキーが必要です。APIキーはGoogle AI Studioで作成・管理できます。
2. 事前準備
まず、Googleスプレッドシートを作ります。
https://sheets.google.com/
新しいスプレッドシートを作成し、ファイル名を次にします。
AI企画生成Webアプリ
次に、スプレッドシート上部からApps Scriptを開きます。
拡張機能
↓
Apps Script
Apps Scriptのプロジェクト名も、次にしておくと分かりやすいです。
AI企画生成Webアプリ
3. Gemini APIキーを取得する
Google AI StudioのAPIキー画面を開きます。
https://aistudio.google.com/app/apikey
手順は次の通りです。
1. Googleアカウントでログインする
2. APIキー作成画面を開く
3. Create API key を押す
4. APIキーをコピーする
5. 他人に見せない場所に保存する
APIキーは、パスワードのようなものです。
人に送らない
SNSに載せない
GitHubに公開しない
授業中に画面共有で見せない
4. APIキーをApps Scriptに保存する
APIキーは、コードに直接書かないようにします。
Apps Scriptの左側にある歯車アイコンを押します。
プロジェクトの設定
↓
スクリプト プロパティ
↓
スクリプト プロパティを追加
次のように入力します。
| 項目 | 入力内容 |
|---|---|
| プロパティ | GEMINI_API_KEY |
| 値 | 自分のGemini APIキー |
これで、コードから安全にAPIキーを読み出せます。
5. ファイル構成
今回は、次の2ファイルだけで作ります。
Code.gs
index.html
| ファイル | 役割 |
|---|---|
| Code.gs | AI APIを呼び出す処理 |
| index.html | Webアプリの入力画面 |
6. Code.gsを作る
Apps Scriptの Code.gs を開き、最初のコードをすべて消します。
そして、次のコードを貼り付けてください。
const SHEET_NAME = '生成履歴';
const MODEL_NAME = 'gemini-2.5-flash';
function doGet() {
setupSheet_();
return HtmlService
.createHtmlOutputFromFile('index')
.setTitle('AI企画生成アプリ')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function generateProjectText(formData) {
validateFormData_(formData);
setupSheet_();
const prompt = buildPrompt_(formData);
const generatedText = callGemini_(prompt);
saveHistory_(formData, generatedText);
return {
ok: true,
text: generatedText,
message: 'AI文章を生成しました。'
};
}
function buildPrompt_(formData) {
return `
あなたは、学生向けの企画制作を手伝うAIです。
次の入力内容をもとに、初心者にも分かりやすい短い企画書を作ってください。
【企画タイトル】
${formData.title}
【ターゲット】
${formData.target}
【伝えたいこと】
${formData.message}
【雰囲気】
${formData.tone}
【画像イメージ】
${formData.imageIdea || '未入力'}
【動画イメージ】
${formData.videoIdea || '未入力'}
【見た人にしてほしい行動】
${formData.action || '未入力'}
以下の形式で出してください。
1. 企画タイトル
2. ターゲット
3. コンセプト
4. 見せ方の雰囲気
5. Webサイトに載せる内容
6. 画像にするとよい場面
7. 15秒動画にするとよい流れ
8. 最後のボタン文言
9. 発表で使える一言
条件:
・難しい言葉を使わない
・1項目を長くしすぎない
・学生がそのまま発表で使いやすい文章にする
・画像、動画、LP制作に展開しやすい内容にする
`;
}
function callGemini_(prompt) {
const apiKey = PropertiesService
.getScriptProperties()
.getProperty('GEMINI_API_KEY');
if (!apiKey) {
throw new Error('GEMINI_API_KEY が設定されていません。スクリプトプロパティを確認してください。');
}
const url =
'https://generativelanguage.googleapis.com/v1beta/models/' +
MODEL_NAME +
':generateContent?key=' +
encodeURIComponent(apiKey);
const payload = {
contents: [
{
role: 'user',
parts: [
{
text: prompt
}
]
}
],
generationConfig: {
temperature: 0.7,
maxOutputTokens: 1200
}
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const statusCode = response.getResponseCode();
const responseText = response.getContentText();
if (statusCode !== 200) {
throw new Error('Gemini APIエラー:' + responseText);
}
const json = JSON.parse(responseText);
const text = json.candidates?.[0]?.content?.parts?.[0]?.text;
if (!text) {
throw new Error('AIの回答を取得できませんでした。');
}
return text;
}
function saveHistory_(formData, generatedText) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
sheet.appendRow([
new Date(),
formData.title,
formData.target,
formData.message,
formData.tone,
formData.imageIdea || '',
formData.videoIdea || '',
formData.action || '',
generatedText
]);
}
function getRecentHistories() {
setupSheet_();
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
const lastRow = sheet.getLastRow();
if (lastRow <= 1) {
return [];
}
const values = sheet.getRange(2, 1, lastRow - 1, 9).getValues();
return values
.map((row, index) => {
return {
rowNumber: index + 2,
createdAt: formatDate_(row[0]),
title: row[1],
target: row[2],
tone: row[4],
generatedText: row[8]
};
})
.reverse()
.slice(0, 5);
}
function setupSheet_() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName(SHEET_NAME);
if (!sheet) {
sheet = ss.insertSheet(SHEET_NAME);
}
if (sheet.getLastRow() === 0) {
sheet.appendRow([
'生成日時',
'企画タイトル',
'ターゲット',
'伝えたいこと',
'雰囲気',
'画像イメージ',
'動画イメージ',
'行動',
'AI生成結果'
]);
}
}
function validateFormData_(formData) {
if (!formData) {
throw new Error('入力データがありません。');
}
const requiredFields = [
['title', '企画タイトル'],
['target', 'ターゲット'],
['message', '伝えたいこと'],
['tone', '雰囲気']
];
requiredFields.forEach(([key, label]) => {
if (!formData[key] || String(formData[key]).trim() === '') {
throw new Error(label + 'を入力してください。');
}
});
}
function formatDate_(date) {
if (!date) return '';
return Utilities.formatDate(
new Date(date),
Session.getScriptTimeZone(),
'yyyy/MM/dd HH:mm'
);
}
7. index.htmlを作る
Apps Scriptの左側にある「+」を押します。
+
↓
HTML
ファイル名は次にします。
index
index.html が作られたら、中身をすべて消して、次のコードを貼り付けます。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<base target="_top" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AI企画生成アプリ</title>
<style>
:root {
--bg: #f5f7fb;
--card: #ffffff;
--text: #111827;
--muted: #6b7280;
--line: #d9e1ec;
--primary: #2563eb;
--primary-dark: #1d4ed8;
--soft: #eff6ff;
--success: #16a34a;
--danger: #dc2626;
--warning: #f59e0b;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: linear-gradient(180deg, #f8fbff 0%, #edf2f8 100%);
color: var(--text);
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
line-height: 1.7;
}
.page {
width: min(1120px, calc(100% - 32px));
margin: 0 auto;
padding: 32px 0 48px;
}
.hero {
padding: 28px;
margin-bottom: 20px;
border: 1px solid var(--line);
border-radius: 24px;
background: var(--card);
box-shadow: 0 18px 40px rgba(15, 23, 42, 0.08);
}
.badge {
display: inline-flex;
align-items: center;
padding: 6px 12px;
border-radius: 999px;
background: var(--soft);
color: var(--primary);
font-size: 13px;
font-weight: 800;
}
h1 {
margin: 18px 0 8px;
font-size: clamp(28px, 5vw, 44px);
line-height: 1.15;
letter-spacing: -0.04em;
}
.lead {
margin: 0;
color: var(--muted);
}
.grid {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
gap: 20px;
}
.card {
border: 1px solid var(--line);
border-radius: 24px;
background: var(--card);
box-shadow: 0 14px 32px rgba(15, 23, 42, 0.06);
overflow: hidden;
}
.card-header {
padding: 20px 22px;
border-bottom: 1px solid var(--line);
background: #fbfdff;
}
.card-header h2 {
margin: 0;
font-size: 20px;
}
.card-header p {
margin: 4px 0 0;
color: var(--muted);
font-size: 14px;
}
form {
padding: 22px;
}
label {
display: block;
margin-bottom: 14px;
font-weight: 800;
}
.hint {
display: block;
margin-top: 2px;
margin-bottom: 6px;
color: var(--muted);
font-size: 13px;
font-weight: 500;
}
input,
textarea,
select {
width: 100%;
border: 1px solid var(--line);
border-radius: 14px;
padding: 12px 14px;
background: #ffffff;
color: var(--text);
font: inherit;
outline: none;
}
textarea {
min-height: 86px;
resize: vertical;
}
input:focus,
textarea:focus,
select:focus {
border-color: var(--primary);
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}
.row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 20px;
}
button {
border: 0;
border-radius: 14px;
padding: 12px 18px;
cursor: pointer;
font: inherit;
font-weight: 900;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.primary {
background: var(--primary);
color: #ffffff;
}
.primary:hover {
background: var(--primary-dark);
}
.secondary {
background: #eef2f7;
color: #111827;
}
.message {
margin: 0 22px 22px;
padding: 12px 14px;
border-radius: 14px;
display: none;
font-weight: 800;
}
.message.success {
display: block;
background: #ecfdf5;
color: var(--success);
}
.message.error {
display: block;
background: #fef2f2;
color: var(--danger);
}
.result {
padding: 22px;
}
.result-box {
min-height: 420px;
padding: 20px;
border-radius: 18px;
background: #0f172a;
color: #f8fafc;
white-space: pre-wrap;
overflow-wrap: anywhere;
font-size: 15px;
}
.result-empty {
color: #94a3b8;
}
.loading {
display: none;
padding: 14px;
margin: 0 22px 22px;
border-radius: 14px;
background: #fffbeb;
color: #92400e;
font-weight: 800;
}
.loading.show {
display: block;
}
.recent {
padding: 0 22px 22px;
}
.recent-item {
padding: 14px 0;
border-top: 1px solid var(--line);
}
.recent-item:first-child {
border-top: 0;
}
.recent-title {
margin: 0;
font-weight: 900;
}
.recent-meta {
margin: 2px 0 0;
color: var(--muted);
font-size: 13px;
}
.small-button {
margin-top: 8px;
padding: 8px 12px;
border-radius: 10px;
background: #eef2f7;
color: #111827;
font-size: 13px;
}
.empty {
color: var(--muted);
font-size: 14px;
}
@media (max-width: 920px) {
.grid,
.row {
grid-template-columns: 1fr;
}
.hero {
padding: 22px;
}
}
</style>
</head>
<body>
<main class="page">
<section class="hero">
<span class="badge">6-3 GAS × Gemini API</span>
<h1>ボタン1つで<br />AI文章を生成する</h1>
<p class="lead">
入力した企画情報をGemini APIに送り、企画書の文章を自動生成します。
</p>
</section>
<section class="grid">
<div class="card">
<div class="card-header">
<h2>企画情報を入力</h2>
<p>入力して「AIで文章を生成」を押してください。</p>
</div>
<form id="generateForm">
<label>
企画タイトル
<span class="hint">例:放課後カフェマップ</span>
<input
id="title"
type="text"
placeholder="企画タイトルを入力"
required
/>
</label>
<label>
ターゲット
<span class="hint">例:学校帰りに寄れる場所を探している学生</span>
<input
id="target"
type="text"
placeholder="誰に届けたいか"
required
/>
</label>
<label>
伝えたいこと
<span class="hint">例:放課後の居場所を分かりやすく紹介する</span>
<textarea
id="message"
placeholder="何を伝えたいか"
required
></textarea>
</label>
<div class="row">
<label>
雰囲気
<span class="hint">迷ったら「明るい」がおすすめ</span>
<select id="tone" required>
<option value="">選択してください</option>
<option value="明るい・親しみやすい">明るい・親しみやすい</option>
<option value="おしゃれ・落ち着いた">おしゃれ・落ち着いた</option>
<option value="かわいい・やさしい">かわいい・やさしい</option>
<option value="かっこいい・シャープ">かっこいい・シャープ</option>
<option value="シンプル・分かりやすい">シンプル・分かりやすい</option>
</select>
</label>
<label>
見た人にしてほしい行動
<span class="hint">例:サイトを見る、参加する</span>
<input
id="action"
type="text"
placeholder="最後にしてほしい行動"
/>
</label>
</div>
<label>
画像イメージ
<span class="hint">例:夕方のカフェ、ノート、ドリンク</span>
<textarea
id="imageIdea"
placeholder="画像にしたい場面"
></textarea>
</label>
<label>
動画イメージ
<span class="hint">例:学校帰りにカフェへ向かう</span>
<textarea
id="videoIdea"
placeholder="動画にしたい場面"
></textarea>
</label>
<div class="actions">
<button class="primary" type="submit" id="generateButton">
AIで文章を生成
</button>
<button class="secondary" type="button" id="sampleButton">
サンプル入力
</button>
<button class="secondary" type="button" id="clearButton">
クリア
</button>
</div>
</form>
<div id="loadingBox" class="loading">
AIが文章を作っています。少し待ってください。
</div>
<p id="messageBox" class="message"></p>
</div>
<div class="card">
<div class="card-header">
<h2>AI生成結果</h2>
<p>生成された文章は、スプレッドシートにも保存されます。</p>
</div>
<div class="result">
<div id="resultBox" class="result-box">
<span class="result-empty">ここにAIの回答が表示されます。</span>
</div>
<div class="actions">
<button class="secondary" type="button" id="copyButton">
結果をコピー
</button>
</div>
</div>
<div class="card-header">
<h2>最近の生成履歴</h2>
<p>最新5件を表示します。</p>
</div>
<div class="recent" id="recentHistories">
<p class="empty">まだ生成履歴がありません。</p>
</div>
</div>
</section>
</main>
<script>
const form = document.getElementById('generateForm');
const generateButton = document.getElementById('generateButton');
const sampleButton = document.getElementById('sampleButton');
const clearButton = document.getElementById('clearButton');
const copyButton = document.getElementById('copyButton');
const loadingBox = document.getElementById('loadingBox');
const messageBox = document.getElementById('messageBox');
const resultBox = document.getElementById('resultBox');
const fields = {
title: document.getElementById('title'),
target: document.getElementById('target'),
message: document.getElementById('message'),
tone: document.getElementById('tone'),
imageIdea: document.getElementById('imageIdea'),
videoIdea: document.getElementById('videoIdea'),
action: document.getElementById('action')
};
form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = getFormData();
setLoading(true);
showMessage('', '');
google.script.run
.withSuccessHandler((result) => {
setLoading(false);
resultBox.textContent = result.text;
showMessage(result.message || '生成しました。', 'success');
loadRecentHistories();
})
.withFailureHandler((error) => {
setLoading(false);
showMessage(error.message || 'AI生成に失敗しました。', 'error');
})
.generateProjectText(formData);
});
sampleButton.addEventListener('click', () => {
fields.title.value = '放課後カフェマップ';
fields.target.value = '学校帰りに友達と寄れる場所を探している学生';
fields.message.value =
'勉強にも休憩にも使える、放課後の居場所を分かりやすく紹介する。';
fields.tone.value = '明るい・親しみやすい';
fields.imageIdea.value =
'夕方のカフェ、ノート、スマホ、ドリンク、手元のアップ。';
fields.videoIdea.value =
'学校帰りにカフェへ向かい、席に座ってスマホで場所を探す。';
fields.action.value = 'サイトを見て、行ってみたいカフェを探す';
showMessage('サンプルを入力しました。必要に応じて書き換えてください。', 'success');
});
clearButton.addEventListener('click', () => {
form.reset();
resultBox.innerHTML =
'<span class="result-empty">ここにAIの回答が表示されます。</span>';
showMessage('', '');
});
copyButton.addEventListener('click', async () => {
const text = resultBox.textContent.trim();
if (!text || text === 'ここにAIの回答が表示されます。') {
showMessage('コピーする結果がありません。', 'error');
return;
}
try {
await navigator.clipboard.writeText(text);
showMessage('生成結果をコピーしました。', 'success');
} catch (error) {
showMessage('コピーに失敗しました。手動で選択してコピーしてください。', 'error');
}
});
function getFormData() {
return {
title: fields.title.value.trim(),
target: fields.target.value.trim(),
message: fields.message.value.trim(),
tone: fields.tone.value.trim(),
imageIdea: fields.imageIdea.value.trim(),
videoIdea: fields.videoIdea.value.trim(),
action: fields.action.value.trim()
};
}
function setLoading(isLoading) {
generateButton.disabled = isLoading;
generateButton.textContent = isLoading
? '生成中...'
: 'AIで文章を生成';
loadingBox.classList.toggle('show', isLoading);
}
function showMessage(text, type) {
if (!text) {
messageBox.textContent = '';
messageBox.className = 'message';
return;
}
messageBox.textContent = text;
messageBox.className = 'message ' + type;
}
function loadRecentHistories() {
google.script.run
.withSuccessHandler(renderRecentHistories)
.withFailureHandler(() => {
document.getElementById('recentHistories').innerHTML =
'<p class="empty">生成履歴を読み込めませんでした。</p>';
})
.getRecentHistories();
}
function renderRecentHistories(histories) {
const container = document.getElementById('recentHistories');
if (!histories || histories.length === 0) {
container.innerHTML =
'<p class="empty">まだ生成履歴がありません。</p>';
return;
}
container.innerHTML = histories
.map((item) => {
return `
<div class="recent-item">
<p class="recent-title">${escapeHtml(item.title)}</p>
<p class="recent-meta">
${escapeHtml(item.createdAt)}|${escapeHtml(item.tone || '')}
</p>
<button class="small-button" type="button" onclick="showHistoryResult('${encodeURIComponent(item.generatedText || '')}')">
結果を見る
</button>
</div>
`;
})
.join('');
}
function showHistoryResult(encodedText) {
const text = decodeURIComponent(encodedText);
resultBox.textContent = text;
}
function escapeHtml(value) {
return String(value)
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"')
.replaceAll("'", ''');
}
loadRecentHistories();
</script>
</body>
</html>
8. 保存する
Code.gs と index.html を貼り付けたら、保存します。
Command + S
Windowsの場合は、
Ctrl + S
です。
9. 初回実行をする
Apps Script上部の関数選択で、次を選びます。
doGet
実行ボタンを押します。
初回は権限確認が出る場合があります。
権限を確認
↓
自分のGoogleアカウントを選ぶ
↓
詳細
↓
安全ではないページに移動
↓
許可
自分で作ったスクリプトなので、この教材では許可して進めます。
10. Webアプリとしてデプロイする
右上の「デプロイ」を押します。
デプロイ
↓
新しいデプロイ
種類の選択で、歯車アイコンを押します。
種類を選択
↓
ウェブアプリ
設定は次のようにします。
| 項目 | 設定 |
|---|---|
| 説明 | 6-3 AI企画生成アプリ |
| 次のユーザーとして実行 | 自分 |
| アクセスできるユーザー | 自分のみ |
まずは「自分のみ」で十分です。
11. WebアプリURLを開く
デプロイが完了すると、URLが表示されます。
ウェブアプリURL
そのURLを開くと、入力画面が表示されます。
12. 動かしてみる
まずは「サンプル入力」を押します。
内容が入ったら、次を押します。
AIで文章を生成
少し待つと、右側にAIの文章が表示されます。
スプレッドシートには、自動で 生成履歴 シートが作られ、生成結果が保存されます。
13. 成功イメージ
生成結果に、次のような文章が表示されれば成功です。
1. 企画タイトル
放課後カフェマップ
2. ターゲット
学校帰りに友達と寄れる場所を探している学生
3. コンセプト
放課後に安心して寄れるカフェを、分かりやすく紹介する企画
4. 見せ方の雰囲気
明るく、親しみやすく、少しおしゃれな雰囲気
5. Webサイトに載せる内容
おすすめカフェ、勉強しやすさ、友達と行きやすい雰囲気
...
ここまでできれば、6-3は成功です。
14. この教材で理解すること
今回理解してほしいのは、次の流れです。
index.html
入力画面
↓ google.script.run
Code.gs
Gemini APIを呼び出す
↓ UrlFetchApp
Gemini API
文章を生成する
↓ 結果を返す
index.html
画面に表示する
↓ 保存
スプレッドシート
生成履歴として残す
つまり、AIアプリはこう考えます。
画面
+
処理
+
AI API
+
保存場所
15. よくあるエラー
エラー1:GEMINI_API_KEY が設定されていません
スクリプトプロパティを確認してください。
Apps Script
↓
プロジェクトの設定
↓
スクリプト プロパティ
↓
GEMINI_API_KEY
名前が少しでも違うと動きません。
正しい名前:
GEMINI_API_KEY
エラー2:Gemini APIエラーが出る
APIキーが間違っている、APIの利用制限に当たっている、またはモデル名が利用できない可能性があります。
まず確認することは3つです。
APIキーが正しいか
スクリプトプロパティに貼れているか
短時間に何度も押しすぎていないか
Gemini APIのモデルや料金、利用制限は変更される可能性があるため、授業前に公式ページを確認するのが安全です。
エラー3:画面は出るが、ボタンを押しても動かない
WebアプリURLから開いているか確認してください。
index.html を直接ブラウザで開いても、google.script.run は動きません。
Apps ScriptでデプロイしたWebアプリURLから開く
エラー4:生成に時間がかかる
AI APIは、回答に少し時間がかかることがあります。
ボタンを何度も連打しない
1回押したら待つ
この教材では、生成中はボタンが「生成中…」に変わるようにしています。
16. 無料で使うときの注意
無料枠で使う場合は、連続で何度も生成しすぎないようにします。
授業では、次のルールがおすすめです。
サンプル生成は1回
自分のテーマで1回
直したい場合は追加で1回
合計2〜3回くらいにすると、授業でも進めやすいです。
17. カスタマイズしてみる
出力内容を変えたいときは、Code.gs の buildPrompt_ を変更します。
例えば、もっと短くしたい場合は、次の条件を追加します。
・各項目は2行以内にする
SNS向けにしたい場合は、次の条件を追加します。
・Instagram投稿に使いやすい言葉も入れる
LP向けにしたい場合は、次の条件を追加します。
・1ページLPの見出し案も作る
大事なのは、コード全体を触るのではなく、まずはプロンプトだけ変えることです。
18. 今日の提出物
この回の提出物は、次の3つです。
1. WebアプリURL
2. AI生成結果のスクリーンショット
3. スプレッドシートの生成履歴スクリーンショット
最低限、次ができればOKです。
ボタンを押して、
AIの文章が画面に表示された
19. チェックリスト
| チェック | 内容 |
|---|---|
| スプレッドシートを作成した | |
| Apps Scriptを開いた | |
| Gemini APIキーを取得した | |
| スクリプトプロパティにGEMINI_API_KEYを保存した | |
| Code.gsを貼り付けた | |
| index.htmlを作成した | |
| index.htmlを貼り付けた | |
| 保存した | |
| Webアプリとしてデプロイした | |
| WebアプリURLを開いた | |
| サンプル入力を押した | |
| AIで文章を生成を押した | |
| 生成結果が画面に表示された | |
| スプレッドシートに生成履歴が保存された |
まとめ
今回は、GASのWebアプリからGemini APIを呼び出して、ボタン1つで文章を生成する仕組みを作りました。
今日作った流れは、AIアプリ開発の基本です。
入力する
↓
AIに送る
↓
結果を表示する
↓
保存する
この仕組みが分かると、次はもっと実用的なアプリにできます。
企画書を自動生成する
画像プロンプトを作る
動画台本を作る
LP構成を作る
提出用ドキュメントを作る
次の回では、この仕組みを使って、企画書メーカーを作ります。