【GAS】興味のあるイベント(connpass)がすでに終了していて悔しかったので解決した話

個人メモ+α

参加したかったイベント

 Tokyo GAS on GCPUG 2018 Spring
 https://gcpug-tokyo.connpass.com/event/81041/

原因

・connpassの利用を始めて2か月 気になるグループの洗い出しが終わっていない。
 ※グループに参加していればメールで通知される。
・定期的に確認していなかった。
・人気のあるイベントだったため、気が付いたころには参加者があふれていた。

解決策

・connpassにイベント検索のAPIあるやんけ
 ⇒これで監視できそう???
・GASのイベントだったし、GASで実装して二度と同じ失敗は繰り返さないようにしよう。
・携帯や職場PCで確認できるSlackに通知させよう

実装

ざっくりした実装の流れ
・SlackのToken取得しておく
・GASのSlackライブラリを導入しておく

コード

前準備.gs
//SlackのTokenを設定
//手動で実行しておく
function setSlackToken(){
  PropertiesService.getScriptProperties().setProperty("token ","your_token"); 
}
main.gs
var apiUrl = "https://connpass.com/api/v1/event/?"
var query = ["keyword_or","series_id"]

//メインメソッド(毎日8~9時にトリガーを設定)
//更新がなかった時にはその旨を通知
function main(){
  var updateFlag = false;
  updateFlag = updateFlag || seminarCheck("GAS","GAS,GoogleAppsScript,Google Apps Script",0) ;
  updateFlag = updateFlag || seminarCheck("アイマス","アイマス,IDOLM@STER,アイドルマスター",0) ;
  updateFlag = updateFlag || seminarCheck("GCPUG","1898",1) ;

  Logger.log(updateFlag)
  if(!updateFlag){
    postMessage("本日の更新はありませんでした。")
  }
}

//セミナー更新確認メソッド
//propertyKey:検索キーの識別文字列(てきとうでもいい)
//keyword:実際に検索で使われる文字列「,」区切りで複数条件の検索が可能
//queryNum:query配列の何番目を使うか指定
//
function seminarCheck(propertyKey,keyword,queryNum) {
  //更新フラグ 更新されたらtrueになる
  var updateFlag = false;

  //プロパティから前回の実行結果を取得
  var properties = PropertiesService.getScriptProperties(); 
  var oldListStr = properties.getProperty(propertyKey);

  //APIをたたく
  var url = apiUrl + query[queryNum] + "=" + keyword;
  var response = UrlFetchApp.fetch(url);
  var json = JSON.parse(response.getContentText());

   //初回実行時は空リストと比較 ⇒ 新たに取得したものは全て通知される
  var oldList =[];
  if(oldListStr != null){
    oldList = oldListStr.split(',');
  }

  var eventIdList = [];
  var diffIdList =[];
  json["events"].forEach(function(event){
    var event_id = event["event_id"].toString();
    eventIdList.push(event_id);
    if(oldList.indexOf(event_id) <= -1){
      diffIdList.push(event_id);
    }
  });


  //前回の検索結果に含まれていないタイトルを通知(新規のタイトル)
  //Logger.log(diffIdList)
  if(diffIdList.length > 0){
    postMessage("種別:"+propertyKey+"\r\n検索キーワード:"+keyword+"\r\n")
    //イベントのjson取り出してloop 出力情報を取り出す。
    json["events"].forEach(function(val) {
      var id = val["event_id"].toString();
      if(diffIdList.indexOf(id) >= 0){
        sendSlack(val);
      }
    });

    postMessage("\r\n   \r\n")//インデント
    updateFlag = true;
  }



  /*
  * 今回の取得結果を保存
  */  
  properties.setProperty(propertyKey, eventIdList.toString()); //プロパティは文字列で保存されるため変換

  return updateFlag;
}
slack.gs
//jsonの整形と送信
function sendSlack(json){
  //整形処理  
  var message = "";
  message = message + "title: "+json["title"]+"\r\n";
  message = message + "更新日: "+dateChange(json["updated_at"])+"\r\n";
  message = message + "url: "+json["event_url"]+"\r\n";

  postMessage(message)
}


//メッセージpostメソッド
function postMessage(message) {
  var prop = PropertiesService.getScriptProperties().getProperties();

  //slackApp インスタンスの取得
  var slackApp = SlackApp.create(prop.token);

  //投稿
  slackApp.postMessage(prop.channelId, message, {
    username : "connpass監視BOT"
  });
}

//日時返還
function dateChange(str){
  return Utilities.formatDate(new Date(str), 'Asia/Tokyo', 'yyyy/MM/dd hh:mm');
}

実行イメージ
505d8c2a76f5863df8d8ff8df2b7e723.png

まとめ

次はどんな犠牲を払ってでも参加する。

課題

 ・純粋にキーワード検索を行っているので、物理的に参加が出来ないイベントも通知される。
  ⇒ 女性限定学生限定、九州で開催など
   ⇒イベント会場の位置情報をもとに地方は除外できそう・・・
   ⇒女性限定学生限定などは若干厳しそうなため、要検討
 ・Slackに通知する際のフォーマットがめちゃくちゃダサい
  ⇒ ・検索キーワードがコード上にべた書きなのでスプレッドシートなどのから読み取るように変更させたい。
  ⇒難しくはないので、直近で修正予定。
 ・Slackの通知がえげつないことになる場合あり。
  ⇒更新されたイベントの出力先をスプレッドシートに変更し、
   更新があった旨をSlackに通知させるとか???

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.