GASで自動通知ツールを開発した時のメモ


GASを使って、GoogleSpreadSheet、Gmail、Chatwork を連携した自動通知ツールを作成した時の備忘録です。
一瞬、IFTTTで何とかなりそうと思いましたが、スクレイピング的なことをする必要があったのでGASを挟みました。
(GASのトリガーがcron的なことをやってくれて最高!

処理概要

  • 一定時間ごとに、Gmailに受信したメールの内容を分析、GoogleSpreadSheetに記載されたChatoworkアカウントおよびroom_idを参照し、それに対して通知を送信、タスクを追加する

メモ

スクリプトロック

スクリプトをロックし、多重実行を回避する

var lock = LockService.getScriptLock();

スクリプトのロック状況を確認し、後続の処理を実行する

  • ロックされている場合は、指定ミリ秒後にタイムアウト
if (lock.tryLock(1000)) // 引数はタイムアウトするまでの秒数
{
    // 処理を実行
    exec();

    // ロック解除
    lock.releaseLock();
}
else
{
    // ポップアップを表示
    Browser.msgBox("現在、別の処理が実行中の為、実行できませんでした。\\n\\n時間をおいて、再度実行して下さい。");
}

Gmail連携

Gmailを指定した検索文字列で検索し、スレッドを取得する

// 検索文字列
var search_string = "is:unread ";

var threads = GmailApp.search(search_string, 0, 500);
  • 検索文字列は、Gmailの画面上部の検索ボックスで作成できます

スレッドの内容を確認、既読処理を実行する

for (var i = 0; i < threads.length; i++)
{
    var msgs = GmailApp.getMessagesForThread(threads[i]);

    for (var j = 0; j < msgs.length; j++)
    {
        var tmpBody = msgs[j].getBody();
        Logger.log(tmpBody);

        // スクレイピング的に文字列を取得、使用する処理
        hoge(tmpBody);
    }

    // 既読にする
    threads[i].markRead();
}

汎用

時間取得

  • 時間を取得する
    • タイムゾーン : Asia/Tokyo
    • フォーマット : yyyy/M/d
var endDate = Utilities.formatDate(sheet.getRange('A1').getValue(), 'Asia/Tokyo', 'yyyy/M/d');

指定範囲の最終入力行を取得

var lastRowNumRangeAA = sheet.getRange('A:A').getValues().filter(String).length;

指定範囲の値を取得し配列化

var values = sheet.getRange('A1:A1000').getValues();
values = Array.prototype.concat.apply([],values);

チャットワークAPI実行

タスク化

var CHATWORK_API_TOKEN = "hogehoge";

// 期限は現在日時
var limit = Math.floor( (new Date()).getTime() / 1000 ) ;
// 期限タイプ(none, date, time)
var limit_type = "time";

var method = "post";
var room_id = 11111111;
var body = encodeURI("メールを確認して下さい。\n※期限 : " + endDate + "まで※");
var to_ids = user_ids;
var url = "https://api.chatwork.com/v2/rooms/"+room_id+"/tasks?body="+body+"&limit="+limit+"&limit_type="+limit_type+"&to_ids="+to_ids;

execChatworkApi(method, url);

function execChatworkApi(method, url)
{
  var _url = url;
  var _method = method;
  var params = {
    headers : {"X-ChatWorkToken" : CHATWORK_API_TOKEN},
    method : _method
  };
  var strResponse = UrlFetchApp.fetch(_url, params);
  var json = JSON.parse(strResponse.getContentText());
  return json;
}

定期実行の設定

  • Googleスプレッドシート > ツール > スクリプトエディタ > 現在のオブジェクトのトリガー のアイコンをクリック > トリガーを追加

GAS実行アカウントの移行に関して

  • GASの実行対象となるスプレッドシートのオーナー権限を変更する
  • 上記で設定したトリガーの権限を変更することはできない(2020/03/01 現在)
    • トリガーはアカウント単位の設定になる
    • 移行前の設定内容を確認しつつ、移行後のアカウントで設定し直すしかない?

参考

  • つい最近、GASでV8ランタイムを使えるようになったとのことで、次にGASを使うことがあれば、 let とか const を使っていきたい(varは使いたくない)