時間割botについて

#はじめに
2018年8月に時間割botという学生向けサービスを公開しました。この記事では、その時間割botの機能やシステムについて解説していこうと思います。

友達追加はこちら
<a href="https://line.me/R/ti/p/%40ywg0561x"><img height="36" border="0" alt="友だち追加" src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png"></a>
#時間割botとは
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">時間割bot <a href="https://t.co/ukfr7sbr3d">pic.twitter.com/ukfr7sbr3d</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1077007534701985793?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- 事前に時間割を登録しておくと、今日の時間割・明日の時間割といったボタンを押すだけで時間割を確認することが出来ます。
- 時間割共有機能というものもあり、共有IDというものを発行することで、自分の時間割を友達等と共有出来ます。
- 天気予報や電車運行状況を確認できる機能もついており、地域、路線を登録するとその路線の運行状況、その地域の天気予報が確認できます。
- 毎日ユーザー指定の時間に時間割をプッシュ通知する機能や、毎朝6:00、6:10にその日の天気予報、運行状況をプッシュ通知する機能もあります。
- ~~友達追加数760人（2018/12/25現在）友達追加数964人（2019/3/8現在）~~
- 友達追加数2457人（2020/08/01現在）

###900人超の友達はどこから来たの？
おそらく口コミだと思います。
最初は僕の高校の友達に広めただけだったので、追加数は100人前後でした。そこからどんどん拡散されてここまで広がりました。
#時間割登録
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">時間割登録 <a href="https://t.co/gLlOApuQpq">pic.twitter.com/gLlOApuQpq</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1077015567901503488?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- 最初に、LIFFを使って時間割を登録してもらいます。~~LIFFはHerokuを使って動かしています。（時間割botは以前GASで動かしていたため、LIFFだけHerokuで作っていました。その名残で、いまだにLIFFだけHerokuを使っています。）~~
- LIFFはS3に移行しました
- 時間割bot自体はAWSLambdaとDynamoDBを使用しているため、入力された時間割のデータを、LIFFからLambdaにPOSTで投げて、LambdaからDynamoDBに登録しています。（AWSのSDKは外部からの使い方がよくわからなかったのでこのような形をとりましたw）

```js
//LIFFからajaxでLambdaへ
$.ajax({
    url: 'LambdaのURL',
    dataType: "json",
    method: 'post',
    data: '入力された時間割のデータ'
})
```

#時間割送信
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">時間割送信 <a href="https://t.co/ADcl4Laglo">pic.twitter.com/ADcl4Laglo</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1077078503789477888?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
- リッチメニューの時間割ボタンが押されると、今日の時間割・明日の時間割・曜日指定・全曜日の時間割を選択できるFlexMessageを返します。
- 最初はクイックリプライにしていたのですが、iOSでリッチメニューからクイックリプライが表示出来ない不具合（現在は修正済み）や、FlexMessageはPC版のLINEでも見られるがクイックリプライは見られないなどの理由により、FlexMessageを使用することにしました。
- ボタンテンプレートなどはPCから見られない（はず）なので、お使いの方はFlexMessageに切り替えることをお勧めします。下にjsonを貼っておきます。
- 内部の処理は、「ボタンが押される」→「Lambdaに飛ぶ」→「userIdをキーにしてDynamoDBに登録してあるその人の時間割を読みにいく」→「曜日にあった時間割を返信する」という流れになっています。

```json:時間割選択ボタン
{
    "type": "bubble",
    "body": {
        "type": "box",
        "layout": "vertical",
        "contents": [{
            "type": "text",
            "text": "選択してください",
            "weight": "bold",
            "size": "md"
        }]
    },
    "footer": {
        "type": "box",
        "layout": "vertical",
        "spacing": "sm",
        "contents": [{
            "type": "button",
            "style": "primary",
            "height": "md",
            "action": {
                "type": "postback",
                "label": "今日の時間割",
                "data": "今日の時間割"
            }
        },
        {
            "type": "button",
            "style": "primary",
            "height": "md",
            "action": {
                "type": "postback",
                "label": "明日の時間割",
                "data": "明日の時間割"
            }
        },
        {
            "type": "button",
            "style": "primary",
            "height": "md",
            "action": {
                "type": "postback",
                "label": "曜日指定",
                "data": "曜日指定"
            }
        },
        {
            "type": "button",
            "style": "primary",
            "height": "md",
            "action": {
                "type": "postback",
                "label": "全曜日",
                "data": "全曜日"
            }
        },
        {
            "type": "spacer",
            "size": "sm"
        }
        ],
        "flex": 0
    }
}
```

