2024年、さくらインターネットが提供する生成AIサービス「高火力」、通称「さくらAI」が注目を集めています。
実は、Google Workspace(旧 G Suite)に標準搭載されている Google Apps Script (GAS) を使えば、プログラミング経験がなくても、さくらAIに接続する自分専用のWebアプリケーションを驚くほど簡単に自作できます。
この記事では、GASを使って「さくらAI」のオリジナルAIアプリを作成する価値から、具体的な設定方法、そして「社内データと連携させる」RAG化の可能性までを、ステップバイステップでご紹介します。
さくらAIとGoogleWorkspace
完成したWEB画面はこんな感じです。さくらAIの「gpt-oss-120b」を使って自分専用のWEBアプリとして動作しています。「gpt-oss-120b」はOpenAIが出しているオープンソースのChatGPTの最高峰の賢さがあり、現行のChatGPT4程度以上の能力があると言われています。これが無料で使えるのはすごいですね。
これまで、さくらAIについて以下の解説ページで紹介しています。


今回はあらたにGoogleWorkspace内で、さくらAIとAPI接続するというチャレンジをしてみました。
この制作については、ほぼGeminiとのやりとりでできています。その意味でもGoogleWorkspace内で開発から運用までできてしまったということです。我ながらすごい(エンジニアではないのに、という意味です)
なぜGASで「さくらAI」を使うのか? その圧倒的価値
「わざわざGASを使わなくても…」と思うかもしれませんが、GASで自作することには、既存のツールにはない大きなメリットがあります。
- Google Workspaceと完全連携できるこれが最大の価値です。GASは、スプレッドシート、Gmail、Googleドキュメント、Googleドライブといった全てのGoogleサービスを操作できます。
- スプレッドシートのデータを読み込ませて、さくらAIに分析・要約させる。
- Gmailの画面から、さくらAIにメールの返信文を作成させる。
- Googleドライブ内のテキストファイルを読み込ませて、自動で議事録を作成する。GASをハブ(中継地点)にすることで、「さくらAI」があなたの業務フローにシームレスに溶け込みます。
- 低コストで「専用アプリ」が持てるさくらAIのAPI利用料(無料枠もあり)と、Google Workspaceの契約(Standardプランなどで十分)だけで動作します。通常、Webアプリを動かすために必要なサーバーの契約やインフラ管理は一切不要です。
- UI(操作画面)を自由に作れるLobeChatは素晴らしいツールですが、機能が多すぎて迷うことも。GASならHTMLとCSSを使って、業務に必要なボタンだけを配置した「自分(自社)専用の操作画面」を作れます。今回作成したシンプルなチャット画面もその一例です。
- 安心の国内完結(心理的安全性)API通信は、Googleのインフラと、さくらインターネットの国内サーバーとの間で完結します。機密性の高い情報を扱う際も、海外のサービスを経由しないという点で、心理的な安心感が得られます。
3ステップで完成!さくらAI専用チャットアプリの設定方法
必要なのは、LobeChatなどで既に使っている「さくらAIの接続情報」だけです。
ステップ1:さくらAIの接続情報を準備
以下の2つをメモ帳などにコピーしておきます。
- トークンID:
24xxxxfa-xxxx-....
のような形式の文字列 - 接続先URL:
https://api.ai.sakura.ad.jp/v1/chat/completions
ステップ2:サーバーサイド(コード.gs)の作成
Googleドライブで「新規」>「その他」>「Google Apps Script」を選び、新しいプロジェクトを開きます。
コード.gs
というファイルに、以下のコードを貼り付けます。これは「GASからさくらAIのAPIを呼び出す」ための心臓部です。
GAS(JavaScript)の「コード.js」内容は以下のとおりです
/*** Webアプリとしてアクセスされたときにindex.htmlを表示する関数*/function doGet() {return HtmlService.createHtmlOutputFromFile(‘index’).setTitle(“さくらのAI カスタムチャット”);}/*** さくらのAI APIに会話履歴を送信し、応答を返す関数* @param {Array<Object>} messages ユーザーとアシスタントの会話履歴の配列* @returns {string} さくらのAIからの応答メッセージ、またはエラーメッセージ*/function callSakuraAI(messages) {// — 設定項目 —const SAKURA_API_URL = “https://api.ai.sakura.ad.jp/v1/chat/completions”;const API_TOKEN = “YOUR_SAKURA_API_TOKEN“; // 自身のsakuraAIトークンIDに書き換えてくださいconst MODEL_NAME = “gpt-oss-120b”; // 利用したいモデルを指定// —————const headers = {“Authorization”: “Bearer ” + API_TOKEN,“Content-Type”: “application/json”};// ペイロードに会話履歴の配列をそのまま設定const payload = {“model”: MODEL_NAME,“messages”: messages};const options = {“method”: “post”,“headers”: headers,“payload”: JSON.stringify(payload),“muteHttpExceptions”: true};try {const response = UrlFetchApp.fetch(SAKURA_API_URL, options);const responseCode = response.getResponseCode();const responseBody = response.getContentText();if (responseCode >= 200 && responseCode < 300) {const responseData = JSON.parse(responseBody);if (responseData.choices && responseData.choices[0] && responseData.choices[0].message && responseData.choices[0].message.content) {return responseData.choices[0].message.content;} else {console.error(“APIからの予期せぬレスポンス形式:”, responseBody);return “エラー:APIから予期せぬ形式の応答がありました。”;}} else {console.error(“APIエラー:”, `ステータスコード: ${responseCode}, レスポンス: ${responseBody}`);return `エラー:APIサーバーからエラーが返されました(コード: ${responseCode})。`;}} catch (e) {console.error(“リクエストエラー:”, e);return “エラー:APIへの接続中に問題が発生しました。”;}}
【重要】 YOUR_SAKURA_API_TOKEN の部分を、ステップ1でメモしたご自身の「トークンID」に必ず書き換えてください。
ステップ3:フロントエンド(index.html)の作成
次に、ユーザーが操作する画面を作ります。スクリプトエディタの「ファイル」>「新規作成」>「HTMLファイル」を選択し、ファイル名を index
にします。
HTMLの内容は以下のとおりです
<!DOCTYPE html><html lang=”ja”><head><meta charset=”utf-8″><!– スマホファースト:全面レスポンシブ対応 –><meta name=”viewport” content=”width=device-width, initial-scale=1.0, viewport-fit=cover”><base target=”_top”><script src=”https://cdn.jsdelivr.net/npm/marked/marked.min.js”></script><style>:root {/* 最低20ptを保証しつつ、viewport幅に応じて可変 */–base-font-size: clamp(20pt, 4.2vw, 24pt);–background-color: #f0f2f5;–border-color: #e0e0e0;–user-bubble-color: #007bff;–ai-bubble-color: #fff;–radius: 22px;–gap: 14px;}html {-webkit-text-size-adjust: 100%;}body {margin: 0;padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, “Helvetica Neue”, Arial, sans-serif;background: var(–background-color);font-size: var(–base-font-size);line-height: 1.7;color: #1d1d1f;display: flex;justify-content: center;}/* レスポンシブ:左右固定なし */#app-container {width: 100%;background: #fff;display: flex;flex-direction: column;min-height: 100vh;margin: 0;}h1 {text-align: center;margin: 0;padding: 16px 10px;font-size: 1.25em;border-bottom: 1px solid var(–border-color);background: #fff;}#chat-container {flex: 1;overflow-y: auto;padding: 16px;-webkit-overflow-scrolling: touch;scroll-behavior: smooth;}.message {max-width: 95%;margin-bottom: var(–gap);padding: 12px 16px;border-radius: var(–radius);word-wrap: break-word;overflow-wrap: anywhere;line-height: 1.65;font-size: 1rem;}.user-message {background: var(–user-bubble-color);color: #fff;margin-left: auto;border-bottom-right-radius: 6px;}.ai-message {background: var(–ai-bubble-color);color: #212529;margin-right: auto;border: 1px solid #e5e5e5;border-bottom-left-radius: 6px;}/* Markdown整形 */.ai-message h1 { font-size: 1.4em; margin: 1em 0 .5em; padding-bottom: .3em; border-bottom: 1px solid #ddd; }.ai-message h2 { font-size: 1.25em; margin: 1em 0 .5em; padding-bottom: .25em; border-bottom: 1px solid #eee; }.ai-message p:last-child { margin-bottom: 0; }.ai-message img, .ai-message table { max-width: 100%; height: auto; display: block; margin: .5em 0; }.ai-message table { overflow-x: auto; border-collapse: collapse; }.ai-message th, .ai-message td { padding: 10px 14px; border: 1px solid #ccc; white-space: nowrap; }.ai-message th { background: #f7f7f7; }/* 入力エリア */#input-area {display: flex;align-items: center;gap: 10px;padding: 10px 12px;padding-bottom: calc(env(safe-area-inset-bottom, 0) + 10px);border-top: 1px solid var(–border-color);background: #f8f9fa;position: sticky;bottom: 0;}#prompt {flex: 1;min-height: 48px;max-height: 40vh;padding: 12px 14px;border: 1px solid #ccc;border-radius: 24px;font-size: 1rem;line-height: 1.6;resize: none;overflow-y: auto;background: #fff;}#send-button {padding: 0 36px;min-height: 96px;border: none;background: var(–user-bubble-color);color: #fff;border-radius: 24px;font-size: 2rem;font-weight: 700;cursor: pointer;touch-action: manipulation;}#send-button:disabled { background: #aaa; cursor: not-allowed; }.blinking-cursor { animation: blink 1s step-end infinite; }@keyframes blink { 50% { opacity: 0; } }</style></head><body><div id=”app-container”><h1>さくらのAI(gpt-oss-120b)</h1><div id=”chat-container”></div><div id=”input-area”><textarea id=”prompt” rows=”1″ placeholder=”メッセージを入力…”></textarea><button id=”send-button” onclick=”sendMessage()”>送信</button></div></div><script>const chatContainer = document.getElementById(‘chat-container’);const promptInput = document.getElementById(‘prompt’);const sendButton = document.getElementById(‘send-button’);let conversationHistory = [];function autosizeTextarea(el) {el.style.height = ‘0’;el.style.height = Math.min(el.scrollHeight, window.innerHeight * 0.4) + ‘px’;}promptInput.addEventListener(‘input’, () => autosizeTextarea(promptInput));autosizeTextarea(promptInput);promptInput.addEventListener(‘keydown’, event => {if (event.key === ‘Enter’ && !event.shiftKey) {event.preventDefault(); sendMessage();}});function sendMessage() {const prompt = promptInput.value.trim(); if (!prompt || sendButton.disabled) return;addMessageToHistory(‘user’, prompt);displayMessage(‘user’, prompt);promptInput.value = ”;autosizeTextarea(promptInput);sendButton.disabled = true;const aiDiv = document.createElement(‘div’); aiDiv.className = ‘message ai-message’; aiDiv.innerHTML = ‘<span class=”blinking-cursor”>▋</span>’;chatContainer.appendChild(aiDiv); scrollToBottom();google.script.run.withSuccessHandler(res => onAiResponse(res, aiDiv)).withFailureHandler(err => onAiError(err, aiDiv)).callSakuraAI(conversationHistory);}function onAiResponse(text, div) { addMessageToHistory(‘assistant’, text); typewriter(div, text); }function onAiError(err, div) { div.textContent = ‘エラー: ‘ + err.message; sendButton.disabled = false; }function addMessageToHistory(r, c) { conversationHistory.push({ role: r, content: c }); }function displayMessage(s, t) { const d = document.createElement(‘div’); d.className = ‘message ‘ + s + ‘-message’; d.innerText = t; chatContainer.appendChild(d); scrollToBottom(); }function typewriter(el, txt) { el.innerHTML = ”; let i=0; const interval = setInterval(() => { if(i<txt.length) { el.innerHTML+=txt[i++]; scrollToBottom(); } else { clearInterval(interval); el.innerHTML = marked.parse(txt); sendButton.disabled=false; promptInput.focus(); } }, 20); }function scrollToBottom() { chatContainer.scrollTop = chatContainer.scrollHeight; }window.addEventListener(‘resize’, () => autosizeTextarea(promptInput));document.addEventListener(‘visibilitychange’, () => { if (!document.hidden) autosizeTextarea(promptInput); });</script></body></html>
なお、htmlについてはGeminiを使ってどんどん自分向けに修正して使いやすいように変更していけばよいです。
ステップ4:「ウェブアプリ」としてデプロイ
コードを保存したら、エディタ右上の「デプロイ」>「新しいデプロイ」をクリックします。
- 「種類の選択」で「ウェブアプリ」を選択します。
- 「アクセスできるユーザー」を「自分のみ」(または共有したい範囲)に設定します。
- 「デプロイ」ボタンを押します。
これで、表示された「ウェブアプリURL」にアクセスするだけで、あなたが作った専用チャットアプリが利用できます。このURLは、ブラウザにブックマークしたり、メモしたりしてすぐに呼び出せるようにしておきましょう。
さらなる拡張性:GASで作る「社内データRAG」の可能性
このアプリが完成したことは、ゴールではなくスタートです。GASの真価は、ここからの拡張性にあります。
現在、LobeChatなどでは「RAG(Retrieval-Augmented Generation)」という、AIに外部の知識(PDFやテキスト)を読み込ませて回答させる機能が注目されています。
これをGASで自作できるのです。
GASでRAGを実現するアイデア
- 知識源: Googleドライブに「社内マニュアル」や「議事録」のフォルダを用意し、そこにGoogleドキュメントやテキストファイルを入れておきます。
- 検索: ユーザーがチャットで質問(例:「A案件の決定事項は?」)をしたら、GASの
DriveApp.searchFiles()
機能を使って、ドライブ内の関連ドキュメントを検索します。 - プロンプト生成: GASが、見つかったドキュメントのテキストを読み込み、「以下の資料を参考にして、A案件の決定事項を要約してください。[ここに資料のテキスト]」というプロンプトを自動で組み立てます。
- AIに送信: そのプロンプトを、さくらAIのAPI(
callSakuraAI
関数)に送信します。
たったこれだけで、Googleドライブを知識データベースにした「さくらAI搭載の社内アシスタント」が完成します。(まだ実装していないので、するのではないかと考えています、これからのチャレンジです)
まとめ
GASは、さくらAIという強力なエンジンを、私たちの日常業務に最適化するための「最高の接着剤」です。
スプレッドシートで=SUM()
関数を覚えるのと同じ感覚で、google.script.run
の使い方を一つ覚えるだけで、あなたのGoogle Workspaceは、ただのオフィスソフトから「強力なAI開発プラットフォーム」へと変貌します。
まずはこの記事のコードをコピーして、自分専用のAIチャットが動く感動を体験してみてください。ちなみに、私はエンジニアではないのですが、ここまではできますということです。

この記事を書いた遠田幹雄は中小企業診断士です
遠田幹雄は経営コンサルティング企業の株式会社ドモドモコーポレーション代表取締役。石川県かほく市に本社があり金沢市を中心とした北陸三県を主な活動エリアとする経営コンサルタントです。
小規模事業者や中小企業を対象として、経営戦略立案とその後の実行支援、商品開発、販路拡大、マーケティング、ブランド構築等に係る総合的なコンサルティング活動を展開しています。実際にはWEBマーケティングやIT系のご依頼が多いです。
民民での直接契約を中心としていますが、商工三団体などの支援機関が主催するセミナー講師を年間数十回担当したり、支援機関の専門家派遣や中小企業基盤整備機構の経営窓口相談に対応したりもしています。
保有資格:中小企業診断士、情報処理技術者など
会社概要およびプロフィールは株式会社ドモドモコーポレーションの会社案内にて紹介していますので興味ある方はご覧ください。
お問い合わせは電話ではなくお問い合わせフォームからメールにておねがいします。新規の電話番号からの電話は受信しないことにしていますのでご了承ください。
【反応していただけると喜びます(笑)】
記事内容が役にたったとか共感したとかで、なにか反応をしたいという場合はTwitterやフェイスブックなどのSNSで反応いただけるとうれしいです。
遠田幹雄が利用しているSNSは以下のとおりです。
facebook https://www.facebook.com/tohdamikio
ツイッター https://twitter.com/tohdamikio
LINE https://lin.ee/igN7saM
チャットワーク https://www.chatwork.com/tohda
また、投げ銭システムも用意しましたのでお気持ちがあればクレジット決済などでもお支払いいただけます。
※投げ銭はスクエアの「寄付」というシステムに変更しています(2025年1月6日)
※投げ銭は100円からOKです。シャレですので笑ってご支援いただけるとうれしいです(笑)