テキストを送ればGeminiのAPIを通してプロンプトに沿った返答をする 返答内容をスプレッドシートに保存
画像を送れば画像のURLをスプレッドシートに保存
という機能が出来ます
1. Googleアカウントを準備する
Googleアカウントを持っていない場合は、Googleアカウントを作成してください。
Googleアカウントが必要です。このアカウントでGoogleドライブやGoogleスプレッドシートにアクセスします。
2. スプレッドシートの準備
Googleドライブで新しいGoogleスプレッドシートを作成します。
名前は何でもいいです。
スプレッドシートに「Sheet1」と「Sheet2」という名前のシートを作成します(デフォルトで存在する場合もあります)。
「Sheet1」は解析結果や画像のURLを保存します。
「Sheet2」はログメッセージを保存します。
3. Google Apps Script (GAS) プロジェクトの作成
スプレッドシートにアクセスし、「拡張機能」→「Apps Script」を選択します。
新しいスクリプトプロジェクトが作成されます。このプロジェクトにコードを書いていきます。
3. コードのコピー&ペースト
下記のコード(doPost(e)から始まる)をすべてコピーします。
作成したGoogle Apps Scriptプロジェクトのエディタに貼り付けます。
function doPost(e) {
var replyToken;
try {
// LINEからのPOSTデータをJSON形式にパース
var json = JSON.parse(e.postData.contents);
logEvent("Received event: " + JSON.stringify(json));
// 最初のイベント情報を取得
var event = json.events[0];
replyToken = event.replyToken;
// メッセージの種類に応じて処理を分岐
if (event.message.type === "image") {
handleImageMessage(event, replyToken);
} else if (event.message.type === "text") {
handleTextMessage(event, replyToken);
} else {
replyToLine(replyToken, "画像またはテキストを送信してください。");
}
} catch (error) {
// エラーが発生した場合、ログに記録し、LINEにエラーメッセージを返信
logEvent("Error in doPost: " + error.message);
if (replyToken) {
replyToLine(replyToken, "エラーが発生しました: " + error.message);
}
}
}
function handleImageMessage(event, replyToken) {
try {
// 画像のIDを取得
var imageId = event.message.id;
// 画像URLを取得するための関数を呼び出し
var imageUrl = getImageUrl(imageId);
// 画像を受け取った旨をLINEに返信
replyToLine(replyToken, "画像を受け取りました。スプレッドシートに保存します。");
// 画像URLをスプレッドシートに保存
saveToSheet("画像が送信されました", imageUrl);
// 画像の保存が完了した旨をLINEに返信
replyToLine(replyToken, "画像を保存しました。URL: " + imageUrl);
} catch (error) {
// エラーが発生した場合、ログに記録し、LINEにエラーメッセージを返信
logEvent("Error in handleImageMessage: " + error.message);
replyToLine(replyToken, "画像の処理中にエラーが発生しました: " + error.message);
}
}
function handleTextMessage(event, replyToken) {
try {
// テキストメッセージを取得
var message = event.message.text;
var replyMessage = "";
// テキストをGemini APIで解析
replyMessage = analyzeTextWithGemini(message);
// 解析結果をLINEに返信
replyToLine(replyToken, replyMessage);
} catch (error) {
// エラーが発生した場合、ログに記録し、LINEにエラーメッセージを返信
logEvent("Error in handleTextMessage: " + error.message + " | Stack: " + error.stack);
replyToLine(replyToken, "テキストの処理中にエラーが発生しました: " + error.message);
}
}
function getImageUrl(imageId) {
try {
// 画像取得のためのログ
logEvent("Attempting to fetch image with ID: " + imageId);
// 画像データを取得するためのURLを生成
var url = "https://api-data.line.me/v2/bot/message/" + imageId + "/content";
// LINE APIを使用して画像データを取得
var response = UrlFetchApp.fetch(url, {
headers: {
"Authorization": "Bearer " + getChannelAccessToken(),
},
muteHttpExceptions: true, // HTTPエラーを無視せずレスポンスを取得
});
var responseCode = response.getResponseCode();
var responseText = response.getContentText();
// 画像取得のレスポンスをログに記録
logEvent("LINE API response code for image fetch: " + responseCode);
logEvent("LINE API response text for image fetch: " + responseText);
// 画像取得に失敗した場合、エラーをスロー
if (responseCode !== 200) {
throw new Error("Failed to fetch image. Response code: " + responseCode + ", Response text: " + responseText);
}
// 取得した画像データをGoogleドライブに保存し、URLを取得
var blob = response.getBlob();
var file = DriveApp.createFile(blob).setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
var imageUrl = file.getUrl();
// 画像URLをログに記録
logEvent("Image URL successfully retrieved: " + imageUrl);
return imageUrl;
} catch (error) {
// エラーが発生した場合、ログに記録し、エラーメッセージをスロー
logEvent("Error in getImageUrl: " + error.message + " | Stack: " + error.stack);
throw new Error("画像URLの取得中にエラーが発生しました。");
}
}
function analyzeTextWithGemini(message) {
logEvent("Starting text analysis with Gemini API...");
try {
// Gemini APIのAPIキーとURLを設定
const apiKey = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');
const url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=' + apiKey;
const objHeaders = {
'Content-Type': 'application/json'
};
// リクエストボディを設定
const objPayload = {
contents: [
{
parts: [
{
text: "ユーザーからのLINEメッセージの内容を博識な文豪が書く日記風に変えてください: " + message
}
]
}
]
};
// リクエストオプションを設定し、Gemini APIにリクエストを送信
const objOptions = {
method: 'post',
headers: objHeaders,
payload: JSON.stringify(objPayload),
//muteHttpExceptions: true
};
logEvent("Sending request to Gemini API...");
const response = UrlFetchApp.fetch(url, objOptions);
const responseCode = response.getResponseCode();
const responseText = response.getContentText();
// Gemini APIのレスポンスをログに記録
logEvent("Gemini API response code: " + responseCode);
logEvent("Gemini API response text: " + responseText);
// APIリクエストが失敗した場合、エラーをスロー
if (responseCode !== 200) {
throw new Error("Gemini API request failed with response code: " + responseCode + ", response text: " + responseText);
}
// 解析結果をパースして取得
const jsonResponse = JSON.parse(responseText);
logEvent("Received response from Gemini API: " + JSON.stringify(jsonResponse));
// テキストの取得部分を修正し、スプレッドシートに保存
const description = jsonResponse.candidates[0].content.parts[0].text;
saveToSheet(description, ""); // テキスト解析結果をシートに保存
return description;
} catch (error) {
// エラーが発生した場合、ログに記録し、エラーメッセージをスロー
logEvent("Error in analyzeTextWithGemini: " + error.message + " | Stack: " + error.stack);
throw new Error("Gemini APIの解析中にエラーが発生しました。");
}
}
function saveToSheet(description, imageUrl) {
try {
// シートを取得し、データを保存
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
sheet.appendRow([description, imageUrl]); // 解析結果と画像URLをシートに保存
logEvent("データをスプレッドシートに保存しました。");
} catch (error) {
// エラーが発生した場合、ログに記録し、エラーメッセージをスロー
logEvent("Error in saveToSheet: " + error.message + " | Stack: " + error.stack);
throw new Error("スプレッドシートへの保存中にエラーが発生しました。");
}
}
function replyToLine(replyToken, message) {
try {
// LINE APIに返信するためのURLとヘッダーを設定
var url = "https://api.line.me/v2/bot/message/reply";
var headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + getChannelAccessToken(),
};
// メッセージが空でないことを確認
if (!message) {
throw new Error("Reply message is empty. Cannot send an empty message to LINE.");
}
// 返信メッセージを設定し、LINE APIにリクエストを送信
var postData = {
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": message
}]
};
var response = UrlFetchApp.fetch(url, {
"method": "post",
"headers": headers,
"payload": JSON.stringify(postData)
});
var responseCode = response.getResponseCode();
var responseText = response.getContentText();
// 返信結果をログに記録
logEvent("LINE API response code: " + responseCode);
logEvent("LINE API response text: " + responseText);
// 返信が失敗した場合、エラーをスロー
if (responseCode !== 200) {
throw new Error("Failed to send message to LINE. Response: " + responseText);
}
logEvent("Replied to LINE: " + message);
} catch (error) {
// エラーが発生した場合、ログに記録し、エラーメッセージをスロー
logEvent("Error in replyToLine: " + error.message + " | Stack: " + error.stack);
throw new Error("LINEへの返信中にエラーが発生しました。");
}
}
function logEvent(message) {
try {
// ログを記録するためのシートを取得または作成
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
if (!sheet) {
sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet("Sheet2");
}
var date = new Date();
var formattedDate = Utilities.formatDate(date, Session.getScriptTimeZone(), "yyyy-MM-dd HH:mm:ss");
sheet.appendRow([formattedDate, message]); // ログメッセージをSheet2に保存
} catch (error) {
// ログ記録のエラーをLoggerに記録
Logger.log("Error in logEvent: " + error.message + " | Stack: " + error.stack);
}
}
function getChannelAccessToken() {
// スクリプトプロパティからアクセス・トークンを取得
var scriptProperties = PropertiesService.getScriptProperties();
var token = scriptProperties.getProperty('YOUR_CHANNEL_ACCESS_TOKEN');
logEvent("Access token retrieved: " + (token ? "Success" : "Failed"));
return token;
}
↓ ここのtext: のとこにプロンプトを書きます
4. 必要なライブラリやトークンの設定
LINEチャネルのアクセストークン取得:
LINE Developers にアクセスし、LINEアカウントでログインします。
新しいチャネルを作成し、アクセストークンを取得します。
参考サイト
Gemini APIキーの取得:
Gemini APIを利用するために、Google Cloud Consoleにアクセスし、APIキーを取得します。
1.Google AI StudioのGemini APIのページにアクセス
Google AI StudioのGemini APIのページ
2.左メニューにある「Get API Key」を選択
3.API Keysのページで「Create API keys in new project」もしくは「APIを作成」をクリックします
4.少し待つとAPIキーが発行されるので、「Copy」をクリック、APIキーがクリップボードにコピーされます
スクリプトのプロパティ設定
取得したトークンをGoogle Apps Scriptのプロジェクトに保存します。
「プロジェクト」→「プロジェクトのプロパティ」→「スクリプトのプロパティ」からトークンを設定します。
例えば、YOUR_CHANNEL_ACCESS_TOKEN という名前でアクセストークンを設定します。
取得したAPIキーをGoogle Apps Scriptのスクリプトプロパティに設定します。名前はGEMINI_API_KEYとします。
6. Webアプリケーションとしてデプロイ
Google Apps Scriptエディタで「デプロイ」→「ウェブアプリケーションとしてデプロイ」を選択します。
次のユーザーとして実行を「自分」に設定
アクセスできるユーザーを「全員」に設定
デプロイ後に表示されるURL(ウエブアプリURL)が、LINEのWebhook URLとして使用されます。
7. LINE Developers コンソールでの設定
LINE Developers コンソールに戻り、作成したチャネルの設定ページに移動します。
Webhook URLとして、上記で取得したGoogle Apps ScriptのウェブアプリURLを設定します。
Webhookの使用を有効にします。
※Webhookの利用のチェック忘れずに!!
8. テスト
LINEアプリからチャネルにテキストメッセージや画像を送信してみてください。
送信したテキストや画像が正常に解析・保存され、LINEに返信が返ってくることを確認します。
Googleスプレッドシートに解析結果や画像のURLが保存されていることを確認します。