Python3
BeautifulSoup
lambda
slackbot
将棋
0

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

僕は永瀬拓矢七段が好きです:banana:

game-info___japanese-chess-game-schedule-bot_Slack.jpg
いつかこんな日が来ると良いですね:stew:

作ったもの :art:

明日の公式戦全対局予定をSlackに通知するBOT(毎日22時に更新:clock10:)
over-all-view.jpg

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

種類 背景画像
AbemaTVとニコニコ生放送で放送する対局 niconico_abema.jpg
AbemaTVで放送する対局 abema.jpg
ニコニコ生放送で放送する対局 niconico.jpg
NHK杯将棋トーナメントで放送する対局 nhk.jpg
銀河戦で放送する対局 ginga.jpg
通常の対局 standart.jpg
女性棋士同士の対局 lady.jpg

リンクボタン :arrow_upper_right:

button.jpg
画像下のリンクボタンをクリック(タップ)すると、ブラウザで以下のページを開きます:notebook_with_decorative_cover:

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

実装した構成 :robot:

structure.jpg

実装でこだわった所 :pick:

:point_up: 対局者名の文字数に合わせて、文字の大きさをほどよく自動調整

最短文字数棋士同士の対局 最長文字数棋士同士の対局
max.jpg min.jpg
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

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

:point_up::v: 画像とリンクボタンを一つのアタッチメントに

attachments.jpg
枠(アタッチメント)の中で 日付 画像 ボタン の順にセットするのにちょっと苦労しました:lifter:
というのも、現状Slackの各APIはこんな仕様になっています:space_invader:
・画像をアップロードするAPIは同時にボタンを配置することができない
・ボタンを配置するAPI(今回はIncoming Webhooks)は画像をアップロードすることができないが、画像のURLを指定するとその画像を表示することができる

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

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を返却し...
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にメンションを飛ばしているので、
notice.jpg
とすれば、放送予定の対局のみPush通知されます:open_hands:


今回のBOTのソースコードはGitHubにアップロードしました:desktop:
それでは良い将棋ライフを:ok_woman:

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away