Slackに天気予報を流したかっただけなんだ

## 2019/8/14 追記
現在、台風情報などに対応するためコードを修正中です。
しばしお待ちください m(._.)m

以下のものは、修正前のコードになります。
通常の天候の場合は正しく動きますが、
災害等が発生している場合は正しくデータ出力ができません。

# TL;DL
最近、個人開発のメモ用にSlackを使っていて、
「あれ、時報的に天気予報流れてきたら便利じゃね？」
と思って自力でゴチャゴチャ頑張った記録です。

# Motivation
- Slackに天気予報を流したい。
- 常時起動しているサーバーがあるので`cron`を使って定期的にSlackに投稿したい。
- 普段「[Yahoo! 天気][1]」を見ているので、その情報をSlackに流したい。
- あと、シェルの勉強。

# 仕組み
1. 「[Yahoo! 天気][1]」から情報を取ってくる
2. シェルスクリプトで出力を整える
3. Slackへ投稿

これを`cron`で定期的に実行させます。
~~もっと楽な方法があるとか言わない~~

# 実装
## 「[Yahoo! 天気][1]」から情報を取ってくる〜シェルスクリプトで出力を整える
@arabian9tsさんの「[Linuxコマンドで天気予報を取得&表示するワンライン(on Mac)][2]」を参考に。

まず、天気予報を取ってくるURLを探します。
[Yahoo! パーソナル天気][3]にアクセスし、郵便番号を入力。
例えば、京都府京都市下京区なら「〒600-8216」なので
URLは https://weather.yahoo.co.jp/weather/26/6110/26106.html となりました。

んで、私が作ったシェルスクリプトは次の通り。
~~かなり汚くなってしまった気がする~~

```shell:Kyoto.sh
#!/bin/bash

function txt_edit(){
    array=()
    for i in `seq 9`
    do
        array+=(`awk "NR==$i" tmp$1.txt`)
    done
    echo -e ${array[*]} >> data.txt
    sed -e '1,9d' tmp$1.txt > tmp`expr $1 \+ 1`.txt
}

url=https://weather.yahoo.co.jp/weather/26/6110/26106.html #ここを、さっきのURLにする

curl -s $url | sed -e 's/<[^>]*>//g' | grep -v '^\s*$' > tmp.txt

head -n 1 tmp.txt > weather.txt
sed -e '1,33d' tmp.txt > tmp0.txt

head -n 3 tmp0.txt > weather.txt
sed -e '1,3d' tmp0.txt > tmp1.txt 

for i in `seq 5`
do
    txt_edit $i
done

array=()
array2=("--")
for i in `seq 1 2 17`
do
    array+=(`awk "NR==$i" tmp6.txt`)
    j=`expr $i \+ 1`
    array2+=(`awk "NR==$j" tmp6.txt`)
done
echo -e ${array2[*]} >> data.txt
echo -e ${array[*]} >> data.txt
sed -e '1,17d' tmp6.txt > tmp7.txt

N=$(head -n 1 data.txt | wc -w)
for i in `seq 1 $N`
do
    awk '{print $'$i'}' < data.txt | tr '\n' '\t' >> weather.txt
    echo >> weather.txt
done

head -n 4 tmp7.txt >> weather.txt
echo $url >> weather.txt

rm tmp*
rm data.txt
```

ざっくりと、スクリプトの中身としては

1. URLから情報をごっそり取ってくる
2. 必要な情報を取りやすいように下整形 → tmp.txt
3. 行を指定して、文字列情報をいい感じに配列へ入れていく → data.txt　　※一時ファイルはtmp(番号).txt
4. data.txtのままだと見ずらいので、行と列を入れ替え（転置）して最終ファイルへ → weather.txt
5. いらなくなったファイルを削除。

転置は http://kenbell.hatenablog.com/entry/20130604/1370308018 を参考にしました。

ターミナルで

```Terminal
$ chmod +x Kyoto.sh
$ ./Kyoto.sh
```

ちなみに、出力は

```weather.txt
2019年8月3日　18時00分発表
今日の天気
 - 8月3日(土)
時刻    天気    気温（℃）       湿度（％）      降水量（mm）    --      風向風速（m/s） 
0時     晴れ    30      72      0       北東    1       
3時     晴れ    29      74      0       静穏    0       
6時     晴れ    28      76      0       北東    2       
9時     晴れ    31      64      0       南西    2       
12時    晴れ    35      48      0       東      2       
15時    晴れ    37      38      0       東      3       
18時    晴れ    34      51      0       南東    3       
21時    晴れ    30      73      0       北西    1       
        京都市の警報・注意報                            
                        注意報
                        大雨、雷
京都市下京区の今の天気はどうですか?
https://weather.yahoo.co.jp/weather/26/6110/26106.html
```

Slackに流す時にTabが崩れるので、インデントずれとか縦がずれてるのとかは気にしない！

## Slackに流す
@ik-fibさんの「[SlackのIncoming Webhooksを使い倒す][4]」あたりを参考に。

curlのURLと、その他オプションは適宜変更。

```shell:Slack_weather.sh
#!/bin/bash
if [ $# != 0 ] ; then
    numLine=1
    cat $1 | while read line
    do
        #echo $numLine: $line # 出力
        numLine=$((numLine + 1)) # 行数を1増やす
        
        str=$line
        curl -X POST --data-urlencode "payload={\"channel\": \"#general\", \"username\": \"Weather bot\", \"text\": \"$str\", \"icon_emoji\": \":robot_face:\"}" https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX
    done
else
    echo ERROR: Please input argument.
fi
```
http://sweng.web.fc2.com/ja/program/bash/read-each-line.html をちょびっと参考にしました。

ターミナルで

```Terminal
$ chmod +x Slack_weather.sh
$ ./Slack_weather.sh weather.txt
```

とすると、Slackに送信されて、、、
![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198686/a34982f6-0b5d-57eb-07ec-a80eafbc884e.png)

## `cron`で定期実行

`cron`を使えば、朝昼晩でも1時間毎でも1分毎でもなんでもいけますね！

# お疲れ様でした & 反省会

- 「何行目から何行目」で情報を整理しているので、Yahoo側で仕様が変わると怖い。
- というか力技感、、、
- 警報・注意報あたりが場合によってはうまく出力されないかも？
- Slackに送信するとき、1行ごとに通知がいってしまう（今回のだと、一気に16通知くらい）。

もっともっと精進ですね。
綺麗でエレガントなプログラムを書けるようになりたい、、、

「こうするともっと良くなる！」などなどあれば教えていただければと思います！



[1]:https://weather.yahoo.co.jp/weather/
[2]:https://qiita.com/arabian9ts/items/6d4c0f3ede699598ce75
[3]:https://weather.yahoo.co.jp/weather/personal/
[4]:https://qiita.com/ik-fib/items/b4a502d173a22b3947a0