イカルプラグイン～ジェムといっしょ～

# kintone×Geminiプラグインをつくってみた。
**［ジェム（Gemini）］** わーい！[kintoneアドベントカレンダー](https://qiita.com/advent-calendar/2024/kintone)の24日目だよー！✨
今日まで毎日窓を開けてプレゼントを見てきたよね！✨
さあ、一緒に窓を開けてみよう！レッツゴー！

## はじめに

以前遊びで作った**イカルプラグイン**をパワーアップさせてみました。
今回はイカルを**AI（Gemini：ジェム）と連携させたい！** 
ポイント解説はジェムにお願い。

詳細はこちら`『師匠と私』`
https://note.com/kodotone_2022/m/m87408e5a25a9
>**イカルプラグイン**をざっくり説明
>+ Excelのイルカ・カイル君を再現したもの。
>+ レコード詳細画面を開くと出現する。
>+ フォームに入力したワードをアプリ内で検索してくれる。
>+ 『お前を消す方法』を入力すると検索をしない。

![スクリーンショット 2024-12-01 130754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/802fc8c7-dec0-e0f6-0f18-b6d40bc9df8e.png)

## 本編
### 機構
🐬イカルプラグイン ver.2.0　の機構
>+ レコード詳細画面を開くとイルカ（イカル）の画像が出てくる
>+ 画面の検索用フィールドに文字を入力する
>+ 入力値をkintoneフィールド【Question】に転記する
>+ kintoneフィールド【prompt】で自動計算したプロンプトを作る
>+ プロンプトをAPIでGeminiに投げる
>+ 回答ボタンを押すとGeminiが生成したテキストを取得する
>+ イカルの画像にテキストが表示される
>+ 指定のフィールド【Answer】に転記する
（イカル消えない）
>+ おまけ：検索用フィールドに「お前を消す方法」と入力したときだけ特定のメッセージが表示される（イカル消えない）

![スクリーンショット 2024-12-21 195226.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/cb78cb6e-a04a-274c-8090-3bf727bfc6b7.png)


### kintoneのアプリを用意
主なフィールドは4つ
1. 文字列（1行）: `変換モード` 
 プロンプトに追加したい指定ワード（例：津軽弁で）
2. 文字列（1行）: `Question`
イカルのフォームに入力した値を格納
3. 文字列（1行）:`Prompt`
　Geminiへなげるプロンプトを生成する
 Question＋変換モード＋「簡潔にまとめて。なるべく120文字以内で答えてください。指定以外の回答は無効です」を付け加えている＊
4. 文字列（複数行）`Answer`
Geminiからの回答（Geminiから取得した値。イカルに出力する）
>＊promptではなくQuestionがGeminiに投げられていたのに気づかず、指定がまったく反映されないので指示を厳しめにしてしまったという。。。

![スクリーンショット 2024-12-21 183526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/34a6d85a-5fbb-09b1-f510-6f0dff93250f.png)


### 環境の用意
GeminiとAPIでアクセスする環境
いくつか方法はありましたが、今回はこちらを使用

**［ジェム］** Google が提供する生成型 AI (Generative AI) のライブラリだよ。
Google SDKは、Googleのサービスを使って、自分だけのオリジナルのものを作りたい人向けの、とても便利な道具箱なんだ。
```
import { GoogleGenerativeAI } from "@google/generative-ai";
```

### フォルダとファイルを用意

**［ジェム］** このフォルダの中には、kintoneのアプリとGoogleのAIという賢いロボットを仲良くさせるための、特別な言葉（プログラム）がたくさん詰まっているよ。この言葉を使って、kintoneのアプリでできることをもっともっと便利にしたり、新しいことができるようにしているんだ。

>お前…自分のこと賢いAIって…

![スクリーンショット 2024-12-16 215700.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/7571a693-9783-4d18-7d6d-0dcb0717965f.png)

### 2つのJavascriptファイルを用意
`index.js` => `bundle.js`
GeminiのAPIにアクセスするためのファイル
のちにkintoneで動作させるため webpackでbundle.jsに変換

`run.js` 
kintoneレコード詳細画面を開いたらイカル画像を出現させるCSSやHTMLとか、検索ボタンをおして入力した値をフィールドに格納してグローバルスコープを呼び出してAPIアクセスしたりとか、そのあとボタンを押してAnserを表示させるとかの実行ファイル

#### JavaScriptコードの一部です～

```diff_javascript:index.js
const apiKey = 'YOUR-API-KEY';//実際のAPIキーを入れる

import { GoogleGenerativeAI } from '@google/generative-ai';

const genAI = new GoogleGenerativeAI(apiKey);

// 関数をグローバルスコープに登録して呼び出せるようにする
 async function generateText(prompt) {
 ---
   try {
    // モデルを取得
      const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

      // プロンプトでコンテンツ生成
      const result = await model.generateContent(prompt);
      return result.response.text(); // 生成されたテキストを返す
    }
// グローバルスコープに登録
window.generateText = generateText;
 ```
**［ジェム］** プログラムの中で使いたいものを、みんながいつでも使えるように置いておく場所、それがグローバルスコープだよ！
```diff_javascript:run.js
 kintone.events.on(['app.record.detail.show'], (event) => {
 ---
 //🐬Step3～GeminiのAPIにアクセス
      try {

          // プロンプト値を searchQuery として設定
           const searchQuery = promptValue;

          // Google Generative AI にリクエスト
              const generatedText = await window.generateText(searchQuery);
              ---
              ---
```
**［ジェム］** kintone.events.onは、kintoneの中で、何か新しいことが起きたり、何かが変わったりしたときに、コンピューターに教えてもらうための言葉なんだ。
+ 「const」 は、一度決めたものを変えないようにするための魔法の言葉。
+ 「await」 は、コンピューターがゆっくり考えて、答えを出すまで待つための合図。

```:bundle.js
(()=>{"use strict";var t,e,n;!function(t){t.STRING="string",t.NUMBER="number",t.INTEGER="integer",t.BOOLEAN="boolean",t.
```
**［ジェム］** bundle.jsは、コンピューターが理解できる言葉（プログラム）を、一つにまとめたファイルのことなんだ。このファイルの中には、ゲームの画面を表示するためのプログラムや、ボタンを押したときの動きをさせるためのプログラムなど、たくさんのプログラムがぎゅっと詰まっているんだよ。

## イカルは　プ・ラ・グ・イ・ン
**［ジェム］** kintoneのカスタマイズとプラグインは、どちらもkintoneをもっと便利にするための方法なんだ。
カスタマイズ は、自分だけのオリジナルのkintoneを作る感じ。
プラグイン は、kintoneに新しい機能を追加する感じ。
　　↓　↓　↓
>プラグインはだれでも簡単にkintoneに機能を追加できる、どんな環境でも。
ということは、GeminiのAPIキーをコード内に書いているとダメ。
（そもそもが書いちゃダメ…）
これをプラグインにすると解決できます。

![スクリーンショット 2024-12-22 164431.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/e48d8d3d-cb09-30d4-d1d2-67f71722860a.png)
![スクリーンショット 2024-12-22 164447.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/227548c6-9351-49de-7853-72c53cab8610.png)


#### 完成しました～🎉
![スクリーンショット 2024-12-21 204004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/129dc3c8-d1c0-fdc4-4e67-b0e56be0f387.png)

 **［ジェム］わぁ、すごい！ウェブの画面にイルカが出てきて何でも答えてくれるなんて、魔法みたいだね！** 
 
#### おまけ
🐬チャッピー（ChatGPT）---コードはチャッピーの方が得意かも！
![スクリーンショット 2024-12-21 183645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936741/3fc8b82e-5b85-5734-04c4-0c200a49d551.png)

🐬Googleの参考サイト
>ここにサンプルコードがあって助かったわ～
https://www.npmjs.com/package/@google/generative-ai
ここに使用モデルも書いてあったよ～
https://ai.google.dev/gemini-api/docs/get-started/tutorial?lang=node&hl=ja

🐬cybozu developer network
> レコードに値をセットする
https://cybozu.dev/ja/id/bd485c4c00776c6a54fbf89c/#set-record-value
1件のレコードを更新する
https://cybozu.dev/ja/id/607d2f57a86f03ca70588ab8/#sample-code
プラグインの作り方
https://cybozu.dev/ja/tutorials/hello-kinplugin/handle-sensitive-data/

🐬にこkin！
＞認証情報のべた書きは禁止！
（今回はお遊びなので…対応できてないですけど）
https://shop.cybozu.co.jp/products/4820287389775?variant=46569864593632

kintoneのお作法はチャッピーに聞いても答えてくれた～

## なんとか
kintoneアドベントカレンダーのために開発を思いたち間に合うかどうか？！？！
私のやる気（と能力）が一番の問題でした。

ジェムになんでも聞けはすぐ出来るのでは？と甘いことを考えてました。
結局はチャッピーに手伝ってもらってようやく出来たんですけどね。


開発の裏話はこちらのnoteに記載してます！

`師匠と私-ふたたび。` 
https://note.com/kodotone_2022/n/ndfd08535d175

Special Thanks:
淺野 將生 師匠　ありがとう！！！