Tech系サービスやガジェットの使い心地、自分の作業環境、資産運用について気が向いたときに記録を残しています。

記事内のAmazonアソシエイト適格販売及び、Google Adsenseでお小遣いを得ています。

Withingsの体組成計を買って、GASでSlackの減量チャンネルにポストする

f:id:gensobunya:20191108222621j:plain
withings

ものぐさレコーディングダイエット

減量できたことないけど、いろんな事を記録して可視化するのはいいこと。
そして、体重の崩壊を防ぐ仲間内Slackでは、このようにpostした体重と体脂肪率をグラフ化してくれるスクリプトがすでに動いています。

f:id:gensobunya:20191108222638p:plain
weight graph

f:id:gensobunya:20191108222655p:plain
fatrate graph

postしたusernameを自動的に取得して、それぞれの人の記録をトレンド含め表示してくれています。
今までは、愛用していたTANITAの体組成計から手動でメモしていたのですが、いかんせん朝にメモ作業するのは結構面倒。目も疲れるし。

そこで、Wi-Fi対応の体組成計を購入して、乗ったら自動的にSlackに体重と体脂肪率を飛ばすシステムを作りました。
白羽の矢がたった機種がこちら。

体重の計測は200g刻みと、21世紀の体重計とは思えない精度ですが計測結果が100g程度変動していたところで一喜一憂するものでもなし、インターネット直結という点を重視しました。

とりあえずIFTTT

計測した内容はWithings Health MateというWEBサービスにアップロードされ、モバイルアプリでも閲覧できます。
本体の設定はすべてモバイルアプリ経由なので楽ちん。このサービス自体がIFTTTに対応しているので、まずは直接IFTTTを使ってSlackに連携してみます。

f:id:gensobunya:20191108222807p:plain
ifttt to slack

骨量や筋肉量、水分量も計測できるのですがAPIで取得できるのは「体重」「前回体重差」「体脂肪量」「前回体脂肪量差」「体脂肪率」「計測日時」の6点のみでした。
こちらのIFTTTアプレットの起動結果がこちら。

f:id:gensobunya:20191108222822p:plain
slack post

連携はできましたが、一つ思い出してください。

postしたusernameを自動的に取得して、それぞれの人の記録をトレンド含め表示してくれています。

IFTTTのbotアカウントがpostするだけだとグラフ化の方のbotが正常に動いてくれません。自分のアカウントがpostしたことにしないと…
ちなみにコードを書かなくてもMyfitnessPal経由でGARMIN CONNECTやSTRAVAに体重を連携できるので単体でも結構便利です。

Slack APIを直接叩こう

Slack APIの仕様によると、chat.postMessageas_userオプションをtrueにしてPOSTすればいいようです
IFTTTのオプションにはないので直接何かしらのスクリプトを起動することにします。

f:id:gensobunya:20191108222834p:plain
overview

どこで実行するかが問題ですが、データの受け皿を用意しつつ無料でスクリプトを動かせるとなると、やっぱりGoogle SpreadSheetとApps Scriptがシンプルで簡単です。 tokenの取得やアプリの登録に関しては割愛します。

一回、IFTTTでスプレッドシートにデータを飛ばしてカラムを確認した後に以下のスクリプトを、編集をトリガーに設定して実行します。 Date,Weight,Weight w/o fat,Fat weight,Fat Percentの順に4カラムIFTTTで入力しています。

function getLatestWeightData(){
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const lastRawNum = sheet.getLastRow();
  const dataRange = sheet.getRange(lastRawNum, 1, 1, 5) //Date,Weight,Weight w/o fat,Fat weight,Fat Percent
  const postData = {
    "weightKg": dataRange.getValues()[0][1], 
    "fatPercent": dataRange.getValues()[0][4]
  }
  Logger.log(postData)
  return postData
}


function postMeasureDataToSlack() {
  //Get latest row data
  const data = getLatestWeightData();
  const postMessage = data.weightKg+"kg "+data.fatPercent+"%";
    
  //POST to Slack channel
  const baseURL = "https://slack.com/api/chat.postMessage";
  const postData = {
    "channel": "<your channel name>",
    "as_user": true,
    "text": postMessage
  };
  const options = {
    "method": "post",
    "contentType": "application/json; charset=utf-8",
    "headers":{
      "Authorization": "Bearer <!!your access token!!>"
    },
    "payload": JSON.stringify(postData)
  }
  
  const response = UrlFetchApp.fetch(baseURL, options);
  Logger.log(response)
  return
}

Slackグループの設定がありませんが、トークンがグループごとに発行されるのでそこで認識されています。
"as_user": trueを設定したので、あたかも自分が発言したかのようにチャンネルにポストされます。

f:id:gensobunya:20191108222850p:plain
users post

仲間内で牽制し合うコミュニティではIFTTTよりこちらのほうがより便利かと思います。
他にも自動で有給連絡したり、as_userオプションの使い道は結構ありそうですね。

アプリ連携体重計だとその後の広がりがあまり良くないのですが、WEBサービスだと連携も簡単です。タニタオムロンも、WEBサービス連携する体重計は結構高いので1万円程度で買えるWithingsはかなりコスパ良い買い物でした。