🐡

超初心者がGASで死活監視するよ。

2022/12/04に公開

始めに

※SEVENRICH GROUPの開発チームDELTAのアドベントカレンダー4日目の記事です。
 よろしければ是非ご購読ください!
https://qiita.com/advent-calendar/2022/delta
「DELTA」の自己紹介↓
https://note.com/delta_sevenrich/n/n15f551a4d7a5

はじめまして。SEVENRICH GROUP、DELTA所属の伊藤静香と申します。
今日は「超初心者がGASで死活監視するよ。」というテーマでお送りしたいので、タイトル通り私がどれだけ初心者かお分かりいただくためにまずは簡単な自己紹介から。

自己紹介

今年4月に入社。DELTA所属で唯一非プログラマ(唯一のアルバイト)
それまでは4年くらいスーパーで魚屋やってたのでIT企業は初です。(キャリアチェンジの角度がえぐい)
プログラマではないので各所のお手伝いがメイン業務。

パソコンは普通に触るけど、動画見たり調べものする程度で、割とスマホで事足りるレベル。
そんな超ハイパー初心者がどうやって死活監視のGASを書いたのか、ゆるく説明していこうかなと思います。

課題

SEVENRICH GROUPではたくさんの事業を持っていて、コーポレートサイトはもとより、各事業のサービスサイトやECサイト、WEB業務システム等、数えきれないほどのサイトを利用しています。
過去に、サイトにアクセスできない・エラーが発生していることに気付くのが遅れた例が複数あり、とりあえず簡単な死活監視でいいならGASで出来るんやないか?という流れです。

正直プログラミング未経験の私がそんなん出来るんかという気持ちでしたが、一回勉強してみたい気持ちもあったのでチャレンジすることに。「こんな感じで出来ると思う。ネットで調べてみても結構記事とかあるし。分からないとこあれば聞いてください~」と設計やおすすめの記事を指南していただいて、勉強をスタートしました。

重宝したキャッチアップ資料

作りたいもの

①スプレッドシートに死活監視したいサイトのURLリストを作る
UrlFetchAppを使って①のURLのHTTPステータスコードを取得する
③ステータスコードが200(正常値)以外だった場合にslackに通知する

実際のslackに来た通知

主に参考にしたサイト

  1. 【無料】Webサイトの監視ツールを作成する方法
    https://moniblo.com/gas-website-monitor
  2. Google Apps ScriptとGoogleスプレッドシートで複数サービスのURL外形監視ツールを作成する
    https://tech.bita.jp/article/20

コード

※こちらは初めてなりにいろんなところから切り貼りして書いたコードとなっています。頑張った形跡として作ったままの実際に動いているコードのため、美しくないとっちらかったコードとなっていますがご容赦ください……。

function kansi() {             
  let spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); //①死活監視したいURLを取得
  let sheet = spreadsheet.getActiveSheet();

  for (var i = 2; i <= sheet.getLastRow(); i++) {
    var url = sheet.getRange(i, 1).getValue();//urlを取得
   url_fetch();               //url_fetchへ
  }

  function url_fetch() {         //②HTTPステータスコードを取得する
    var options = {
      muteHttpExceptions: true
    };
    var response;
    try {
      response = UrlFetchApp.fetch(url, options);//urlをフェッチ
    } catch (e) {
      return;
    }
    var code = response.getResponseCode();    //レスポンスコードを取得
    sheet.getRange(i, 3).setValue(code);     //シートに出力
    console.log('"%s": "%s"', url, code);

    if (code !== 200) {      //コードが200以外の場合slack通知する
      slackNotice();
    }

    function slackNotice() {   //③slackに通知

      var postUrl = 'https://'; //通知先となるSlackチャンネルのIncoming Webhook URL
      var username = 'Webサイト監視中';  // 通知時に表示されるユーザー名
      var icon = ':sos:';  // 通知時に表示されるアイコン

      let jsonData =
      {
        "username": username,
        "icon_emoji": icon,
        "text": "<!channel>" + "\n"
          + "HTTPステータスコード: " + code + "\n\n"
          + "【要確認】Webサイトにエラーが発生している恐れがあります。" + "\n"
          + url
      };
      var payload = JSON.stringify(jsonData);

      var options =
      {
        "method": "post",
        "contentType": "application/json",
        "payload": payload
      };

      UrlFetchApp.fetch(postUrl, options);
    }
  }
}

詳細

