【GAS】天気予報をslackに通知する

どんな感じのものかは↓のtweetのスレッドを見てもらえばイメージできると思う。

季節の変わり目ということもあり、日々の気温が気になる。

そうだ、slackに天気や気温を日々通知するようにしよう!と思い立ち、いくつかのサイトを見ながら天気予報をslackに通知するようにしてみた。

// 今日の天気をslackに通知
function weatherForecastToday() {
  var dateType = 0;
  weatherForecast(dateType);
}

// 明日の天気をslackに通知
function weatherForecastTomorrow() {
  var dateType = 1;
  weatherForecast(dateType);
}

function weatherForecast(dateType) {

  var response = UrlFetchApp.fetch("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010"); //URL+cityID
  var json = JSON.parse(response.getContentText());

  var publicTime = json.publicTime //発表時間

  // dateTypeに応じて、今日か明日の天気予報データを取得する
  if(dateType === 0) {
    var forecastData = json.forecasts[0];
  }else{
    var forecastData = json.forecasts[1]; 
  }  
  var date = forecastData.date; // 予報の日付
  var telop = telopMessage(forecastData.telop); //天気(例: 晴れ)

  //気温: 取れないときがあるので制御する
  if(forecastData.temperature.min !== null) {
    var tempMin = forecastData.temperature.min.celsius; // 最低気温
  } else {
    var tempMin = "- "
  }

  if(forecastData.temperature.max !== null) {
    var tempMax = forecastData.temperature.max.celsius; // 最高気温
  } else {
    var tempMax = "- "
  }
  
  if(dateType === 0){
    var dateMessage = ":red_circle: 今日の天気\n"
  }else{
    var dateMessage = ":large_blue_circle: 明日の天気\n"
  }

  // メッセージ文を作成してslackに送信
  var messageBody =  dateMessage + date + "の天気: " + telop + "\n最低気温: " + tempMin + "℃" + " 最高気温: " + tempMax + "℃" + "\n\n発表時間:" + publicTime;
  sendSlackMessage(messageBody);
}

//天気の文字列を見て、絵文字を追加する
function telopMessage(telop) {
  switch (telop) {
    case "晴時々曇":
      return telop = ":sunny:→:cloud: " + telop;
      break;
    case "曇り":
      return telop = ":cloud: " + telop;
      break;
    case "曇時々雨":
      return telop = ":cloud:→:rain_cloud: " + telop;
      break;
    case "晴れ":
      return telop = ":sunny: " + telop;
      break;
    default:
      return telop;
  }
}

function sendSlackMessage(message) {

  var postUrl = 'https://hooks.slack.com/***********'; 
  // postUrl の設定はここを参照した https://qiita.com/chihiro/items/c7b11abc78f5d806c3a8
  var username = '天気bot';  // 通知時に表示されるユーザー名
  var icon = ':mostly_sunny:';  // 通知時に表示されるアイコン
  var jsonData =
  {
     "username" : username,
     "icon_emoji": icon,
     "text" : message
  };
  var payload = JSON.stringify(jsonData);
  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };
  UrlFetchApp.fetch(postUrl, options);
}


最初は 今日の天気を通知する関数と、明日の天気を通知する関数のそれぞれでほぼ同じコードを書いていたのでどちらからも利用できるように別の関数に切り出すなどにチャレンジしてみた。

あとは
– 今日の天気を起床する時間帯に通知
– 明日の天気を就寝前の時間帯に通知
するようにトリガーで設定した。

これで前日との気温差に敏感になって、服装選びも失敗しにくいはずだ。

IF()とIFS()とIF(AND())

IF(): AがBだったら●,そうでなければ▲

if(A=B,"●", "▲")


IFS(): AがBだったら●,AがCだったら▲,BがDだったら■

ifs(A=B,"●",A=C,"▲",B=D,"■")


IF(AND()): AがB かつ BがCだったら ●、そうでなければ▲

