📚

[GAS] 実行制限を回避する

2023/07/18に公開

GASは無料で使えて強力ですが、実行時間の制限があり、6分間実行されるとタイムアウトします。これは、長時間実行されるタスクを実行する場合問題となります。今回はそのタイムアウトを回避します。

例として、1日に1度slackのメンバー情報をすべて引っ張ってきて、そのメンバーの詳細なプロフィールを取得しなければならないものとします。それぞれAPIを使いますが、

  1. 全メンバーの情報を取得する
  2. それぞれのメンバーごとに詳細なプロフィールを取得する

の2種類のAPI通信を行わなければならず、2つ目の方はメンバー数だけ行わなければなりません。
ここでは考えやすいようにメンバー数を1000、詳細なプロフィールの取得に1回10秒かかるとします。
すると2時間半以上実行にかかることになり、当然実行制限に抵触します。

解決策

1. メンバーシートにメンバーを反映させる

1つ目のAPI通信を行った後、取得したメンバー情報をspreadsheetのシートに反映させます。
例えば以下のような表とします。

id name status プロフィール
a 田中 未実行
b 佐藤 未実行
c 渡辺 未実行

ここのstatusは固定でこの値です。
1日に1度、0〜1時の間に定期実行されるように設定します。

2. 10分に10件ずつデータを更新する

1で保存したシートから情報を取得します。そしてここから以下条件に合致するデータを更新していきます。

  • ステータスが未実行である

また、10件以上取得した場合は、上から10件に制限します。

処理
function main(){
    // メンバーリストを取得して10件に絞る
    const memberList = getMemberList().slice(0, 10);
    memberList.forEach(member => {
        member.getProfile();
        member.refreshSheet();
    });
}

class Member{
    constructor(id, name, status){
        this.id = id;
        this.name = name;
        this.status = status;
    }

    isYetAPI(){
        return this.status === '未実行';
    }

    getProfile(){
        // API通信を行ってプロフィールを取得する
        this.status = '実行済';
    }

    refreshSheet(){
        // シートAにプロフィール情報とステータスを反映させる
    }
}


function getMemberList(){
    // シートAからメンバー情報を配列で取得する
}

実行すると上からの段々とプロフィールが埋まっていきます。

id name status プロフィール
a 田中 実行済 血液型A
b 佐藤 未実行
c 渡辺 未実行

これを10分に1度定期実行されるように設定します。
実行間隔と、一度に実行する数は気をつけないといけませんが、上の方法で実行制限を回避できます。

Discussion