シートの内容は以下

  • A列-URL
  • B列-サイト名[=IMPORTXML(A2,"//title")](サイト名を取得する関数)
  • C列-ステータスコード(ここに取得したステータスコードが入力されるようにする)

①死活監視したいURLを取得

  let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = spreadsheet.getActiveSheet();

  for (var i = 2; i <= sheet.getLastRow(); i++) {
    var url = sheet.getRange(i, 1).getValue();//urlを取得
   url_fetch();
  }
  • urlを記載しているシートを取得
  • 1行目は項目を記載のため、for文で2行目から最後の行まで
  • 1列目(A列)のURLを値を取得
  • 次のurl_fetch

②HTTPステータスコードを取得する

  function url_fetch() {
    var options = {
      muteHttpExceptions: true
    };
    var response;
    try {
      response = UrlFetchApp.fetch(url, options);   //urlをフェッチ
    } catch (e) {
      return;
    }
    var code = response.getResponseCode();    //レスポンスコードを取得
    sheet.getRange(i, 3).setValue(code);      //シートに出力
    console.log('"%s": "%s"', url, code);

    if (code !== 200) {      //コードが200以外の場合slack通知する
      slackNotice();
    }
  • ①で取得したURLに対してUrlFetchAppを使用してレスポンスコードを取得
  • シート3列目(C列)に出力
  • レスポンスコードが200以外の場合はslackNotice

③slackに通知

  function slackNotice() {

      var postUrl = 'https://';    //通知先となるSlackチャンネルのIncoming Webhook URL
      var username = 'Webサイト監視中';   // 通知時に表示されるユーザー名
      var icon = ':sos:';      // 通知時に表示されるアイコン

      let jsonData =
      {
        "username": username,
        "icon_emoji": icon,
        "text": "<!channel>" + "\n"
          + "HTTPステータスコード: " + code + "\n\n"
          + "【要確認】Webサイトにエラーが発生している恐れがあります。" + "\n"
          + url
      };
      var payload = JSON.stringify(jsonData);

      var options =
      {
        "method": "post",
        "contentType": "application/json",
        "payload": payload
      };

      UrlFetchApp.fetch(postUrl, options);
    }
  • あらかじめ通知するチャンネルのIncoming Webhook URLを発行しておく
    こちらのnoteを参考にしました。
    https://note.com/skipla/n/na3f7f9cd9b7d
  • 通知する内容を設定
  • UrlFetchAppで設定したチャンネルに通知を飛ばす

コード以外の処理

合わせてやった処理

  • Googleフォームを紐づけて死活監視したいサイトを回答してもらい、URLの追加も自動で出来るようにします。

    今回はQUERY関数を使ってフォームの回答を引っ張ってます。
    (フォームの投稿結果は追記ではなく行追加で入ってくるので、[=シート1!A1]の形では関数が上書きされてしまうため列指定で呼んでいます)

    [=QUERY('フォームの回答'!1:100,"select B")]

  • スプレッドシートは条件付き書式を設定してエラーがどこなのか発見しやすくしました。
    (設定した時点の私にはこれが限界でしたが、今見ると効率的でないことが分かりますね;)

結果

得られたもの

  • サイトが落ちてしまっていないか気にしなくていい安心感(大事)
  • GAS操作の知識
  • スプレッドシートやフォームの知識

個人的に難しかったのは、コードをどうやって繋げていくか。「スプレッドシートから値(URL)を取得する」「URLを指定して死活監視する」「slackに通知する」単一では調べればいくらでも出てきますが、「取得した複数のURLを順番にfetchする」とか「ステータスコードが200以外の時にslackに通知する」などの繋げていく箇所は知識がない状態では簡単ではなかったです。
初めてのGAS、初めてのプログラミングだったため、キャッチアップにはかなり時間を要しましたが、これを通して少し自信がつきました。

最後に

この死活監視を足掛かりに、今ではwebスクレイピングやフォルダ複製のGASなどを使って関わっている事業にすこし貢献できるようになりました。まだまだ分からないことだらけでつまずくこともありますが、お手上げになったら優しい人たちが助けてくれるので、プログラミング超初心者の伊藤はレベル上げ真っ最中です。この記事を読んで超初心者でもプログラミングってなんとかなるもんやなって感じて頂ければ幸いです。

※DELTAでは一緒に助け合える仲間を募集中です!
※DELTAの魅力を知っていただくためにも、是非アドベントカレンダーをご購読ください!
https://qiita.com/advent-calendar/2022/delta

Discussion