GASとSlack botでドコモ「コミュニティサイクル」の未返却問題を解決する

初記事です。
私はNTTドコモグループのドコモバイクシェアが提供する「コミュニティサイクル」サービスを愛用しており、毎日通勤に使っているのですが、返却まわりのエラーによって利用料金を余計に払ってしまうという事態に悩まされていたので、GASとSlack botを使って解決したいと思います。

# ドコモバイクシェアとは
NTTドコモが提供するコミュニティサイクルサービスです。
会員登録することで特定のサイクルポートで借りることができ、サイクルポートがあるところならどこでも乗り捨てできます。
横浜市、勝沼市等でサービス提供している他、東京都では複数の区をまたいだ乗り捨てモデルの実証実験をしています。

# 未返却問題とは？
上記のようにとても便利なドコモバイクシェアですが、一つだけ欠点があります。

** 返し忘れた場合に気づきづらい **

ということです。
具体的には、返却手続きとして、
「自転車を施錠する」
→「返却ポートの電波内に入る」
→「返却ボタンを押し、返却を確認する」
という手順を踏むのですが、

- ポートにて返却処理をしたつもりでも、通信状況等や管理端末との距離次第では返却できてない

ことがあり、

- それに気づく手段が「返却完了メールの不達を確認する」しかない

ために次回使用しようと思ったときに「貸出中」であることに気づき、長期延滞料金(100円/30分)を払うことになる、という自体が発生するという問題です。

# どうやって未返却を判断するか？
現在(2017年1月時点)、ドコモバイクシェアは管理機能のAPI等を公開していないので、自転車の貸出状況の把握手段が原始的な方法に限られてしまいます。

ドコモバイクシェアは以下の「施錠確認通知」「返却完了通知」2つのメールで利用ステータスを通知してくれます。

1. 施錠確認通知:自転車のロックを掛けたときに通知される。
2. 返却完了通知:自転車のロックを掛けた状態で返却ボタンを押し、返却ステータスになった瞬間に通知される

の2つです。
したがって、1.「施錠確認通知」が来ているのに2.「返却完了通知」が来ていなければ返却がうまく行っていないことになります。
(これに加えて利用開始ステータスをメールしてくれればもっときちんと判別できるのですが…)

すなわち、この手段で判断できる利用ステータスは「施錠」したうえで「返却」されているか/いないかです。

| |判断できるステータス|
|:-----------------|:-------------:|
|A 施錠しており、<br>返却している|◯|
|B 施錠しているが、<br>返却できていない|◯|
|C 施錠しておらず、<br>返却もできていない|×|

※もちろん、ドコモバイクシェアのユーザ管理画面の「利用中」の文字列をスクレイピングすればよりCも含めた細かい判断ができるのですが、アクセスが過度に集中しているので、今回はその方法は取っていません。

# 実装方法
GASを使って以上のルールでSlack botを実装していきます。

## ドコモバイクシェアのアカウントをGmailで登録する
ドコモバイクシェアのアカウントをGmailに登録して、通知メールをGmailで読めるようにします。
もちろん他のメールアドレスからの自動転送でも問題ありません。

## SlackのWebhookURLを取得
割愛します。
[今日の予定をまとめて教えてくれるslackの秘書BOT](http://qiita.com/seya128/items/028274fc014af37f7931)を参照してWebhookURLを発行しましょう。

## GASスクリプト登録
GASスクリプトは下記の内容を登録します。
停車時に施錠することもありうるので、アラートまでの時間は30分としました。

```javascript:sharecycle.gs
function cyclecheck() {

//Gmailを取得し、施錠からの時間を計算する
  var Today = new Date();
  var Searchwords = '(from: community_cycle_info@docomo-cycle.jp AND 
  ("【CycleShare】返却完了" OR "【CycleShare】施錠確認通知") )';
 
  var MailThreads = GmailApp.search(Searchwords, 0, 1);
  var Massages = GmailApp.getMessagesForThreads(MailThreads);
  var Title = Massages[0][0].getSubject();
  var Timestamps = Massages[0][0].getDate();
  var Period = (Today - Timestamps)/60/1000;
  var Result;
  
//最後に届いたメールが「施錠確認通知」で受信から30分以上経っていたらアラート
  if (Title.match(/施錠確認通知/) && Period > 30){
  Result = 1;} else if (Title.match(/返却完了/)){
  Result = 0;} else {
  Result = 0;}
  return Result;
}

//Slackに結果を送信するスクリプト
function slacksending() {

//発行したWebhookURLを記載する
  var slackUrl = "https://hooks.slack.com/services/xxxx/xxxx/xxxx";
 
  var payload = {"text": "自転車が返却されていません"}
 
  UrlFetchApp.fetch(slackUrl, {
      method: "POST",
      payload: JSON.stringify(payload)
  });
}

//アラート対象のメールであればSlackにアラートを送信する
function cycle_alert() {
  if(cyclecheck() == 1){
  slacksending();}
}
```

## トリガーを設定する
一定期間ごとに起動するようにGoogle Apps Scriptのトリガーを設定します。GASエディタのメニューバーにある時計のマークからトリガーを設定しましょう。
30分で設定していますが、もっとこまめにアラートして費用を抑えたい人は短くしても良いと思います。

![トリガーコマンド.JPG](https://qiita-image-store.s3.amazonaws.com/0/160845/12b76cd0-b885-0f8f-b406-5345e8cef1ab.jpeg)
![トリガー.JPG](https://qiita-image-store.s3.amazonaws.com/0/160845/07c56cef-01c0-3235-8c93-14b7321d471e.jpeg)


以上で完成です。
あとはパソコンやスマホにSlackアプリをインストールして、プッシュ通知されるような環境を整えましょう。

## まとめと課題
ということで、現在の状況で可能な限りのアラートを作成しました。
ただし、
- 施錠を忘れるとアラートされない
- アラートしたところで、どこにあるかわからない場合もある

という事態が起こるとお手上げになってしまうので、思いつき次第対策して行きたいと思います。

## 参考
今日の予定をまとめて教えてくれるslackの秘書BOT
http://qiita.com/seya128/items/028274fc014af37f7931