前提できなかったのですが、調べて実行した内容を記載しておきます。
やりたかったこと
ユーザーに直接入力はさせたくなかったが、GASで列追加やデータ更新などの操作はできる状態を作りたい。
そのためにOAuth2.0での認証で操作させたいと考えました。
Googleの認証種類はこちらを参考
https://cloud.google.com/docs/authentication#strategies
Oath認証とアクセストークンの取得
OAuth2 for Apps Scriptというライブラリを使用して認証していきます。
https://github.com/googleworkspace/apps-script-oauth2
1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF
をライブラリのIDに入れてOAuth2
を使用できるようにします。
続いてこちらのコードで認証部分を作成してきいます。
https://github.com/googleworkspace/apps-script-oauth2#1-create-the-oauth2-service
ファイルから呼んだ方が良いと思いますが、テスト実施で終わったので直接入力していました。
const PRIVATE_KEY= '';
const CLIENT_ID = '';
const CLIENT_EMAIL= '';
/**
* Configures the spreadsheet service.
*/
function getSpreasheetService() {
return OAuth2.createService("spreadsheet")
.setTokenUrl("https://accounts.google.com/o/oauth2/token")
.setClientId(CLIENT_ID)
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
.setPropertyStore(PropertiesService.getScriptProperties())
.setScope("https://www.googleapis.com/auth/spreadsheets");
}
これでアクセストークンを取得するためには下記で実行可能です。
const service = getSpreasheetService();
service.getAccessToken();
Sheets API(v4)でデータの取得
下記の情報を参考に実施コードを作成します。
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get
function getSheet(){
const spreadsheetId= '';
const service = getSpreasheetService();
const range = 'シート1!A1:C2';
const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}`;
const res = UrlFetchApp.fetch(url,{
method: 'GET',
headers:{
"Authorization": 'Bearer ' + service.getAccessToken(),
'content-type':'application/json'
}
});
console.log(res.getContentText());
}
この内容で実行すると、ユーザーに権限がなくて、
サービスアカウントに権限付与したスプレッドシートのデータは取得できました。
Sheets API(v4)でデータの更新
batchUpdateでの更新方法を記載します。
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate
function updateSheet(){
const spreadsheetId= '12lQMoI5_YNmwhtcVvb248NBrwyfqRlq-OgLL6iu5KaU';
const service = getSpreasheetService();
const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values:batchUpdate`;
const body = {
"valueInputOption": "USER_ENTERED",
"data": [
{
"range": "シート1!A1",
"values": [
[1, 2, 3]
],
}
],
};
const res = UrlFetchApp.fetch(url,{
'method': 'POST',
'headers': {
"Authorization": 'Bearer ' + service.getAccessToken(),
},
'payload': JSON.stringify(body),
'contentType': 'application/json',
"muteHttpExceptions" : true,
});
console.log(res.getContentText());
}
うまくいくとレスポンスとして下記が返ってきます。
{
"spreadsheetId": "1E3wJW0MhAqe-gSumMekcsVegw3c9**********",
"totalUpdatedRows": 1,
"totalUpdatedColumns": 3,
"totalUpdatedCells": 3,
"totalUpdatedSheets": 1,
"responses": [
{
"spreadsheetId": "1E3wJW0MhAqe-gSumMekcsVegw3c9**********",
"updatedRange": "'シート1'!A1:C1",
"updatedRows": 1,
"updatedColumns": 3,
"updatedCells": 3
}
]
}
payloadって今までよくわかっていなかった(公式サイトちゃんと呼んでなかった)けど
リクエストのbodyのことなんですね。
contentTypeはbodyの形式を指定するってことかな?
JSON.stringify()
でテキストにしないとエラーになったのと、
JSONにしたときにcontentType
でタイプを指定しないと実行ができなかったです。
GASのリクエストの理解も深まってよかった。