1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GAS】気象庁XMLから地震情報を取得してGoogle Chatに自動通知する方法

Last updated at Posted at 2025-03-14

はじめに

本記事では、Google Apps Script (GAS) を活用し、地震発生時に Google Chat へ自動で安否確認メッセージを送信するシステム を構築する方法を紹介します。
このシステムは、気象庁の地震速報を自動取得し、震度5弱以上の地震が発生した場合に、Google Chat のスペースにメッセージを送信する仕組みになっています。
GAS を使った業務自動化に興味のある方は、ぜひ参考にしてください。

本記事で紹介するシステムは、Google Workspace の有料版を利用していることを前提としています。無料の Google アカウントでは一部の機能が制限される可能性があるため、ご注意ください。

この記事でわかる・できること

  • 気象庁の XML データを取得し、地震情報を抽出する方法
  • Google Apps Script を使って Google Chat に自動通知を送る方法

動作環境・使用するツールや言語

  • OS: 任意 (Windows / macOS / Linux)
  • ツール: Google Apps Script (GAS), Google Chat Webhook
  • 言語: Google Apps Script

地震情報の取得方法

気象庁が公開している気象庁防災情報XMLを利用し、地震の検知および情報取得を行います。

高頻度フィールドの地震火山XMLから、タイトルが「震源・震度に関する情報」のデータを取得し、その中の最大震度によって通知を出すか否かを判定しています。

ソースコード

function sendEQAlert() {
 // constants
 // ネームスペース
 const eqvolxm_uri = 'https://www.data.jma.go.jp/developer/xml/feed/eqvol.xml';
 const w3org05_uri = 'http://www.w3.org/2005/Atom';
 const seismol_uri = 'http://xml.kishou.go.jp/jmaxml1/body/seismology1/';
 const informa_uri = 'http://xml.kishou.go.jp/jmaxml1/informationBasis1/';

 const eqlevel_num = 5; // 通知下限震度
 const diffmin_int = 600000; // 600000ms:10分

 const earthqu_str = '震源・震度に関する情報';

 // 地震火山 XML 関連
 let eqvolxm_conText, eqvolxm_document, eqvolxm_element;
 // 詳細情報 XML 関連
 let vxse53_conText, vxse53_document, vxse53_element;
 // ネームスペース
 let w3org05_ns, seismol_ns, informa_ns;
 // 配列・配列要素
 let entryfd_array = [], entrynd_array = [], entrynd_elem;
 // 文字・数字
 let trigger_date, title_str, urlid_str, eqlevel_str, eqlevel_conv;
 let eqinfo_str, hypoce_str;
 // XML 取得
 eqvolxm_conText = UrlFetchApp.fetch(eqvolxm_uri).getContentText();
 eqvolxm_document = XmlService.parse(eqvolxm_conText);
 eqvolxm_element = eqvolxm_document.getRootElement();
 // entry ノードをすべて entrydf_array 配列に push する
 entrynd_array = eqvolxm_element.getDescendants();
 for(var i in entrynd_array) {
   entrynd_elem = entrynd_array[i].asElement();
   if ( entrynd_elem != null && entrynd_elem.getName() == 'entry') {
       entryfd_array.push(entrynd_elem);
   }
 }
 // xmlns 定義
 w3org05_ns = XmlService.getNamespace(w3org05_uri);
 seismol_ns = XmlService.getNamespace(seismol_uri);
 informa_ns = XmlService.getNamespace(informa_uri);
 
 // トリガー発動時刻取得(ミリ秒)
 trigger_date = new Date().getTime();
 // entry の一つ一つの要素を true になるまで見る
 entryfd_array.some(function(fdElement, j) {
   
   // title と updated を取得
   title_str = fdElement.getChild('title', w3org05_ns).getText();
   updat_date = (new Date(fdElement.getChild('updated',w3org05_ns).getText())).getTime();

    // タイトルが「震源・震度に関する情報」のものを取得する
   if(earthqu_str == title_str){
    if(trigger_date - diffmin_int <= updat_date){
 
       // 詳細情報を取得
       urlid_str = fdElement.getChild('id', w3org05_ns).getText(); 
       vxse53_conText = UrlFetchApp.fetch(urlid_str).getContentText();
       vxse53_document = XmlService.parse(vxse53_conText);
       vxse53_element = vxse53_document.getRootElement();
       // 最大震度取得
       eqlevel_str = vxse53_element.getChild('Body',seismol_ns).getChild('Intensity',seismol_ns)
                   .getChild('Observation',seismol_ns).getChild('MaxInt',seismol_ns).getText();

       //取得した震度を変換する処理
       switch(eqlevel_str){
         case '5-': 
           eqlevel_conv = 5.1; //震度5弱
           break;
         case '5+':
           eqlevel_conv = 5.2; //震度5強
           break;
         case '6-':
           eqlevel_conv = 6.1; //震度6弱
           break;
         case '6+':
           eqlevel_conv = 6.2; //震度6強
           break;
         default:
           eqlevel_conv = eqlevel_str;
       }

       if(eqlevel_conv >= eqlevel_num){
         // 震度が規定値以上なら情報取得
         eqinfo_str = vxse53_element.getChild('Head',informa_ns).getChild('Headline',informa_ns)
                     .getChild('Text',informa_ns).getText(); 
         hypoce_str = vxse53_element.getChild('Body',seismol_ns).getChild('Earthquake',seismol_ns)
                     .getChild('Hypocenter',seismol_ns).getChild('Area',seismol_ns)
                     .getChild('Name',seismol_ns).getText(); 
         
         //チャット送信処理
         try{
           chatSend();
         }catch(e){
           Logger.log(e.message);
         }
         
       }else{
         Logger.log("震度が " + eqlevel_str + " のため処理せず");
       }
     }else{
       // true を返すことで some から抜ける
       return true;
     }
   }

   function chatSend() {
     const webhookUrl = "WebhookのURL";
     const googleformUrl = "GoogleformのURL"; 

     //通知するメッセージ
     const mailMessage ="" + eqinfo_str + "\r\n" + 
      "最高震度: " + eqlevel_str + "\r\n" +
      "震源地: " + hypoce_str + "\r\n\r\n" +
      "以下の回答フォームから、安否状況を報告してください。(報告期限:1時間以内)\r\n" + googleformUrl;
    
     const data = {
     'text': mailMessage
     };
     const options = {
       'method': 'post',
       'headers' : {
         'Content-Type': 'application/json; charset=UTF-8'
       },
       'payload': JSON.stringify(data)
     };
     // Webhook URL に POST
     const response = UrlFetchApp.fetch(webhookUrl, options);
     // レスポンスをログ出力
     Logger.log(response.getContentText());
   }
 });
}

コードの解説は省きますが、WebhookのURL、GoogleフォームのURLを変更すればコード自体は完成します。


Webhook URLの取得方法については、こちらの記事などを参考にして下さい。

GAS のトリガー設定

トリガーを以下のように設定することで、10分間隔でコードを実行するようになります。

image.png

通知メッセージ例

Chatに送信されるメッセージは以下のようになります。
(震度5弱は「5-」、5強は「5+」のように表示されます。)

jisin.png

おわりに・まとめ

本記事では、Google Apps Script を用いて気象庁の地震速報を取得し、Google Chat に自動通知するシステムの作り方を紹介しました。
このシステムを活用することで、迅速な情報共有と安否確認を行うことが可能になります。ぜひ、業務の効率化や防災対策に役立ててみてください!

参考資料

ソースコードの参考にした記事:

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?