9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Slack App × GAS × GeminiでAIキャラクターボットを作ってみた

Last updated at Posted at 2025-12-01

この記事はOPENLOGI Advent Calendar 2025の2日目の記事です。

1日目は、弊社VPoE 坂井が担当した『EMになって10年。10年前の自分に伝えたい8つのこと』でした。赤裸々に失敗について語り、学びを言語化している激アツな記事なので、まだ読んでいない方はぜひご覧ください!

はじめに

最近、Slack App、Google Apps Script(GAS)、そしてGemini APIを組み合わせて、AIキャラクターボットを作成してみました。この組み合わせが想像以上に開発しやすく、お遊びにぴったり個人開発やプロトタイピングに最適だと感じたので、その魅力と実装のポイントをご紹介します。

無料枠の範囲内で十分に遊べる構成になっているので、「AIボットを作ってみたいけど、インフラ構築が面倒」「とりあえず手軽に試してみたい」という方にぴったりです。

SlackとGoogle Workspaceを導入している会社であれば、サクッと社内で使えるツールを作れちゃったりもします。まず何を作ったかからご紹介して、GASについて、Slack Appの開発のポイント、Gemini APIについてと、順々に紹介していこうと思います!

1. 何を作ったか? - AIキャラクターSlackボット

Slackワークスペース内で動作するAIキャラクターボットを実装しました。
ボットにメンションすると、設定されたキャラクターとして応答します。

呼び出し方はシンプルで、@ボット名 キャラクター名/絵文字 本文 の形でメンションするだけです。メンションの後にキャラクター名を指定することで、キャラクターを切り替えられるようになっています。

image.png

↑の例はあんまり実用的な例ではないですが、スレッドの内容を要約してくれるキャラクターを作っておけばこんな感じのことができたりします。

image.png

そして、実は添付画像が読めたり、Google Docsが読めたりします。
単なるチャットボットではなく、様々なコンテキストを理解して応答できる高機能なボットを目指しました。

以下で、簡単に機能を紹介しますね。

余談: Museという命名はGeminiに提案してもらいました。

@Muse(ミューズ)は、ギリシャ神話に登場する芸術、科学、インスピレーションを司る女神たち(ムーサ)に由来します。AIキャラクターチャットボットにとって、ユーザーが新しいキャラクター設定を考えたり、創造的な会話を引き出したりする際の「インスピレーションの源」となる役割を象徴するのに非常に適しています。創造性を刺激し、多様なペルソナを引き出すAIの機能性を表現できます。

柔軟なキャラクター設定

キャラクターの設定は複数の方法で編集可能です:

  • スプレッドシートでの直接編集: スプレッドシートを開いて直接セルを編集することも可能です。非エンジニアでも簡単に設定変更できます。
  • Slackコマンドでの編集: ボットにメンション + コマンド名 + 引数で設定を変更できます。コマンドの一覧は @bot help で見られます。
@bot create Mentor :owl:
あなたは穏やかで励まし上手なメンターです。
質問の意図をくみ取り、次の一歩を丁寧に提案してください。

@bot update_prompt Mentor
新しいプロンプト内容...

@bot update_name Mentor メンター

スレッド内会話の文脈保持

スレッド内でボットを呼び出すと、そのスレッド全体の会話履歴をコンテキストとして取得します。過去のやり取りを踏まえた自然な会話が可能になり、「さっき言ってたあれ」のような指示語にも対応できます。

Slackリンクの自動展開

会話の中に他のスレッドやメッセージへのSlackリンクが含まれている場合、その内容を自動的に展開してコンテキストに含めます。「このスレッドの内容について教えて」のように、別の会話を参照した質問にも答えられます。

添付ファイル対応

スレッド内に添付されたファイルを認識し、その内容を踏まえた応答が可能です。テキストファイルだけでなく、10MBまでのPDFファイル、および画像ファイルに対応しています。「この画像について説明して」「このPDFの要点をまとめて」といった依頼に応えられます。

Google Docs対応

Google Docsのリンクがスレッドやキャラクター設定に含まれている場合、ドキュメントの内容を自動取得してコンテキストに含めます。以下のような用途で活用できます:

  • キャラクター設定の詳細化: 長文のキャラクター設定やキャラクターが持つ知識(業務知識など)をGoogle Docsで管理できます。呼び出すたびに展開するので、更新に自動で追従します。
  • 参考資料の参照: 「このドキュメントに基づいて回答して」のような依頼に対応できます。

なお、Google スプレッドシートやGoogle スライドへの対応も近日中に実装予定です。

Geminiモデルの選択

キャラクターごとに使用するGeminiモデルを選択できます。用途に応じて使い分けが可能です。また、メインモデルの他にフォールバックモデルを設定することができ、メインモデルのレートリミットに達した時はフォールバックモデルが使われます(ex. proをメイン、flashをフォールバックに設定)。

@bot show_models  # 利用可能なモデル一覧を表示
@bot update_model Mentor gemini-1.5-flash-latest gemini-1.5-pro-latest

ちなみに、画像生成(Imagen, Nano Banana)にも対応するコードを実装してみたのですが、無料枠では利用できないため、課金しないと動作確認ができず、まだテストできていません笑
今度動かしてみたいなあ...。

今後の展望

最初は個人的に遊びで作ってたのですが、あれ?意外と使えるんじゃね?と欲が出てきています。

1. 社内展開してみたい

今も社内で動かしてはいますが、私の個人アカウントで動かしている状態なので、色々と取り回しがしにくい状態です。会社管理のアカウントを発行して動かしてもらえないか打診中です。

2. エージェント的な動きをさせてみたい

「このスレッドの会話内容をまとめてRedmineにコメントして!」のようなリクエストにも答えられるように実装してみたいです。スキルのような概念を実装して、ボットがボット自身にメンションを飛ばして指示することでできるんじゃないかなーとぼんやり考えたりしています。

まあ、本格的にそういうことをするなら、普通にエージェントを動かしたサーバーを用意してそちらでどうこうしたほうが良いと思いますが...笑
それはそれで、社内に作ってくれているエンジニアがいるので乞うご期待です!

3. 改善・機能追加もボット起点で行いたい

「こういう機能つけてほしいんだけど」とか「バグってるよ!」と報告すると、2のエージェント的な機能の応用で、いい感じの説明でGitHubにissueを作る -> issueをトリガーにして自動実装 -> PR完成!みたいな仕組みにしてみたいです。

そうすれば、社内で使ってくれているユーザーの意見をすぐに反映できるかもしれません。そのためには実装やらドキュメント類やらをいい感じに整理して、エージェントが迷わず実装できるようにする必要があるので、まだ道半ばですね...笑


ということで、こんな感じのボットがサクッとお手軽に作れたので、ここからは、その 構成要素(GAS, Slack App, Gemini API) について簡単にご紹介していきたいと思います。

2. GASはいいぞ! - サーバーレスの快適さ

このプロジェクトでGASを採用した理由は、その手軽さと機能の充実度にあります。

お手軽な実行環境

GASの最大の魅力は、何も準備せずにすぐ始められる ことです。

  • 無料で即立ち上げ→デプロイ可能: Googleアカウントさえあれば、すぐにコードを書いてWebアプリケーションとしてデプロイできます。サーバーのセットアップや管理は一切不要です。
  • スプレッドシートをDB代わりに使える: 簡単なデータ保存ならスプレッドシートへの読み書きで十分です。今回は主にキャラクター設定の保持に活用しました。
  • スプレッドシートをUI(設定画面)代わりに使える: キャラクター設定をスプレッドシートに保持することは、そのまま簡易的な設定画面を提供することになります。管理画面を別途実装する必要がありません。
  • 充実した周辺機能: CacheServiceでAPIレスポンスをキャッシュしたり、PropertiesServiceでAPIキーなどの機密情報を安全に管理したりできます。複雑なことをしなければこれで事足ります。

Google Workspaceとのシームレスな連携

