全国の藤井聡太七段ファンに言いたい事がある

##僕は永瀬拓矢七段が好きです:banana:
<img width="600" alt="game-info___japanese-chess-game-schedule-bot_Slack.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/ab208e1e-692e-ef43-30b3-3d4bb89e50c4.jpeg">
いつかこんな日が来ると良いですね:stew:
## 作ったもの :art:
明日の公式戦全対局予定をSlackに通知するBOT(毎日22時に更新:clock10:)
<img width="598" alt="over-all-view.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/81373cbf-a90e-508f-55a4-b39b9b005496.jpeg">

###対局カードによって背景画像を変更 :mountain:

|種類|背景画像|
|:-:|:-:|
|AbemaTVとニコニコ生放送で放送する対局 |<img width="200" alt="niconico_abema.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/e259ef70-202e-a277-3458-ec079e9b46f1.jpeg">|
|AbemaTVで放送する対局|<img width="200" alt="abema.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/254383b7-2434-54ef-2742-32ec60f8188a.jpeg">|
|ニコニコ生放送で放送する対局|<img width="200" alt="niconico.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/fd85e772-8a56-cff1-9330-26a7756b8b31.jpeg">|
|NHK杯将棋トーナメントで放送する対局|<img width="200" alt="nhk.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/94272de9-4d38-44b9-2990-a0cfdd28e748.jpeg">|
|銀河戦で放送する対局|<img width="200" alt="ginga.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/2c203956-b84e-c3e6-4191-903695b5f465.jpeg">|
|通常の対局|<img width="200" alt="standart.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/894f7905-3987-638a-4232-ca9ab86c6df1.jpeg">|
|女性棋士同士の対局|<img width="200" alt="lady.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/6a4080ab-00e0-ba40-128b-39677f9ae4de.jpeg">|

###リンクボタン :arrow_upper_right:
<img width="304" alt="button.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/80007130-54ac-0f1e-a6a1-6d999835acd7.jpeg">
画像下のリンクボタンをクリック(タップ)すると、ブラウザで以下のページを開きます:notebook_with_decorative_cover:

|対局者名ボタン|棋戦名ボタン|
|:-:|:-:|
|Googleの検索結果ページを開く<br>(対局者名 + 将棋で検索)|日本将棋連盟の公式ページを開く|

##実装した構成 :robot:
<img width="750" alt="structure.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/1dc25ebc-0e4e-a3ab-c2f7-4846e81af0a6.jpeg">


##実装でこだわった所 :pick:
###:point_up: 対局者名の文字数に合わせて、文字の大きさをほどよく自動調整

|最短文字数棋士同士の対局|最長文字数棋士同士の対局|
|:-:|:-:|
|<img width="350" alt="max.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/b986291e-254d-9d57-2fea-e5dbbbde05d9.jpeg">|<img width="350" alt="min.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/1d74ac84-fb7f-105c-3fd0-6669b07c9619.jpeg">|

```python:picture.py
    # フォントのサイズが描画領域のサイズを下回るまでループして縮小させる
    while img_width < out_text_size[0] + 120 or img_height < out_text_size[1]+ 120:
        font = ImageFont.truetype(text_font_family, text_max_font_size - font_size_offset)
        
        out_text_size = draw.textsize(text, font=font)
        font_size_offset += 1

    w, h = font.getsize(text)
    x = (img_width - w)/2
    y = (img_height - h)/2
    draw.text((x, y + text_height), text, fill=(text_color), font=font)
```

###:v: 明日の対局予定を通知する前に、過去の対局予定を全て削除する
![delete.gif](https://qiita-image-store.s3.amazonaws.com/0/328086/e9594156-b902-970c-71f7-ccef4feb43b0.gif)

タイムラインに過去の対局予定が残っていると、明日の対局予定の開始時点がわかりづらいのと、将来的にSlackのファイルアップロード数制限に引っかかってしまうので、過去の対局予定は毎日削除する実装にしました:wastebasket:
チャンネルのメッセージのhistoryを取得するAPIを叩き、取得したデータをループで回してdeleteのAPIを叩いてやります:fist:
[slackメッセージの一括削除（python3）](https://qiita.com/maruga/items/448c0a1fa0c15f54e919)を参考にさせていただきました:writing_hand:

###:point_up::v: 画像とリンクボタンを一つのアタッチメントに
<img width="524" alt="attachments.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/4d0ac496-9a92-030e-7170-87b12c3c188a.jpeg">
枠(アタッチメント)の中で `日付` `画像` `ボタン` の順にセットするのにちょっと苦労しました:lifter:
というのも、現状Slackの各APIはこんな仕様になっています:space_invader:
・画像をアップロードするAPIは同時にボタンを配置することができない
・ボタンを配置するAPI(今回はIncoming Webhooks)は画像をアップロードすることができないが、画像のURLを指定するとその画像を表示することができる

というわけで**「画像専用のチャンネルに画像をアップロードし、そのURLをIncoming WebHooksで指定する」**といった二段階の処理でこれを実現することにしました :muscle:

```python:picture.py
    result = requests.post(url="https://slack.com/api/files.upload",params=param, files=files)
    json_data = result.json()
    image_url = json.dumps(json_data["file"]["url_private"])
    return image_url.replace("\"", "") # 画像をアップロードしてURLを返却し...
```
```python:main.py
    payload = {
        "attachments": [
            {
                "fallback": fallback,
		        "text": text,
                "image_url": image_url, # ここで指定！
                "actions": [
                    {
                        "type": "button",
                        "name": "player1",
                        "text": ":bust_in_silhouette: " + row_list[2],
                        "url": player1,
                        "style": "normal",
                    },
                    {
                        "type": "button",
                        "name": "player2",
                        "text": ":bust_in_silhouette: " + row_list[4],
                        "url": player2,
                        "style": "normal",
                    },
                    {
                        "type": "button",
                        "name": "title",
                        "text": ":newspaper: " +  row_list[0] ,
                        "url": 'https://www.shogi.or.jp' + row_list[1],
                        "style": "normal",
                    }
                ] 
            }
        ]
    }
    requests.post(boto3.client('kms').decrypt(CiphertextBlob=b64decode(os.environ['incoming_web_hook_url']))['Plaintext'], data=json.dumps(payload))

```
##最後に
誰でも無料でこのチャンネル(#game-info)に参加できます:clap::ideograph_advantage:
https://goo.gl/forms/DJMFjivR2m807WpR2
(メールアドレスを入力すると招待メールが届きますので、アカウントを作成してください:bust_in_silhouette:)

ちなみに放送予定の対局には`@channel`にメンションを飛ばしているので、
<img width="500" alt="notice.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/328086/c7f2f6a9-cf29-de31-de02-df8f47603c86.jpeg">
とすれば、放送予定の対局のみPush通知されます:open_hands:

---
今回のBOTのソースコードは[GitHub](https://github.com/karmanord/japanese-chess-game-schedule-bot)にアップロードしました:desktop:
それでは良い将棋ライフを:ok_woman: