これは何?
↑ この投稿の「課題と対策」の課題を解決してみました。
課題
上の記事で「Chrome拡張機能からGASにリクエストを送って情報を取ってくる」ことが可能になりました。しかし、
- 画面が更新されるたびに(正確には
content.js
が実行されるたび)に、GASと通信が発生します - GASから取ってくるデータ量が大きくなると
content.js
の実行完了まで時間がかかってしまいます
という問題が発生します。かつ、GAS側にある情報の更新頻度は低いとします。ですので
- 拡張機能時に一回だけGASから取得して chrome.storage.local に保存する
- 画面更新時には chrome.local.storageから情報を取ってくる
- 1時間に1回、GASから情報をとって chrome.storage.local の情報を更新する
をやってみます。
コードを書いてみた
GASのコード
簡単のため、固定値のJSONを返すだけのGASを作成し、デプロイし、URLを控えておきます。
// 固定値のJSONを返すだけ
function doGet(e){
const res = [{ name: "TARO", age: "17"}, {name: "JIRO", age: "15"}];
const output = ContentService.createTextOutput();
output.setMimeType(ContentService.MimeType.JSON);
output.setContent(JSON.stringify(res));
return output;
}
拡張機能のコード
manifest.json
{
"name": "GASから情報を取ってきて何かする拡張機能",
"version": "1.0",
"manifest_version": 3,
"description": "なにかします",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"alarms",
"storage"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_idle"
}
],
"background": {
"service_worker": "background.js"
}
}
↓ これがポイントっぽい。
"permissions": [
"alarms",
"storage"
],
background.js
// GASからデータを取得し、chrome.storage.local に保存する関数
function fetchDataFromGAS() {
const gasUrl = "https://script.google.com/a/macros/xxxxxxxxx/exec";
fetch(gasUrl)
.then((response) => response.json())
.then((data) => {
chrome.storage.local.set({ gasData: data }, () => {
console.log("GASから取得した情報", data)
});
})
.catch((error) => console.error("fetchでエラー:", error));
}
// 拡張機能が起動した時に実行
chrome.runtime.onInstalled.addListener(() => {
console.log("起動時に実行: chrome.runtime.onInstalled.addListener")
fetchDataFromGAS();
});
// 定期的に実行するためのアラームを設定。ここで更新頻度を調整可能
chrome.alarms.create("fetchData", { periodInMinutes: 60 });
// アラームが鳴った時のリスナーを設定
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === "fetchData") {
fetchDataFromGAS();
}
});
content.js
function main(){
// storageから情報を取る
chrome.storage.local.get("gasData", function (result) {
if (result.gasData) {
console.log("local.storageから取った情報:", result.gasData);
// その情報を使った処理を書く
} else {
console.log("gasData が無いよ");
}
});
}
main()
実行してみる
「Service Worker」のコンソール
うん。想定どおりGASと通信してますね。
content.js のコンソール
こちらでも想定通り local.storage
から取得しています。
これ以降、画面を更新してもGASとの通信は行われず、local.storage
からの情報を取得します。
background.js
の中にある periodInMinutes: 1
にして実験すると、Service Worker のコンソールに1分ごとにログが出力され、定期的にアラームが実行されてGASと通信していることがわかります。
思ったより簡単に実装できました。拡張機能すごい。