長崎県民の為に！ディズニーのお勧めアトラクションを教えてくれるLINEBotを作ってみた！

##長崎県民に、ディズニーのお勧めアトラクションを伝えたい！！
私は、長崎県出身で、東京に上京してきて13年目。
東京にきて、ビックリした事の一つに、東京都民は、ディズニーランド、ディズニーシーのアトラクション事に妙に詳しいこと。
平然と、ビックサンダーマウンテン、センターオブジアース、スプラッシュマウンテン、タワーオブテラーなど言われるが、田舎者の私には、全然分からなかった事を今でも覚えております。
旅行できた地元の友達達からもよくディズニーのお勧めの場所やアトラクション、宿泊先など、よく聞かれます。そんな友達達の為に、今回ディズニーリゾートのお勧めのアトラクションを教えてくれるLINEBotを作ってみました！

##作成した仕組み
ディズニーリゾートのお勧めアトラクションを教えてくれるLINEBot

##開発環境
・LINE公式アカウント開設
・LINE Developersアカウント登録
・Visual Studio Code
・ngrok
・LINE Bot


##共通テンプレート
テンプレートをもとに作成しました！

<details><summary>サンプルコード　<font color="Red">**(クリックで表示)**</font></summary><div><br><br>

```js
'use strict';

// ########################################
//               初期設定など
// ########################################

// パッケージを使用します
const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');

// ローカル（自分のPC）でサーバーを公開するときのポート番号です
const PORT = process.env.PORT || 3000;

// Messaging APIで利用するクレデンシャル（秘匿情報）です。
const config = {
    channelSecret: '作成したBotのチャネルシークレット',
    channelAccessToken: '作成したBotのチャネルアクセストークン'
};



// ########## ▼▼▼ サンプル関数 ▼▼▼ ##########
（この行をサンプル関数丸ごと全部と置き換えてね）
// ########## ▲▲▲ サンプル関数 ▲▲▲ ##########



// ########################################
//  LINEサーバーからのWebhookデータを処理する部分
// ########################################

// LINE SDKを初期化します
const client = new line.Client(config);

// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されます
async function handleEvent(event) {
    // 受信したWebhookが「テキストメッセージ以外」であればnullを返すことで無視します
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    // サンプル関数を実行します
    return sampleFunction(event);
}



// ########################################
//          Expressによるサーバー部分
// ########################################

// expressを初期化します
const app = express();

// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をします
app.post('/webhook', line.middleware(config), (req, res) => {
  
  // 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行
  if (req.body.events.length === 0) {
    res.send('Hello LINE BOT! (HTTP POST)'); // LINEサーバーに返答します（なくてもよい）
    console.log('検証イベントを受信しました！'); // ターミナルに表示します
    return; // これより下は実行されません
  } else {
    // 通常のメッセージなど … Webhookの中身を確認用にターミナルに表示します
    console.log('受信しました:', req.body.events);
  }

  // あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、
  // 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返します
  Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});

// 最初に決めたポート番号でサーバーをPC内だけに公開します
// （環境によってはローカルネットワーク内にも公開されます）
app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);

```
</div></details>
##お勧めのアトラクションを教えてくれるAPI
「おすすめは？」と聞くと、おすすめのアトラクションをランダムに答えてくれます。
「遊びに行きたい」や「アトラクション何がいいかな」など、ある特定の単語を含むメッセージには乗り気ですが、それ以外は適当な相槌を返します。

<details><summary>サンプルコード　<font color="Red">**(クリックで表示)**</font></summary><div><br><br>

```js
const sampleFunction = async (event) => {
    const userText = event.message.text;
    let replyText = '';

    // 部分一致1（「遊」という文字が1ヶ所でも含まれていたら反応）
    if (userText.indexOf('遊') > -1) {
        replyText = 'ディズニーリゾートへ行きましょう！';
    }

    // 部分一致2（「アトラクション」という単語が1ヶ所でも含まれていたら反応）
    if (userText.indexOf('アトラクション') > -1) {
        replyText = 'アトラクションのことでしたら、ぜひ「おすすめは？」と聞いてみてください！';
    }

    // 完全一致したらランダムに返信
    if (userText === 'おすすめは？') {
        // アイスの配列
        const attractions = ['ビッグサンダー・マウンテン', 'センター・オブ・ジ・アース', 'スペース・マウンテン', 'エレクトリック・レールウェイ', 'スプラッシュマウンテン', 'インディ・ジョーンズ・アドベンチャー', 'カリブの海賊', 'スポンサーラウンジ'];
        // アイスの種類数
        const att_count = attractions.length;
        // 乱数（0以上1未満の小数）* 種類数 をして小数以下切り捨て
        const index = Math.floor(Math.random() * att_count);
        // インデックスを指定して特定のアイスを示す文字列を取り出す
        replyText = '「' + attractions[index] + '」がおすすめです🎢';
    }

    // この時点でどの条件にも引っかかってない（replyTextが空文字列のまま）なら相槌をうっておく
    if (replyText === '') {
        replyText = 'そうですね〜';
    }

    return client.replyMessage(event.replyToken, {
        type: 'text',
        text: replyText
    });
};

```
</div></details>

##今回出来なかったこと
企画案までは、出来たのですが、実機で試すまでが出来ませんでした。
また、お勧めのアトラクションまでしか制作する事が出来ませんでした。
次回は、宿泊施設やお勧めの場所も教えてくれるLINEBotを制作したいと考えております。

##これまでの成果物
■CodePen
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">マスクチェッカ―！<br>連携させるのが難しい！汗<br>何とかできたが、まだまだ、、（；^ω^）<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/Java?src=hash&amp;ref_src=twsrc%5Etfw">#Java</a> <a href="https://twitter.com/hashtag/nodered?src=hash&amp;ref_src=twsrc%5Etfw">#nodered</a> <a href="https://twitter.com/hashtag/lINEBot?src=hash&amp;ref_src=twsrc%5Etfw">#lINEBot</a> <a href="https://t.co/CTLz8P2BJF">pic.twitter.com/CTLz8P2BJF</a></p>&mdash; YE0905 (@EgashiraYosuke) <a href="https://twitter.com/EgashiraYosuke/status/1424708162624516096?ref_src=twsrc%5Etfw">August 9, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

■LINE Botへ配信
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">LINE Botと連携<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/h2hDdoTrjp">pic.twitter.com/h2hDdoTrjp</a></p>&mdash; YE0905 (@EgashiraYosuke) <a href="https://twitter.com/EgashiraYosuke/status/1424709466159665159?ref_src=twsrc%5Etfw">August 9, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


■ドメイン検索LINEBot
![プロトアウトスタジオ②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/b1c4a960-7300-1114-cdcb-bcd738817089.png)
![プロトアウトスタジオ①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/a6c182e0-3e7e-e0ab-1708-ba7ffe2a3161.png)

#動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <br>中々苦戦してますが、日々成長出来て嬉しい！<br>今週も頑張るぞ！ <a href="https://t.co/qJ6RF5mrA5">pic.twitter.com/qJ6RF5mrA5</a></p>&mdash; YE0905 (@EgashiraYosuke) <a href="https://twitter.com/EgashiraYosuke/status/1422126078378737665?ref_src=twsrc%5Etfw">August 2, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>