GASはGoogleのサービスなので、当然ながらGoogle Workspace(スプレッドシート、ドキュメント、ドライブ、カレンダーなど)との連携が非常に簡単です。認証も不要で、スクリプトから直接アクセスできます

  • Google Docs: DocumentApp.openByUrl(url)のようなシンプルなAPIで、ドキュメントの内容を取得できます。今回のボットへの導入も楽々でした。
  • スプレッドシート: SpreadsheetAppを使ってデータの読み書きが可能です。DBの代わりとして使えちゃいます。
  • カレンダー: CalendarApp を使って予定の作成・取得・更新が可能です。
  • ドライブ: DriveApp でファイルのアップロード・ダウンロード・共有設定などが行えます。

これらのサービスを組み合わせることで、業務自動化ツールとして非常に強力な仕組みを比較的簡単に構築できます。

claspが優秀 - ローカル開発環境の構築

GASはブラウザ上のエディタでも開発できますが、claspというCLIツールを使えば、ローカルの使い慣れたエディタで開発することができます。

  • ローカル開発 → push → デプロイ: ローカルで編集したファイルを clasp push でGASにアップロードし、 clasp deploy でデプロイできます。
  • ディレクトリ構成の自由度: GASのエディタ上ではフォルダ階層を作れませんが、claspを使えばローカルではディレクトリを分けて管理でき、pushすると自動的にフラットなファイル名(folder/file.gsのような形式)に変換してくれます。
  • .claspignore でテストコードを除外: テストファイルやREADMEなど、デプロイ不要なファイルを除外できます。Jestなどを使ったテスト実装もバッチリです。
  • TypeScriptだってもちろんOK: もちろん、TypeScriptで書いてJavaScriptにトランスパイルしてからデプロイすることも可能です。そうすれば、型安全性を保ちながら開発できます。

私のボット開発は雑に始めたせいであんまり整ってないですが、ちゃんと設計すれば十分に整った開発環境で開発することができますよ!

3. Slack Appも楽々開発 - Slack APIの扱いもAIエージェントがあれば一撃だ!

Slack APIは非常に多機能ですが、その分ドキュメントも膨大で、初めて触る場合は学習コストがかかります。

  • OAuth認証とスコープの設定
  • メッセージの取得・送信
  • スレッド情報の取得
  • ファイルのダウンロード処理

などなど、細かい仕様を理解するのは骨が折れます。

しかし、Claude CodeなどのAIエージェントを使えば、実装方針を伝えるだけで、Slack APIをいい感じに使って実装してくれます。

今回の開発で私は一切API連携部分のコードを書いていませんし、リファレンスも読んでいません。 基本的に「エージェントへの指示 -> テスト -> 動かない場合はエラーを伝えて指示」で済んでいます。

迷うことがあれば、公式リファレンス(Slack API Documentation)の内容をぶん投げれば良さそうです。

特に外部APIとの接続部分は、エージェントに任せることで開発効率が劇的に向上しますね。ちょっとしたツールなら丸投げで作れてしまうので、Slack Appの開発などは本当に捗ります。

ちなみに、本記事で書いているAIキャラクターSlackボットの開発は、最初の原型(とりあえずキャラ固定でスレッド読んで応答してくれるまで)はある夜思いついて実装に着手し、GitHub Copilotを使って2, 3時間くらいでできてしまって驚愕しました。

注意点: Slack Eventのタイムアウトを回避する

Slack Events APIには3秒以内に200番台のレスポンスを返さないとタイムアウトという仕様があります。これはGASと相性が悪くまあまあ厄介です。

GASの実行速度はスプレッドシートとの接続等でただでさえ遅くなりがちです。ましてやAIを呼び出すとなると、ほぼ確実にオーバーします。

そのまま実装するとタイムアウトが発生し、Slackが同じイベントを再送信してしまい、多重実行されてしまいます。よって、CacheServiceを用いてイベントIDをキャッシュし、既に処理済みならスキップするなどの工夫が必要なので注意してください。

