任意の条件でホテルの空室が発生したら通知するプログラムを作りました

はじめに

7月半ばのことでした。岩手県出身なので、久しぶりに盛岡さんさ踊り(2023年8月1日~4日)を見に行きたいと思いました。

しかしながら、盛岡さんさ踊りは、コロナ禍を経て、4年ぶりの通常開催であり、またニューヨークタイムズ紙「2023年に行くべき52カ所」に盛岡市が選ばれたこともあり、近隣のホテルの空室がありません。しかも、電車移動で盛岡市に行けるエリアのホテルにも空室がありません。

そこで、任意のホテルに空室が出たときに通知を得られるWebサービス(宿の空き待ち)を見つけたのですが(2023年8月23日現在、停止しているようです)、このWebサービスはホテル名の指定が必要です。今回のように宿泊地域を指定したいときには活用できません。

作ったもの(プログラム名:空室ぽよ)

  • Google Apps Script(GAS)において、1時間に1回実行されるプログラム
    • 楽天トラベル空室検索APIにより任意のクエリで空室状況を問い合わせ、空室があればメールを送信するJavaScript(gs)コード
    • 上記コードを1時間に1回実行するトリガ設定

このプログラムによって、ホテルの空室があるとき以下のメールが届きます。

空室があるとき実際に届く通知メール

書いたコード

GAS上で実行させるコードを用意します。コード内の手順1~4を説明します。

【手順1】
自分宛にGmailを送信する関数を作ります。
GASのGmail送信メソッドGmailApp.sendEmailを使います。
初回の実行のみ、Gmailを送信する権限を与えるようポップアップが出るので、画面にしたがって許可します。

【手順2】
楽天ウェブサービスにアプリケーション登録をしてアプリケーションIDを取得します。
楽天ウェブサービスのアプリケーションIDを取得する方法は、Web上に多くの情報があるので、ここでは記載しません。

【手順3】
入力パラメータにより、検索条件を指定します。
今回であれば、下記の検索条件としました。
checkinDate=2023-08-04
checkoutDate=2023-08-06
largeClassCode=japan
middleClassCode=iwate
smallClassCode=morioka
adultNum=2

【手順4】
楽天トラベル空室検索APIでは、「シングル」、「ツイン」あるいは「ダブル」といった部屋タイプの指定ができません。
そのため、出力パラメータにより得られる部屋名称(roomName)に部屋タイプの文字列が含まれているかを判断することとしました。

function sendMail(str) {  //手順1
  const recipient = '自分のGmailアドレス';
  const subject = '空室ぽよ';
 
  const body = '空室ぽよ。\n\n' + str
 
  const options = {
     from: '自分のGmailアドレス',
     name: 'ぽよさん'
     };  
 
  GmailApp.sendEmail(recipient, subject, body, options);
 
}

function fetchVacantHotels() {
  const uri = 'https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?applicationId=取得したアプリケーションID&format=json&checkinDate=2023-08-04&checkoutDate=2023-08-06&largeClassCode=japan&middleClassCode=iwate&smallClassCode=morioka&adultNum=2'
  //手順2、手順3
  
  const options = {
    "method": 'get',
    //'headers': headers,
    "muteHttpExceptions" : true,
    "validateHttpsCertificates" : false,
    "followRedirects" : false,
  }

  try {
    const response = UrlFetchApp.fetch(uri, options)
    const res = JSON.parse(response);
    var str = ''
    var twinNum = 0
    
    res.hotels.forEach((hotel) => {
      var hotelName = ''
      var hotelInformationUrl = ''

      hotel.hotel.forEach((info) => {
        if('hotelBasicInfo' in info) {
          hotelName = info.hotelBasicInfo.hotelName
          hotelInformationUrl = info.hotelBasicInfo.hotelInformationUrl

        } else {
          info.roomInfo.forEach((roomBasicInfo) => {
            if('roomBasicInfo' in roomBasicInfo) {
              var roomName = roomBasicInfo.roomBasicInfo.roomName
              var reserveUrl = roomBasicInfo.roomBasicInfo.reserveUrl

              if(roomName.indexOf('ツイン') != -1) {  //手順4
                twinNum++
                str += 'hotelName: ' + hotelName + '\n'
                    + 'hotelInformationUrl: ' + hotelInformationUrl + '\n'
                    + 'roomName: ' + roomName + '\n'
                    + 'reserveUrl: ' + reserveUrl + '\n\n'

              }

            }
          })
        }
      })
    })

    if(twinNum > 0) {
      sendMail(str)
    }

  } catch(e) {
    // 例外エラー処理
    Logger.log('Error:')
    Logger.log(e)
  }
}

function myFunction() {
  var str = fetchVacantHotels()
  
}

設定したトリガ

前節で書いたコードをGASで1時間に1回実行するトリガを設定します。

GASの画面の左にあるメニュー内の目覚まし時計マーク(トリガー)をクリックし、用意したコードおよび実行間隔を指定します。

作ったプログラムは役に立ったのか

このプログラム「空室ぽよ」は、たいへん役に立ちました!!

盛岡市菜園のホテルニューカリーナの大きめの部屋に泊まりました。
部屋が広いと浴衣に着替えやすくていいですね。
しかし、全館空調だったので、室温を調整できなくて少し暑かったです(フロントに電話しました)。

浮かれポンチ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です