Gemini API を使った要約機能付き受信メール通知 LINE Bot
やりたいこと
メールの着信を LINE 通知. そのときにメールの内容を要約して表示したい.
環境
GAS + GCE(Node.js)
仕組み
- [GAS] 新着メールを定期的に確認し、検知したら内容を 2 へ送信
- [GCE] Express HTTP サーバが 1 からのリクエストを受信したら、Gemini にメールを要約するようにプロンプトを送信
- Gemini がプロンプトに対して返答し 2 へ返す
- [GCE] 3 からの返答を 5 へ送信
- [GAS] LINE Messaging API へ通知データを送信
- LINE Messagine API から LINE に通知が届く
GAS
├ main.gs (Gmailへのアクセス)
└ do-post.gs (LINE 通知要請プログラム)
GCE
└ Express サーバ
詳しい設定方法はこちら
ステップ
- Gemini API アクセス
Gemini へプロンプトを送信し、結果を取得するプログラム. - Gmail へのアクセス
Gmail を定期的に確認する GAS プログラム. - LINE 通知要請プログラム
LINE Messaging API に通知内容を送信する GAS プログラムである. - Express サーバ作成
1 のプログラムと連携し、Gemini に問い合わせるための HTTP サーバ.
API を公開し、GAS(2) からのリクエストを受け付け、Gemini を通したメッセージを GAS(3) にリクエストするプログラム.
1. Gemini API アクセス
- Gemini API Key を作成する
Google AI Studio を使うと簡単に取得できる - 公式 SDK パッケージ GoogleGenerativeAI をインストールする
npm i @google/generative-ai
- 今回は gemini-api.js をモジュールとして使うためにマイナーチェンジ
const { GoogleGenerativeAI } = require("@google/generative-ai");
// ↓ your-gemini-api-key には生成した API Key を入れる. (実装時は環境変数を使う)
const genAI = new GoogleGenerativeAI('<your-gemini-api-key>');
async function run(_prompt) {
// For text-only input, use the gemini-pro model
const model = genAI.getGenerativeModel({ model: "gemini-pro"});
const prompt = _prompt;
const result = await model.generateContent(prompt);
const response = result.response;
const text = response.text();
return text;
}
module.exports.run = run; // Module Export
2. Gmail へのアクセス
GAS で次のコードを作成し、main 関数を 10 分おきに起動する設定を行う.
Gmail を "is:unread" で定期的に検索し、ヒットしたら、Express サーバに送信する.
function main() {
const GmailSreadLimit = 3; // 取得するメール検索結果のスレッド数
const masking = (text) => text
.replace(/ID:.*$|ID.*|PW:.*$/g, "*****") // 必要に応じた個人情報マスキング
.replace(/\r\n/g, '\n');
const threads = GmailApp.search('is:unread', 0, // メール検索
GmailSreadLimit);
const msgsInThreads = threads.map((t) => {
if (t) return t.getMessages();
});
const mails = msgsInThreads.map((msgs) => {
return msgs.map((m) => {
m.markRead(); // 取得したメールを既読にする
const plainBody = m.getPlainBody(); // メール本文
return {
from: m.getFrom(),
subject: masking(m.getSubject()),
body: masking(plainBody),
};
});
});
const arr = mails.flat();
arr.forEach((m) => {
sendPostRequest(m); // データを POST
});
}
// data を Express サーバに POST する関数
function sendPostRequest(data) {
const options = {
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"payload": JSON.stringify(data)
};
UrlFetchApp.fetch("http://xxx.xxx.xxx.x:3000", // Express サーバアドレス
options);
}
3. LINE 通知要請プログラム
POST があったら LINE Messaging API に通知内容を POST する GAS プログラムである.
LINE Messaging API へのアクセスには、ライブラリをお借りした.
インポートが必要.
ライブラリID: 1EvYoqrPLkKgsV8FDgSjnHjW1jLp3asOSfDGEtLFO86pPSIm9PbuCQU7b
また、GAS スクリプトプロパティに LINE_USER_ID を追加する.
LINE の プッシュ通知には、友達追加済みの既知の LINE USER ID が必要.
コードを作成したら、それをウェブアプリケーションとして公開し、URL を取得する.
const AccessToken = PropertiesService // LINE_ACCESS_TOKEN スクリプトプロパティ
.getScriptProperties().getProperty("LINE_ACCESS_TOKEN");
const LineUserId = PropertiesService // LINE_USER_ID スクリプトプロパティ
.getScriptProperties().getProperty("LINE_USER_ID");
function doPost(e) {
if (e === undefined) return;
const LnClient = new LineBotSDK // API Client 作成
.Client({ channelAccessToken: AccessToken });
const contents = JSON.parse(e.postData.contents);
const mailData = contents.content;
LnClient.pushMessage(LineUserId, { // POST 送信
'type': 'text',
'text': `
${mailData.from}\n
ーーーーーーーーーーーーーーー\n
${mailData.subject}\n
ーーーーーーーーーーーーーーー
${mailData.body}`
});
return;
}
ちなみに、上記のコードは、LINE Developpers の Webhook 検証に失敗する.
しかし、通知はできるので OK.
4. Express サーバ
ソースコードはこちら. これを GCE で 起動しておく. (初期は Port 3000)
エンドポイントに POST があれば、gemini-api.js でプロンプトを送信. その返答を前項で作成した GAS ウェブアプリケーション の URL に POST するシステム.
URL 等は適宜変更が必要.
Discussion