余談: Slackを知的生産活動のハブにするのはいいぞ

余談ですが、本記事のボットの他にも、スタンプ1つでSlackのスレッドをGoogle DriveにMarkdown形式でDumpしてくれるAppを作ったりして、個人的に使っているSlackワークスペースを知的生産活動のハブにしています。

日記やら、アイデアやら、つぶやきやら、記事のネタやらをとりあえずSlackに突っ込んで、そこから永続化したいものをGoogle Driveに飛ばして、Obsidianから見たりとか、そういう感じで使ってます。

本記事のボットを使って、Slack上でAIとアイデアについて壁打ちができたりもします(あと、暇つぶしもね笑)。

私は不器用なので、そういうちょっとしたツールの開発とかにはほとんど手を出してこなかったのですが、今ではサクッとそういうことができちゃうので、AIエージェント様様ですね。

4. Gemini APIは優しい - 無料枠がある!コスト面の安心感

AIボットを作る際に気になるのがAPI利用料金ですが、Gemini APIには無料枠が用意されています。特に、組織で何かを始めるときに、お金の話が絡むと面倒なのはあるあるなので、無料枠があるのはとてもありがたいことです。

無料枠の条件

Google AI StudioからAPIキーを発行し、支払い方法を紐づけなければ課金は発生しません。無料枠の範囲内であれば、個人利用や学習目的で十分に活用できます。

無料枠の制限(2025年12月時点)

Gemini APIの無料枠には以下のようなレート制限があります:

モデル RPM(リクエスト/分) TPM(トークン/分) RPD(リクエスト/日)
Gemini 2.5 Flash 10 250,000 250
Gemini 2.5 Flash プレビュー 10 250,000 250
Gemini 2.5 Flash-Lite 15 250,000 1,000
Gemini 2.5 Flash-Lite プレビュー 15 250,000 1,000
Gemini 2.0 Flash 15 1,000,000 200
Gemini 2.0 Flash-Lite 30 1,000,000 200
Gemini 2.5 Pro 2 125,000 50

※最新の情報は公式ドキュメントをご確認ください

実用性

今回のSlackボットのように、個人やチーム内での利用であれば、FlashFlash-Lite の無料枠でなら十分に運用できます。Flashをメインに使い、レートリミットに達したらFlash-Liteにフォールバックするようにしておけば、1分間に25リクエスト、1日に1,250リクエストまで可能なので、よほど頻繁にボットを呼び出さない限り制限に引っかかることはありません。

なお、トークンの方は、日本語の場合Geminiでは「1トークン ≒ 1文字」と考えて良いらしい(by Gemini)ので、そちらのリミットに引っかかることはそうそうなさそうです。25万字というと、文庫本2冊分程度だそうですよ。

Proは一応無料枠はあるものの、個人でお試し程度にちょろっと利用できるくらいですね。会社やチームで使うとなると厳しそうです。そして、残念ながら3.0 Proには無料枠はないみたいですね。

また、画像生成(Imagen, Nano Banana)は無料枠では利用できませんが、画像認識 は問題なく使えます。今回のボットでもスレッド内の画像を認識させる機能を実装できました。Gemini Files APIを用いてファイルをアップロードし、そのキーをGeminiのAPIを呼び出す際に渡すようなイメージです。

Geminiにアップロードしたデータは48時間キャッシュされるようなので、GAS側でも添付ファイルのidをキーにしてキャッシュを持ち、何度もアップロードするのを避けています。十分実用的な速度で動いていますよ。

まとめ

Slack App × GAS × Geminiの組み合わせは、以下のような場面で非常に有効です:

  • 個人開発・プロトタイピング: インフラ構築不要で即座に始められる
  • チーム内ツール: 無料枠で十分に運用可能
  • 学習目的: 実際に動くものを作りながら学べる

AIエージェントの支援を受けながら、サーバーレス環境で気軽にAIボットを作れる時代になりました。今回紹介した構成で、皆さんもオリジナルのボットを作ってみてはいかがでしょうか。ぜひ試してみてください!

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?