LoginSignup
4
4

More than 1 year has passed since last update.

GASでサービスアカウントとしてデータ操作する方法

Last updated at Posted at 2021-12-06

前提できなかったのですが、調べて実行した内容を記載しておきます。

やりたかったこと

ユーザーに直接入力はさせたくなかったが、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のリクエストの理解も深まってよかった。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4