IF(AND(A=B, B=C),"●","▲")

どれ使えばいいんだっけ、ってなりかけたのでメモ

スプレッドシートに特定の文字列が出現したらSlackに通知するGoogleAppScript

スプレッドシートで試算などを行っているときに、「いつの間にか数式が壊れてることに気づかずそのまま作業を進めてしまい死…」みたいなことがあるので、防止する仕組みを作ってみることにした。

仕組み

  1. 検算用のセルを用意しておき、数値が合わないときは特定の文字列を出すようにしておく
    • このセルとこのセルの数値は必ず一致するという部分に =if(A1=B1,"OK","NG【要確認】") を仕込んでおく
  2. 特定文字列(ここではNG【要確認】)がスプレッドシート内にあるということは、何かしら問題が起きているということなので、Slackで自分宛てにmentionする
    • 手動で実行だと実行すること自体を忘れてしまうので、GASのトリガーでn分おきにスクリプトを実行する設定をしておくことで自動化する

特定文字列をチェックするスクリプト

function checkCell() {
  // スプレッドシートを指定
  var spreadshseet = SpreadsheetApp.openById('***********')
  var numSheets    = spreadshseet.getNumSheets();

  //チェックする文字列を定義
  var reg = "NG【要確認】";

  loop:
  for(var sheetNo = 0; sheetNo <= numSheets-1; sheetNo++) {
    SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[sheetNo];
    var sheetName = SpreadsheetApp.getActiveSpreadsheet().getSheets()[sheetNo].getSheetName();
    var range = sheet.getDataRange();
    var values = range.getValues();

    for (var i = 0; i < values.length; i++) {
      var row = "";
      for (var j = 0; j < values[i].length; j++) {      
        if (values[i][j]) {    
          row = row + values[i][j];
          if (row.match(new RegExp(reg))) {
            var messageBody = "<@U8LPZ1BBP>" + sheetName + "シートの" + i + "行目でセルの差異チェックがNGになってるよ";
            sendSlackMessage(messageBody);
            break loop;
          }
        }
      }
    }
  }
}

function sendSlackMessage(message) {
  var postUrl = 'https://hooks.slack.com/services/******';
  var username = 'bot';  
  var icon = ':hatching_chick:';  
  var jsonData =
  {
     "username" : username,
     "icon_emoji": icon,
     "text" : message
  };
  var payload = JSON.stringify(jsonData);
  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };
  UrlFetchApp.fetch(postUrl, options);
}

スクリプトのトリガーを設定する

これで10分おきにチェックするようになり、特定文字列を発見したら、Slackに通知してくれるようになった。

GASとSlackの連動は便利だなあ。

参考にしたサイト

スピンバイク買った

去年の夏頃からランニングを始めて割と習慣化できていたのだけど、年初から右膝の痛みが出てしまいランニングが億劫になってしまった。

膝に負担がかからない水泳にするかーと思いプールにいくも、梅雨時期で外出も面倒…。
プールは泳いでる間考え事くらいしかできないし、何往復したかすぐ忘れるしであんまり続かなかった。

こうなりゃ室内で運動できるようにしてやると思い、スピンバイクを注文。

設置から2週間経過したくらいだけど、ほぼ毎日30分以上は乗っている。
ランニングと比べると景色が変わらない単調さがあるが、

  • 膝痛くならない
  • 天候に左右されない
  • ながら運転ができる

ってあたりがメリットだとおもう。
なんとなく気になってたけど未消化だったアニメや映画を見ながら運動できるし、いい感じなのではなかろうか。

minneでtergenさんのdaypackをカスタムオーダーした

オール黒でオーダーした新しいマイバッグ。ああ、大変愛おしい。

最近、MBPとiPadを持ち歩く生活になったこともあって、カバンを新調したい欲が高まり色々物色していたところ、 minneで tergenさんのデイパックを発見。

