ChatGPT4を使って読みたい本リストを作ってみた
初noteです。
あと、初制作物です。
タイトル通り、
ChatGPT4(利用料 : 20ドル/月)を使って、読みたい本リストを作りました。
読みたい本リストについて
ChatGPT4について
コード
の順に書いていきます。
読みたい本リストについて
なにを作ったのか
本のタイトルをGoogle ToDoリストのタスクに入力すると、Googleスプレッドシートに自動で転記されて、Amazonと早稲田大学図書館の検索リンクも自動で入力されるシステム
設計
GAS*だけで完結させること。
ToDoリストとスプレッドシートを使用する。
ToDoリストは本のタイトルを入力する機能のみ持たせる。
ToDoリストの採用理由は、PCとスマホ両方からのアクセスが簡単なため。
また、Googleカレンダーをメインのタスク管理ツールとして利用しているため、ToDoリストが身近な存在だった。
スプレッドシートの採用理由は、ToDoリストとの連携が簡単なため。
*GASとは
Google Apps Scriptの略
なんかGoogleのアプリの動作をコードで自動化したり、アプリ同士を連携させたり出来る。
JavaScriptで記述する。
https://script.google.com/home
動作
Google ToDoリストのタスク名に本のタイトルを入力すると、
スプレッドシートのA列にタイトルが転記され、
AmazonのKindleURLクエリがB列に記入される。
AmazonのURLクエリがC列に記入される。
早稲田大学図書館のURLクエリがD列に記入される。
また、ToDoリストのタスクの"詳細"にも早稲田大学図書館のURLクエリが記入される。
トリガーはスプレッドシートの起動時に設定している。
ToDoリストへのタスク追加をトリガーに設定することは出来ないみたい。
なぜ作ったのか
気になる本があった時にAmazonで調べて、図書館にあるか検索して、という過程を踏むのが面倒になって自動化したくなった。
どうなったのか
ToDoリストにタイトル入力するだけで良いのめっっっちゃ楽。
これまではAmazonの欲しいものリストに読みたい本を入れていたが、確認するのが非常に面倒だった。
いまは簡単に一覧を確認できるようになって快適。
スプレッドシートを開かないと動作しないけど、即時反映されなくても困らないから別にいいかな〜。
今後の課題
理想としては、Amazonのセール情報を取得したり、図書館の貸出状況を取得したりしたかったが、実装の手間と運用・保守するほどのモチベが無く、諦めた。
ChatGPT4とコーディングについて
筆者のコーディングレベル
コーディング経験は初歩のプログラムを書いたことがあるぐらい。
JSに関しての知識はProgateを一通りやっただけ。
未だにクラスとかよく分かってない…
ChatGPT4はコーディングに使えるのか
使える。
コーディングは全てChatGPTに任せた。
どういった課題があったのか
やり取りを続けていくうちに、コードの修正によって解決した問題が元のコードに戻ることで、再び同じ問題が出現することが一番ストレスだった。
コードをテストする工程も煩雑で大変だった。
この課題はコーディングスキルが無いのも原因だろうけど…
短時間に一定以上のやり取りをすると、回数制限に達してしまうため、数時間待たないといけないことも…
どうクリアしたのか
愚直にトライ&エラー
次やるならどうするか
設計の段階で想定される問題をChatGPTに尋ねたり、また、検討事項の抜け漏れがないかを確認してもらうことで、実装段階のコーディングやテストの工数を短縮できたと思う。
次にプログラムを作るときは、プラグインとかCode interpreterとかも試してみたい。
ChatGPTじゃなくてもGitHub Copilotとかもあるし。
実際のコード
const TASK_LIST_ID = 'YOUR_TASK_LIST_ID';
YOUR_TASK_LIST_IDをGoogleからユニークに割り当てられたTaskListIDに置換。
fetchTasksAndWriteToSheet()
下4つの関数を全て呼び出す。
トリガーの対象に設定する関数。
getTasksFromToDoList()
ToDoリストからタスクを取得。
writeToSheet(tasks)
スプレッドシートにタスクを書き込む。
既存のデータがある場合、重複するデータはスキップされる。
AmazonクエリURLと早稲田図書館のクエリURLを書き込む。
早稲田図書館のクエリURLが必要ない場合は該当する箇所のコードを削除すること。
addWasedaLibraryQueryToTaskDetails()
ToDoリストのタスクの詳細に早稲田図書館のクエリURLを書き込む。
早稲田図書館のクエリURLが必要ない場合はこの関数を削除すること。
transferCompletedTasksToSheet()
完了したタスクがある場合は、todoシートから該当データを削除し、completedシートに該当データを書き込む。
const TASK_LIST_ID = 'YOUR_TASK_LIST_ID'; // タスクリストIDを調べて''の中に入力してください
// トリガー対象の関数です。全ての関数を呼び出します。
function fetchTasksAndWriteToSheet() {
var tasks = getTasksFromToDoList();
writeToSheet(tasks);
addWasedaLibraryQueryToTaskDetails();
transferCompletedTasksToSheet();
}
function getTasksFromToDoList() {
var tasks = [];
var pageToken;
do {
var response = Tasks.Tasks.list(TASK_LIST_ID, {
showCompleted: true,
showHidden: true,
maxResults: 100, // 最大100件を取得
pageToken: pageToken // 次のページのタスクを取得するためのトークン
});
if (response.items) {
tasks = tasks.concat(response.items);
}
pageToken = response.nextPageToken; // 次のページのトークンを取得
} while (pageToken); // nextPageTokenが存在する限りループを続ける
return tasks;
}
function writeToSheet(tasks) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getLastRow();
var data = sheet.getRange(2, 1, lastRow, 4).getValues();
var existingTitlesSet = new Set(data.map(row => row[0])); // 既存のタスクタイトルをSetに変換
var nextEmptyRow = 2;
for (var i = 0; i < data.length; i++) {
if (!data[i][0]) {
nextEmptyRow = i + 2;
break;
}
}
var rowsToWrite = []; // 書き込む行のデータを格納する配列
for (var i = 0; i < tasks.length; i++) {
var task = tasks[i];
var title = task.title;
// タスクが未完了でない場合、スキップ
if (task.status !== "needsAction") {
continue;
}
if (existingTitlesSet.has(title)) {
continue;
}
var amazonKindleQuery = "https://www.amazon.co.jp/s?k=" + encodeURIComponent(title) + "&i=digital-text";
var amazonBookQuery = "https://www.amazon.co.jp/s?k=" + encodeURIComponent(title);
var wasedaLibraryQuery = "https://waseda.primo.exlibrisgroup.com/discovery/search?query=any,contains," + encodeURIComponent(title) + "&tab=Everything&search_scope=MyInst_and_CI&vid=81SOKEI_WUNI:WINE&mfacet=rtype,include,books,1&lang=ja";
rowsToWrite.push([title, amazonKindleQuery, amazonBookQuery, wasedaLibraryQuery]);
}
// 一度に複数の行を書き込む
if (rowsToWrite.length > 0) {
sheet.getRange(nextEmptyRow, 1, rowsToWrite.length, 4).setValues(rowsToWrite);
}
}
function addWasedaLibraryQueryToTaskDetails() {
var pageToken;
do {
var response = Tasks.Tasks.list(TASK_LIST_ID, {
showCompleted: true,
showHidden: true,
maxResults: 100, // 最大100件を取得
pageToken: pageToken // 次のページのタスクを取得するためのトークン
});
if (response.items) {
for (var i = 0; i < response.items.length; i++) {
var task = response.items[i];
var title = task.title;
var wasedaLibraryQuery = "https://waseda.primo.exlibrisgroup.com/discovery/search?query=any,contains," + encodeURIComponent(title) + "&tab=Everything&search_scope=MyInst_and_CI&vid=81SOKEI_WUNI:WINE&mfacet=rtype,include,books,1&lang=ja";
// 既存のnotesにWaseda Libraryのクエリが存在するか確認
if (task.notes && task.notes.includes(wasedaLibraryQuery)) {
continue;
}
// 既存のnotesにクエリを追加
var updatedNotes = task.notes ? task.notes + "\n" + wasedaLibraryQuery : wasedaLibraryQuery;
// タスクのnotesを更新
task.notes = updatedNotes;
Tasks.Tasks.update(task, TASK_LIST_ID, task.id);
}
}
pageToken = response.nextPageToken; // 次のページのトークンを取得
} while (pageToken); // nextPageTokenが存在する限りループを続ける
}
function transferCompletedTasksToSheet() {
var tasks = getTasksFromToDoList();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var todoSheet = spreadsheet.getSheetByName("ToDo"); // ToDoシートを取得
var completedSheet = spreadsheet.getSheetByName("Completed"); // Completedシートを取得
if (!completedSheet) {
Logger.log("Target sheet 'Completed' not found.");
return;
}
var lastRowInCompleted = completedSheet.getLastRow();
var nextEmptyRowInCompleted = lastRowInCompleted + 1;
for (var i = 0; i < tasks.length; i++) {
var task = tasks[i];
if (task.status === "completed") {
// 完了したタスクの行をToDoシートから取得
var finder = todoSheet.createTextFinder(task.title);
var cell = finder.findNext();
// タスクのタイトルが見つかった場合のみ処理を続行
if (cell) {
var rowIndex = cell.getRow();
var dataRange = todoSheet.getRange(rowIndex, 1, 1, todoSheet.getLastColumn());
var dataValues = dataRange.getValues();
// 完了したタスクのデータをCompletedシートにコピー
completedSheet.getRange(nextEmptyRowInCompleted, 1, 1, dataValues[0].length).setValues(dataValues);
// ToDoシートから完了したタスクの行を削除
todoSheet.deleteRow(rowIndex);
nextEmptyRowInCompleted++;
} else {
Logger.log(`Title '${task.title}' not found in ToDo sheet.`);
}
}
}
}
導入手順
Googleスプレッドシートの拡張機能のApps Scriptを選択
コピペする。
タスクリストIDは以下のコードを実行することで、実行ログに表示される。
function getTaskListIds() {
var taskLists = Tasks.Tasklists.list();
if (taskLists.items) {
for (var i = 0; i < taskLists.items.length; i++) {
var taskList = taskLists.items[i];
Logger.log('Task List ID: ' + taskList.id + ' Title: ' + taskList.title);
}
} else {
Logger.log('No task lists found.');
}
}
この記事が気に入ったらサポートをしてみませんか?