#時間割共有

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">時間割共有 <a href="https://t.co/ZraoXyINof">pic.twitter.com/ZraoXyINof</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1077092145490579456?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
- 自分が登録した時間割を友人やグループと共有することが出来ます。
- 時間割登録時に共有IDというものを発行しており、その人の時間割と紐付けてDBに登録しています。
- あたかも時間割共有ボタンを押した際に発行しているように見えますが、実は登録時に発行していますw
- 他の人が発行した共有IDを、自分のアカウントやグループから時間割botに送信すると、LIFFから時間割を入力しなくても、発行元の人と同じ時間割を登録することが出来ます。
- 共有IDは、[JavaScriptでユニークな文字列をさくっと生成する](https://qiita.com/coa00/items/679b0b5c7c468698d53f)を参考に生成したものの末尾に、「hftd32」という文字列をくっつけたものになっています。（共有IDに共通の文字列を付けたかっただけで、hftd32には何の意味もありませんw）

#時間割お知らせ機能
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">時間割お知らせ機能 <a href="https://t.co/ixtf8K0Z4h">pic.twitter.com/ixtf8K0Z4h</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1077098413710168064?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
- 毎日定時に時間割をプッシュ通知する機能です。通知時間はユーザーが指定出来ます。（00分単位で、12:30など半端な時間は登録できないようになっています。）
- 午前中は当日の時間割、午後は翌日の時間割を送信するようにしています。
- 時間登録には日時選択アクションを使用しています。
- プッシュ通知は以下のようなシステムになっています
    - ~~まず、GASであらかじめ01:00から23:00まで一時間単位でLambdaにPOSTを送るトリガーを設定しておきます。~~
    - CloudWatchのcronを使用するように変更しました
    - Lambda側は~~POST~~cronが飛んできたら```new Date()```で何時かを取得し、15:00だったら15:00に配信登録している人のデータをDBから取得して、PUSHメッセージで時間割を送信するという処理を行なっています。

#電車運行状況
<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">電車運行状況 <a href="https://t.co/r41ouQGcSQ">pic.twitter.com/r41ouQGcSQ</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1077110574624862208?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
- 事前に路線を登録しておくと、その路線の運行状況が確認出来ます。また、毎朝6:10に運行状況をプッシュ通知します。
- プッシュ通知の仕組みは時間割お知らせ機能とほとんど同じで、~~GASのトリガー機能~~CloudWatchのcronを使用してLambdaを叩いています。
- 電車運行状況は[鉄道遅延情報のjson](https://rti-giken.jp/fhc/api/train_tetsudo/)から取得しています。
ちなみに、取得できるJSONは以下のような形になっています

```json
[{
	"name": "豊肥本線",
	"company": "JR九州",
	"lastupdate_gmt": 1545668705,
	"source": "鉄道com RSS"
}, {
	"name": "日田彦山線",
	"company": "JR九州",
	"lastupdate_gmt": 1545668705,
	"source": "鉄道com RSS"
}, {
	"name": "筑豊本線",
	"company": "JR九州",
	"lastupdate_gmt": 1545668705,
	"source": "鉄道com RSS"
}, {
	"name": "関西本線",
	"company": "JR東海",
	"lastupdate_gmt": 1545668729,
	"source": "鉄道com RSS"
}, {
	"name": "井川線",
	"company": "大井川鐵道",
	"lastupdate_gmt": 1545667327,
	"source": "鉄道com RSS"
}, {
	"name": "芸備線",
	"company": "JR西日本",
	"lastupdate_gmt": 1545668708,
	"source": "鉄道com RSS"
}, {
	"name": "呉線",
	"company": "JR西日本",
	"lastupdate_gmt": 1545668708,
	"source": "鉄道com RSS"
}, {
	"name": "福塩線",
	"company": "JR西日本",
	"lastupdate_gmt": 1545668708,
	"source": "鉄道com RSS"
}]
```

#天気予報

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">天気予報 <a href="https://t.co/CiMNE2wYGQ">pic.twitter.com/CiMNE2wYGQ</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1077240700985499648?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
- 事前に郵便番号を登録しておくと、その地域の天気予報を確認出来ます。また、毎朝6:00に天気をプッシュ通知します。
- プッシュ通知の仕組みは時間割お知らせ機能とほとんど同じで、~~GASのトリガー機能~~CloudWatchのcronを使用してLambdaを叩いています。
- 天気予報は[OpenWeatherMap](https://openweathermap.org/)のAPIを使用しています。OpenWeatherMapAPIを使用したbotの作り方は、[GASを使って天気予報botを作ってみよう！](https://qiita.com/shinbunbun_/items/23e2100abbe0fcd0274c)に書いているので、興味がある方は是非！

#その他の情報
###DynamoDBのキャパシティー

|   | 読み込み | 書き込み |
|:-:|:-:|:-:|
| テーブル | 1 | 1 |
| index1 | 1 | 1 |
| index2 | 1 | 1 |
| 合計 | 3 | 3 |



#最後に
まだまだ発展途上のサービスではありますが、ゆくゆくは1000人以上の方に使っていただけるサービスにしていきたいと思っています！下のボタンから友達追加できるので、興味がある方は是非使ってみてください！
<a href="https://line.me/R/ti/p/%40ywg0561x"><img height="36" border="0" alt="友だち追加" src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png"></a>
また、質問や、「ここのシステムこうした方が良いんじゃない？」などの意見、アドバイスがあれば、お気軽に下のコメント欄までお願いします！
#Twitter
https://twitter.com/shinbunbun_