endoflife.dateからEOL情報を取得しGoogleスプレッドシートで一覧化する
アノテーション株式会社のあのふじたです。
最近、様々なプロダクトごとのEOL情報をまとめたサイト「endoflife.date」 を知りました。
このサイトのAPIを利用して、EOL情報を取得し、Googleスプレッドシートで一覧化してみたいと思います。
endoflife.date とは
endoflife.date は、様々な製品のEOL日付とサポートライフサイクルを文書化しているサイトです。
API のページ
APIの詳細は以下のリンクから確認できます。
API ドキュメント
現時点では3つのエンドポイントが説明されています。
- Get All Details
- Single cycle details
- All Products
All Products エンドポイントを使うと、全プロダクトの情報が取得できます。
全プロダクト情報
Get All Details は特定のプロダクトの全情報を
Single cycle details は特定のプロダクトの1つのリリースサイクルの情報を取得できます。
スプレッドシートの構成
全てのプロダクト一覧を取得するのは All Products エンドポイントで一発ですが、現在 309 プロダクトをトラックしているようです。必要なプロダクトのみに絞ってEOL情報を取得したいですね。
以下のようなシート構成にします。
- Productsシート: All Productsリクエストで取得したプロダクト一覧を記載
- GetProductsListシート: トラックしたいプロダクトを選別
- EOLシート: GetProductsListシートのプロダクト一覧を元に、Get All Detailsを複数回実行しEOL情報を記載
- Logsシート: 定期実行を前提に実行ログを記載
- Diffシート: 更新があった際の差分を記載
1. プロダクト一覧をシートに記載するスクリプト
まずは All Products へのリクエスト結果をスプレッドシートに記載するGoogle App Scriptを作成します。
拡張機能 > App Script からプロジェクトを立ち上げ、コード.gs を getAllProducts.gs に書き換えて以下のコードを記載します。
function writeToProdutsSheet() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName('Products') || ss.insertSheet('Products'); const url = 'https://endoflife.date/api/all.json'; const options = { 'method': 'GET', 'headers': {'Accept': 'application/json'}, 'muteHttpExceptions': true // 例外をミュートにする }; // データを取得してパースします let response, data; try { response = UrlFetchApp.fetch(url, options); // 正常なレスポンスを確認します if (response.getResponseCode() === 200) { data = JSON.parse(response.getContentText()); // スプレッドシートに書き込む前にデータを加工します const dataArray = data.map((item, index) => [index + 1, item]); // スプレッドシートの A1 セルからデータを書き込みます const range = sheet.getRange(1, 1, dataArray.length, 2); // 行数と列数を指定します range.setValues(dataArray); } else { throw new Error('非正常なレスポンス: ' + response.getResponseCode()); } } catch (error) { Logger.log(error.message); } }
実行を押すとアクセス権限のポップアップがでますが、承認し実行します。
シート[Products] で有効化したいプロダクトのC列に enable を入力しておきます。入力規則で enable を入力しやすくしておくのも良いかと思います。
今回は amazon と aws が含まれたプロダクトのみにします。
2. トラックしたいプロダクトのみに選別するシートの設定
GetProductListシートのA1にquery関数でProductsシートでenableとなった行のみ抽出します。
A1に =query(Products!A1:C500,"select A, B, C where C='enable'")
と入力します。
以下のように抽出されます
- amazon-cdk
- amazon-corretto
- amazon-eks
- amazon-glue
- amazon-linux
- amazon-neptune
- amazon-rds-mysql
- amazon-rds-postgresql
- aws-lambda
3. GetProductListシートからプロダクト一覧を取得し各プロダクトのEOL情報や差分をシートに記載する
EOL情報を記載する GoogleAppScript を作成します。
+をクリックしてスクリプトを追加し、コード.gs を getGetAllDetails.gs に書き換えて以下のコードを記載します。
function writeToEolSheet() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const eol_sheet = ss.getSheetByName('EOL'); const eoldiff_sheet = ss.getSheetByName('Diff') || ss.insertSheet('Diff'); // 差分シートがなければ作成 const logs_sheet = ss.getSheetByName('Logs') || ss.insertSheet('Logs'); // ログシートがなければ作成 const headers = ["Products", "Cycle", "Release Date", "EOL", "Latest", "latestReleaseDate", "LTS", "Support", "Discontinued", "Link"]; // 現在のデータを一時的に保存 const currentDataRange = eol_sheet.getDataRange(); const currentData = currentDataRange.getValues(); // データのみをクリア(フォーマットは保持) eol_sheet.clearContents(); eol_sheet.appendRow(headers); // ヘッダーの追加 const sheet = ss.getSheetByName('GetProductsList'); const nameColumnIndex = 2; const lastRow = sheet.getLastRow(); const productNamesRange = sheet.getRange(1, nameColumnIndex, lastRow - 1); const productNames = productNamesRange.getValues(); // 一括でプロダクト名を取得 const dataToWrite = []; // プロダクト名毎にAPIから情報を取得 productNames.forEach(function(row, index) { const productName = row[0].trim(); if (productName) { // プロダクト名が空でない場合のみ処理 const url = 'https://endoflife.date/api/' + encodeURIComponent(productName) + '.json'; const options = { method: 'get', muteHttpExceptions: true }; try { const response = UrlFetchApp.fetch(url, options); const statusCode = response.getResponseCode(); if (statusCode === 200) { var data = JSON.parse(response.getContentText()); data.forEach(function(entry) { dataToWrite.push([ productName, entry.cycle || '', entry.releaseDate || '', entry.eol || '', entry.latest || '', entry.latestReleaseDate || '', entry.lts || false, entry.support || '', entry.discontinued || '', entry.link || '' ]); }); } else { console.error(`Product ${productName}: Failed to fetch data with status code ${statusCode}`); } } catch (e) { console.error(`Unable to fetch data for ${productName}: ${e}`); } // 待機を挿入(最後のリクエストの後は不要) if (index < productNames.length - 1) { Utilities.sleep(500); } } }); // 一括でデータを書き込む if (dataToWrite.length > 0) { eol_sheet.getRange(eol_sheet.getLastRow() + 1, 1, dataToWrite.length, headers.length).setValues(dataToWrite); } // 差分の計算と出力 const newDataRange = eol_sheet.getDataRange(); const newData = newDataRange.getValues(); const diffData = calculateEolDiff(currentData, newData); if (diffData.length > 0) { eoldiff_sheet.clearContents(); // 差分シートをクリア eoldiff_sheet.getRange(1, 1, diffData.length, diffData[0].length).setValues(diffData); // 差分を出力 // ログシートに実行時間とメッセージを記載 const timestamp = new Date(); const logMessage = `Script executed at ${timestamp.toLocaleString()}: Updates found in EOL sheet.`; logs_sheet.appendRow([logMessage]); } else { // ログシートに実行時間とメッセージを記載 const timestamp = new Date(); const logMessage = `Script executed at ${timestamp.toLocaleString()}: No Updates in EOL sheet.`; logs_sheet.appendRow([logMessage]); } // 列の幅を整列 eol_sheet.autoResizeColumns(1, headers.length); } // 差分を計算する関数 function calculateEolDiff(oldData, newData) { const diff = []; const oldDataStringified = oldData.map(row => JSON.stringify(row)); const newDataStringified = newData.map(row => JSON.stringify(row)); // 新しいデータをチェックし、古いデータに存在しない行を検出 newDataStringified.forEach((newRow, i) => { if (!oldDataStringified.includes(newRow)) { diff.push(['+', ...newData[i]]); // 新規追加された行に "+" を追加 } }); // 古いデータをチェックし、新しいデータに存在しない行を検出 oldDataStringified.forEach((oldRow, i) => { if (!newDataStringified.includes(oldRow)) { diff.push(['-', ...oldData[i]]); // 削除された行に "-" を追加 } }); return diff; }
処理の流れは以下の通りです。
- 現在のEOLシートのデータを一時的に保存
- データのみをクリア(フォーマットは保持)
- GetProductListシートから一括でプロダクト名を取得
- プロダクト名毎にAPIから情報を取得(少し待機を挿入)
- EOLシートに一括でデータを書き込む
- 差分があるか確認し、DiffシートとLogsシートに書き込む
実行後のEOLシートの状況です。
Diffシートは見やすいように条件付き書式A列の+-入力に応じて色を付けると良いでしょう。
まとめ
任意のプロダクトのEOLの一覧ページがざっくりと作成できました。 getGetAllDetails.gs を定期実行し、Slackなどに通知できるようにすれば、利用できる場面もあるのではないでしょうか。
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。
サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。
当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。