35
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

この暑さを何とかしてくれるBotを作る!!!

Posted at

この記事はリンク情報システム(Facebookはこちら)が主催する真夏のアドベントカレンダー「2019 Tech Connect Summer」のリレー記事です。engineer.hanzomon のグループメンバによってリレーされます。

ついに「2019 Tech Connect Summer」も最終日!!
:bear:クマさんチームの最終日は、@r-kanai が担当致します:bear:

最近暑いですね~

な~んてのんきなことを言ってられないくらい、
毎日が暑すぎる:sun_with_face::dizzy_face::sun_with_face:

通勤とお昼休みしか外に出ないけど、
滝のように汗をかく日々:sweat_drops::sweat_drops::sweat_drops:

『お願いだから、この暑さなんとかして!!』

と(心の中で)何度も叫んでいるけれど、誰も助けてくれないので、
自分で暑さを何とかしてくれるBotでも作ってみようかしら。(唐突)

暑さを何とかしてくれる「涼しくなるBot」

できることは2つ。

1. 今居るところの気温と体感温度がわかる。

 今どんだけ暑いかを知りたいので、
 気象情報を取得できるAPIを利用して、現在地の気温と体感温度を表示する。

2. 涼しくなる方法を提案してくれる。

 涼しくなる方法なんて山ほどあるので、今回は「体感温度」を下げるものに絞る。
 今回は提案する方法は、
 『涼しい画像を見る』
 『涼しい音を聞く』
 の2つにします。
 (画像を見たり、聞いたりするだけでも人間って体感温度が下がるらしい。)

