Closed6

TypeScript+clasp+Google Apps Script(GAS)で簡易Web APIサーバーを作成しデプロイする

3w36zj63w36zj6

環境構築

任意の場所に新しいフォルダを作成しその中に移動。

claspをnpmで入れる。-gはグローバルインストールのオプション。

https://github.com/google/clasp

npm install -g @google/clasp

使用するアカウントのGoogle Apps Script APIをオンにする。

https://script.google.com/home/usersettings

以下のコマンドでGoogleアカウントへのログインを行う。ログインが完了すると~/.clasprc.jsonにTokenが作成される。

clasp login --no-localhost

npm initpackage.jsonを初期化してGASの型定義をインストールする。TypeScriptについてはclaspが依存しているので追加の作業は不要。

npm init -y
npm install @types/google-apps-script

以下のコマンドでGASアプリケーションを作成する。--rootDir ./src/でソースコードを入れるフォルダを指定。

clasp create --rootDir ./src/

するとこのような選択肢が表示されるので今回はwebappを選ぶ。

? Create which script? 
> standalone
  docs
  sheets
  slides
  forms
  webapp
  api

このような表示が出たら環境構築は完了。

Created new webapp script: https://script.google.com/d/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/edit
Warning: files in subfolder are not accounted for unless you set a '.claspignore' file.
Cloned 1 file.
└─ ./src/appsscript.json

.gitignore.clasp.jsonを追加しておく。

3w36zj63w36zj6

Web APIとして公開

初回

script.google.comでpushしたファイルの編集画面を開く。

右上のデプロイから新しいデプロイを選択。

種類の選択の歯車アイコンからウェブアプリを選択。

次のユーザーとして実行を自分に、アクセスできるユーザーを全員にしてデプロイする。

ウェブアプリのURLが表示される。

2回目以降

appscript.jsonに以下の記述を追加。

appscript.json
{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
-  "runtimeVersion": "V8"
+  "runtimeVersion": "V8",
+  "webapp": {
+    "access": "ANYONE_ANONYMOUS",
+    "executeAs": "USER_DEPLOYING"
+  }
}

以下のコマンドでデプロイの一覧が表示されるので、最新のデプロイIDをコピーする。

clasp deployments

確認したデプロイIDを使って以下のコマンドを実行するとデプロイが更新される。

clasp push
clasp deploy -i <Deploy ID>

URLは更新してもhttps://script.google.com/macros/s/<Deploy ID>/execのまま固定。

https://qiita.com/ume3003/items/cd9d05dff014952a73f8

https://developers.google.com/apps-script/reference

3w36zj63w36zj6

プロジェクトごとにアカウントを切り替える

プロジェクトのルートに.clasprc.jsonを用意し、claspコマンドを実行する際は常に--authオプションでトークンを読み込ませる。

clasp login --auth .clasprc.json

プライベートリポジトリでない場合、.clasprc.json.gitignoreに追加する。

https://zenn.dev/ptna/articles/bc49c1d61f6dd7

以下のようにscriptsを追加しておく。

package.json
{
  "scripts": {
    "login": "clasp login --auth .clasprc.json",
    "push": "clasp push --auth .clasprc.json",
    "deployments": "clasp deployments --auth .clasprc.json",
    "deploy": "clasp deploy -i ${npm_config_id} --auth .clasprc.json"
  }
}
3w36zj63w36zj6

PrettierとESLint

Prettier

npm install -D prettier

.prettierrcを作成して好みに合わせて設定をする。

ESLint

npm install -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-import

.eslintrc.jsを作成して好みに合わせて設定をする。

.eslintrc.js
module.exports = {
  extends: ["eslint:recommended"],
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  parserOptions: {
    ecmaVersion: 2019,
  },
  overrides: [
    {
      files: ["src/**/*.ts"],
      extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
      parser: "@typescript-eslint/parser",
      parserOptions: {
        sourceType: "module",
        project: "./tsconfig.json",
      },
      plugins: ["@typescript-eslint", "import"],
      rules: {
        "import/order": "error",
      },
    },
  ],
}

TSConfig

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2019",
    "strict": true
  },
  "include": ["src/**/*.ts"]
}
3w36zj63w36zj6

GitHub ActionsによるCD

.github/workflows/deploy-to-gas.yml
name: Deploy to Google Apps Script

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: 18
      - name: Install Clasp
        run: npm install
      - name: Create .clasprc.json
        run: |
          echo '{"token":{"access_token":"${{ secrets.ACCESS_TOKEN }}","scope":"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/script.projects https://www.googleapis.com/auth/script.webapp.deploy https://www.googleapis.com/auth/logging.read openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/script.deployments https://www.googleapis.com/auth/service.management https://www.googleapis.com/auth/cloud-platform","token_type":"Bearer","id_token":"${{ secrets.ID_TOKEN }}","expiry_date":1620870307822,"refresh_token":"${{ secrets.REFRESH_TOKEN }}"},"oauth2ClientSettings":{"clientId":"${{ secrets.CLIENT_ID }}","clientSecret":"${{ secrets.CLIENT_SECRET }}","redirectUri":"http://localhost"},"isLocalCreds":false}' > .clasprc.json
      - name: Create .clasp.json
        run: |
          echo '{"scriptId":"${{ secrets.SCRIPT_ID }}","rootDir":"./src"}' > .clasp.json
      - name: Push to Google Apps Script
        run: npm run push
      - name: Deploy to Google Apps Script
        run: npm run deploy -id="${{ secrets.DEPLOY_ID }}"

以下のSecretsを設定しておく。

Name Description
ACCESS_TOKEN .clasprc.jsonaccess_tokenの値
CLIENT_ID .clasprc.jsonclientIdの値
CLIENT_SECRET .clasprc.jsonclientSecretの値
DEPLOY_ID 本番環境のデプロイID
ID_TOKEN .clasprc.jsonid_tokenの値
REFRESH_TOKEN .clasprc.jsonrefresh_tokenの値
SCRIPT_ID .clasp.jsonscriptIdの値
このスクラップは2022/05/26にクローズされました