この記事が古くなってしまったので、Chrome拡張とGASを連携させる例(改) - Qiita を参照してください!(2021/05/18)
【エンジニア交流会】Google Apps Script 活用ミートアップ #4 - connpass
で発表したこれ↓
Google Apps Script 活用ミートアップ#4 発表資料
の中で Chrome拡張とGASで連携させる例 を紹介したのですが、質疑応答のときに「ソースコードが見たい!」というリクエストをもらいました。時間の都合と、懇親会で酔ってたので、改めてこの場で紹介します。
Chrome拡張(エクステンション)とGASを使ってこんなことができるよ、という例です。
活用方法はいろいろあると思うので、いいネタがあったら教えてほしいです!
例題として
「Qiitaを見ていて「この記事いいな」って思ったら、そのタイトルとURLをスプレッドシートに記録しておきたい」
※今回は例として紹介していますので、本来ならQiitaにある「ストック」機能を使ってくださいねw
必要なスキル
- Chrome拡張が作れること
- GASでスプレッドシート操作ができること
- GASで「ウェブアプリケーションとして導入」ができること
処理の流れ
- Chrome拡張で、Qiitaの画面にボタンを挿入する
- ボタンを押したらURLとタイトルをGASに送信する
- GASが doPost()で受け取って、スプレッドシートに書き出す
(追記:190602)
「画面の中にボタンを挿入」しなくても、Browser Action
(Chrome右上のアイコンを押したときに発動するやつ)で実装するほうがより実践的だと思うのですが、特にChrome拡張を知らない人に「こんなこと(画面内に要素を追加できちゃう)ができるのか!」というのを知ってもらうため、わざわざこうしてみました。
GASのコード
今回はスタンドアロンのスクリプトでリクエストを受けて、そこからスプレッドシートに書き込んでいます。
スプレッドシートにバインドされてるスクリプトで受けてもOKです。
function doPost(e) {
// エクステンションから送信されたデータを取り出す
const params = JSON.parse(e.postData.getDataAsString());
const title = params.title;
const url = params.url;
// スプレッドシートの最終行に書き出す
const sheet = SpreadsheetApp.openById('xxxxxxxxxxxxxxx').getSheetByName("xxxxx");
sheet.appendRow([title, url]);
// エクステンションにレスポンスを返す
var output = ContentService.createTextOutput();
output.setMimeType(ContentService.MimeType.JSON);
output.setContent(JSON.stringify( { sucsess: true }));
return output;
}
スクリプトエディタから、
「公開」→「ウェブアプリケーションとして導入」してURLを取得する。
そのURLをエクステンションに記載。
おまけ情報(ログの確認)
GASの中で
console.log("あああ"); // Logger.log() じゃなくて
て書いておくと、ログを Apps Script ダッシュボード
で確認できます。
「表示」→「Stackdriver Logging」から見えます。(現時点では)
Chrome拡張のコード
ファイル構成
JQueryはダウンロードしておいてください。→ Download jQuery
Qiitaで実験
└ content.js
└ jquery-3.4.0.min.js
└ manifest.json
manifest.json
{
"manifest_version":2,
"name":"QiitaのタイトルとURLをスプレッドシートに書き出す君",
"version":"1.0",
"permissions": [
"https://script.google.com/*",
"https://script.googleusercontent.com/*"
],
"content_scripts":[
{
"matches":[
"https://qiita.com/*"
],
"js":[
"jquery-3.4.0.min.js",
"content.js"
]
}
]
}
content.js
↓ 私、最近のJSについていけてないので、書き方おかしかったらゴメンナサイ。
// 「Webアプリケーションとして導入」しているGASのURL
const gasUrl = "https://script.google.com/a/xxxxxxxxxxxxxxxxxx/exec";
$(function() {
// 画面にボタンを挿入する
$('#main').prepend('<input type="button" id="postBtn" value="リストに保存">');
// ボタンがクリックされたときの処理
$('#postBtn').on('click', function() {
const url = location.href;
const title = $('.it-Header_title').text();
post2GAS(url, title);
});
});
function post2GAS(url, title){
const data = {
url: url,
title: title
}
$.ajax({
type: 'POST',
url: gasUrl,
data: JSON.stringify(data)
})
.done( function(data) {
console.log("成功");
})
.fail( function(jqXHR, textStatus, errorThrown) {
console.log("失敗");
console.log("XMLHttpRequest : " + jqXHR.status);
console.log("textStatus : " + textStatus);
console.log("errorThrown : " + errorThrown);
})
.always( (data) => {
console.log("処理終了");
});
}
実行してみる
- エクステンションをインストール
- Qiitaの記事にアクセス
- ボタンを押す
↓ エラーがあったらConsole
に何か出ると思います。
注意点
(というか教えてほしいこと)
Googleのアクセス権限
弊社はG Suiteを導入しているので、自社のGoogleアカウント内で公開しているGASに対して、社内アカウント以外からはアクセスできなくなっています。「ウェブアプリケーションとして導入」のときも「自分だけ」あるいは「社内ドメインの全員」しか選べません。(匿名が選べない)
そのため、Chrome拡張を動かすChromeが、自社アカウントでGoogleログインしていることが必要。
(ここらへん、本当にそうなのか確信が持ててないのだけれど、どなたか情報ありましたら教えてほしい)
(追記:190602)
実験したところ、「Chromeブラウザで、自社アカウントから ログアウト した状態」でボタンを押すと下記のようにエラーになります。つまり「会社のGoogleアカウントを持っていない人がこのエクステンションをインストールしたとしてもGASにはアクセスできない」となります。
CORS対応
"permissions": [
"https://script.google.com/*",
"https://script.googleusercontent.com/*"
],
実験しているうちに上記の2つのURLでエラーが出るパターンがあったのでこれを追加しているのですが、
正直、CORSについて「完全に理解した」とは言えない状態なので何か間違ってたら教えてほしい。
エクステンション機能追加
(追記:190602)
仮にこのエクステンションを他の人に配布すると、利用者全員の「リストに保存する」が、一つのスプレッドシートに書き出されることになります。実用的にするには、エクステンションに「設定画面」を用意して「ユーザーごとに保存先を指定できる」機能をつけるカッコイイと思います。
最後に
今回は「Chrome拡張からGASにPOSTする」でしたが、「Chrome拡張がGAS(スプレッドシートとか)が持っている情報をGETして、それを元にブラウザ上の表示や挙動を制御する」みたいなこともできます。
ブラウザを使ってお仕事している人はいっぱいいると思うので、これを活用したらいろいろ「業務効率化」できるのでは!?