どうやって作る?

  • Bot →  LINEMessagingAPI(LINEBot) (公式
  • サーバー → googleAppsScript (公式
  • 気象情報の取得 → DarkSky (公式

★処理の概要は以下の通り

  1. ユーザーが位置情報を送信

  2. 位置情報をセットしてDarkSkyAPIを実行

  3. DarkSkyAPIの戻り値から体感温度(currently.apparentTemperature)と気温(currently.temperature)を取得し、botに表示

  4. LINEのFlexMessageを利用し、涼しくなる方法をボタンで表示

  5. 選択されたボタンによってそれぞれのコンテンツを表示

    • 『涼しい画像を見る』を選択 → GoogleDriveに保存してある画像を表示する。
    • 『涼しい音を聞く』を選択 → 予め探しておいたYoutubeの動画URLを表示する。

準備

  • LINEDevelopers と GoogleAppsScript(GAS)の登録
    (参考にした記事はこちら

  • Dark Sky の登録
    (参考にした記事はこちら

実装

cool.gs

/** LINE関連情報 */
var LINE_ACCESS_TOKEN = '**LINEBotのアクセストークン**';
var LINE_REPLY_URL = 'https://api.line.me/v2/bot/message/reply';

/** DarkSky関連情報 */
var DARK_SKY_URL = 'https://api.darksky.net/forecast/**DarkSkyのsercretKey**/';

/**
 * ユーザーがBotに対してアクションした時の処理
 * @param {object} e 
 */
function doPost(e) {
  var events = JSON.parse(e.postData.contents).events;
  events.forEach(function(event) {
    if(event.type === 'message') {
      // メッセージの返信
      replyMessage(event);
    } else if (event.type === 'postback') {
      var data = JSON.parse(event.postback.data);
      if (data.action === 'next') {
        if (data.res === 'img') {
          // 涼しい画像の返信
          replyCoolImg(event);
        } else if (data.res === 'sound') {
          // 涼しい音の返信
          replyCoolSound(event);
        }
      }
    }
  });
};

/**
 * メッセージの返信
 * @param {object} e 
 */
var replyMessage = function (e) {
  var replyToken = e.replyToken;
  var lat = e.message.latitude;
  var lon = e.message.longitude;

  // DarkSkyAPIの実行
  var weatherURL = DARK_SKY_URL + lat + ',' + lon + '?lang=ja';
  var json = UrlFetchApp.fetch(weatherURL).getContentText();
  var jsonData = JSON.parse(json);

  // 気温情報の取得・変換
  var AppTemp = changeTemp(jsonData.currently.apparentTemperature);
  var AirTemp = changeTemp(jsonData.currently.temperature);
  
  // 体感気温と気温表示の設定
  var tempMsg = {
    type: 'text',
    text: '体感温度は' + AppTemp + "℃だよ。\n気温は" + AirTemp + "℃だよ。"
  }

  // 「涼しくなる方法」の提案表示の設定
  var coolMsg = {
    type: "flex",
    altText: "This is cool msg.",
    contents: {
      "type": "bubble",
      "styles": {
        "body": {
          "backgroundColor": "#000080"
        }
      },
      "header": {
        "type": "box",
        "layout": "vertical",
        "contents": [
          {
            "type": "text",
            "text": "どうやって涼しくなる?"
          }
        ]
      },
      "body": {
        "type": "box",
        "layout": "vertical",
        "spacing": "md",
        "contents": [
          {
            "type": "button",
            "style": "primary",
            "color": "#66ccff",
            "action": {
              "type": "postback",
              "label": "涼しい画像を見る",
              "data": "{\"action\":\"next\", \"res\":\"img\"}"
            }
          },
          {
            "type": "button",
            "style": "primary",
            "color": "#66ccff",
            "action": {
              "type": "postback",
              "label": "涼しい音を聞く",
              "data": "{\"action\":\"next\", \"res\":\"sound\"}"
            }
          }
        ]
      }
    }
  };
  
  // ユーザに返信
  UrlFetchApp.fetch(url, {
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
      Authorization: 'Bearer ' + ACCESS_TOKEN
    },
    method: 'post',
    payload: JSON.stringify({
      replyToken: replyToken,
      messages: [
        {tempMsg},
        {coolMsg}
      ]
    })
  });  
};

/**
 * 華氏温度から摂氏温度変換
 * @param {number} fTemp 華氏温度
 * @return {number} 摂氏に変換した温度
 */
var changeTemp = function(fTemp) {
  var cTemp = (5/9) * (fTemp - 32);
  var fixedCTemp = cTemp.toFixed(1);
  return fixedCTemp;
}

/**
 * 涼しい画像の返信
 * @param {object} e 
 */
var replyCoolImg = function(e) {
  var replyToken = e.replyToken;
  var imageURL = 'https://drive.google.com/uc?id=**googleDrive内の画像ID**';
  var imagePreURL = 'https://drive.google.com/uc?id=**googleDrive内の画像ID**';
  
  UrlFetchApp.fetch(url, {
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
      Authorization: 'Bearer ' + ACCESS_TOKEN
    },
    method: 'post',
    payload: JSON.stringify({
      replyToken: replyToken,
      messages: [
        {
          type: 'image',
          originalContentUrl: imageURL,
          previewImageUrl: imagePreURL
        }
      ]
    })
  }); 
};

/**
 * 涼しい音の返信
 * @param {object} e 
 */
var replyCoolSound = function(e) {
  var replyToken = e.replyToken;
  var soundURL = 'https://youtu.be/ZJVSjhYwQpE';
  
  UrlFetchApp.fetch(url, {
      headers: {
          'Content-Type': 'application/json; charset=UTF-8',
          Authorization: 'Bearer ' + ACCESS_TOKEN
      },
      method: 'post',
      payload: JSON.stringify({
          replyToken: replyToken,
          messages: [
            {
              type: 'text',
              text: soundURL
            }
          ]
      })
    }); 
};

完成した「涼しくなるBot」

(bot1.png

位置情報を送るとすぐに体感温度と気温を教えてくれる。
(体感温度がほぼ40℃は暑すぎる:joy:

そして、涼しくなる方法を提案。

『涼しい画像を見る』をクリックすると、
bot2.png
涼しげなかき氷の画像が表示:shaved_ice:

『涼しい音を聞く』をクリックすると、
図4.png
風鈴の音が聞けるYoutubeのURLを表示:wind_chime:

このBotをもっと良くする為に

今回は体感的に涼しくなる方法のみ提案するBotを作ってみたけど、
結局のところ、物理的に涼しくならないとダメ!!

実用性を考えると選択肢としてこういうものも追加したい。
「涼しい場所に避難する」→ 近くの涼しい場所(図書館・美術館)を表示してくれる。
「冷たい食べ物を食べる」→ 近くのアイスクリーム・かき氷屋さんを表示してくれる。
...etc

アイディアが膨らむ:balloon:

作ってみて

GASを使って、LineBotを作るのはとても簡単!!
(オウム返しのBotを作るのに準備含めて30分もかからなかった。)

LINEBotだと作ったBotを他の人に手軽に見せることができるのがいいなぁと感じます。
(自分が作ったものは自慢したいタイプ:stuck_out_tongue:

改善の余地がたくさんあるので、少しずつ改修していきます:fist_tone1:

最後に

前回に引き続き、アドベントカレンダー2回目の参加でした。

業務以外でプログラミングをしようしようと思っても、
なかなかしないできない私にとって、こういう機会はとてもありがたいです:grinning:

同じ会社の人でも中々技術について話すことは少ないので、
**「この人こういうことできるんだ!」**とか、
**「この人こういうことに興味だあるんだ!!」**とか、
アドカレを通じて知ることができるのはいいなぁと思いました:sunglasses:

何より毎日更新される記事を読むのが楽しかったです!!

35
17
1

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
35
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?