DAYPACK Camouflage Gray | ハンドメイドマーケット minne

形は最高なのだが、カバンは黒が好みなので「オール黒で作っていただけますか?」と伺ったら、快く対応してくださった。数週間後、無事手元に届いた。

イメージどおりの仕上がりなのと、背中側の独立した収納スペースが本当に便利。

洗濯機を買い換えた BD-SV110C

梅雨だし、今年マンションの大規模修繕予定あるし、乾燥までできるドラム式の洗濯機に買い替え。

同僚が日立推しだったので、BD-SV110C にしてみた。

洗濯乾燥の基本機能とは別に、スチームアイロン機能があってこれが意外と便利だった。

朝来ていくシャツを選んだら洗濯機に放り込んで、ボタンを押して15分くらい待つ。

そうすると、そこそこシワが気にならない状態のシャツが出てくるので意外と重宝する機能だなって思った(生地によっては残念な結果になることもある)。

シューグー 買ってみた

ワンサイズ大きめの靴を履いているせいか、歩き方がおかしいのかわからないけど、踵のすり減りがハイペース(特にオールスター)なので、なんか対策はないのかなとググってたらこのサイトにたどり着き、シューグーってやつがあることを知った。

ということで早速、買ってみた。

すり減った部分の補修だけじゃなく、すり減り防止にも良いとあったので、買って日が浅い靴にも塗ってみた。

効果はいかほどなのかなー。感想はまた後日。

【Googleスプレッドシート】GoogleAppScript (GAS)で参照元のセルにジャンプするショートカットを実現する

Googleスプレッドシートよりエクセルのほうが最高!と思うシーンは僕にとっては1つしかなくて

  • セルの参照元に command + { でジャンプできること

である。

参照元のセルにジャンプしたい、というのはこういうとき

予算管理をエクセルファイルでやってる都合上、参照元のセルにジャンプするショートカットには大変お世話になっていて、Googleスプレッドシートで同等の機能がないことに絶望していた。

ショートカットがないと何が辛いって、参照元のセル位置を見て忘れないように脳内に一時的に情報を保持しつつ目的のセルにたどり着かないといけないことだ。ましてや参照元が別のシートだったりすると発狂しそうだ。

2つのことを同時にやれるほど僕は器用にできてないので、GoogleAppScript を書いてみたら思いの外あっさり実現できた。

function JumpToDefinition() {

  // 現在のスプレッドシートを取得
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  // 現在のシートを取得
  var sheet = spreadsheet.getActiveSheet();
  // 参照元のセルの位置を取得する
  var value = sheet.getCurrentCell().getFormula().replace("=","");
  //該当のセルに移動する
  var objRange = sheet.getRange(value);
  objRange.activate();
}

GoogleAppScript自体はじめてつかったのだけど、見よう見まねで書いてみたらなんとかなるものだなあ。便利便利。

統計検定3級を受けた

去年から数学を学び直しているんだけど、途中で興味があった統計検定を受けた。

高校数学の[データの分析]の講を先に終わらせて、代表値、標準偏差、共分散、相関係数、標準化といった用語に多少慣れ親しんで、統計検定のテキストと過去問を買い、ゴールデンウィークはひたすら問題をとき、5月の中頃に受験した。

試験が終わってそわそわしたくなかったので、その場で合否がわかるCBTにした。
結果は無事合格。正解率は8割超という感じだった。

最初は棒グラフとヒストグラムの違いもわからない状態だったので、普通に勉強になったなー。高校数学を一通り追えたら、2級を受けに行こうと思う。

という感じの進捗。
高校数学はようやく半分といったところ。
先は長いが割と楽しい。

ゴアテックスのオールスターもう一足追加


1年前にグレーのハイカットを買って周囲に絶賛しているゴアテックスのオールスター、梅雨をむかえる前にもう一足購入。

今度はローカット。雨の日のどんよりした気持ちを払拭するような水色にした。