LoginSignup
3
2

More than 5 years have passed since last update.

プログラミング初心者が Python で Slack bot 作成 [ 実践編 ]

Posted at

はじめに

前回の プログラミング初心者が Python で Slack bot 作成 [ 準備編 ]
の続きとなります。

開発環境

環境

  • Python
  • Docker
  • Make

ツール

  • Atom Editor
  • iTerm 2

実践

まずは 開発環境 をクローンします。

続いてクローンしたリポジトリの src ディレクトリに weather.py ( ファイル名はご自由に ) を新規作成します。

今回使うライブラリは標準のものだけです ( Lambda では基本的に標準のもの以外使えません ) 。

weather.py
import json # 追記
import urllib # 追記

import json これを使うことで Python で JSON を扱うことができます。
import urllib これは Python で HTTP リクエストを出すために必要なものです ( 今回は GET リクエストと POST リクエストを使います ) 。

まずは Yahoo デベロッパーネットワークで作成したリクエスト URL を変数 REQUEST_URL に入れます。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL' # 追記

次に Slack で取得した Web hook URL を変数 WEB_HOOK_URL に入れます。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL' # 追記

では実際に Yahoo 気象情報 API から情報を取得してみましょう!

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL) # 追記
    with urllib.request.urlopen(reqg) as res: # 追記
        response = res.read() # 追記

1 行目は REQUEST_URL へリクエスト ( GET ) し、結果を変数 reqg に入れています。
噛み砕いて説明すると、

使うもの    使う機能     オブジェクト      どこの
   urllib     .request      .Request      (REQUEST_URL)

こうなります。

2 行目は 1 行目で取得したものを開いて変数 res の中に入れています。

3 行目は変数 response の中に 2 行目で展開した変数 res を読み込んだものを入れています。

これで変数 response にリクエストのレスポンスが入りました。
では response の中身を見てみましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

print(response) # 追記

実行してみましょう。

$ python weather.py

すると、

{
  "ResultInfo": {
    "Count": 1,
    "Total": 1,
    "Start": 1,
    "Status": 200,
    "Latency": 0.003538,
    "Description": "",
    "Copyright": "(C) Yahoo Japan Corporation."
  },
  "Feature": [
    {
      "Id": "201903252255_139.707831_35.774614",
      "Name":"\xe5\x9c\xb0\xe7\x82\xb9(139.707831,35.774614)\xe3\x81\xae2019\xe5\xb9\xb403\xe6\x9c\x8826\xe6\x97\xa5 14\xe6\x99\x8220\xe5\x88\x86\xe3\x81\x8b\xe3\x82\x8960\xe5\x88\x86\xe9\x96\x93\xe3\x81\xae\xe5\xa4\xa9\xe6\xb0\x97\xe6\x83\x85\xe5\xa0\xb1",
      "Geometry": {
        "Type": "point",
        "Coordinates": "139.707831,35.774614"
      },
      "Property": {
        "WeatherAreaCode": 4410,
        "WeatherList": {
          "Weather": [
            {
              "Type": "observation",
              "Date": "201903252255",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252305",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252315",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252325",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252335",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252345",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252355",
              "Rainfall": 0
            }
          ]
        }
      }
    }
  ]
}

name の部分が読めませんね ( 見やすくするため整形しています )。

原因はこれが HTTPResponse オブジェクト だからです。
なので文字列に変換する必要があります。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode() # 追記

print(response)

もう1度確認してみましょう。

$ python weather.py

すると

{
  "ResultInfo": {
    "Count": 1,
    "Total": 1,
    "Start": 1,
    "Status": 200,
    "Latency": 0.003538,
    "Description": "",
    "Copyright": "(C) Yahoo Japan Corporation."
  },
  "Feature": [
    {
      "Id": "201903252255_139.707831_35.774614",
      "Name": "地点(139.707831,35.774614)の2019年03月25日 22時55分から60分間の天気情報",
      "Geometry": {
        "Type": "point",
        "Coordinates": "139.707831,35.774614"
      },
      "Property": {
        "WeatherAreaCode": 4410,
        "WeatherList": {
          "Weather": [
            {
              "Type": "observation",
              "Date": "201903252255",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252305",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252315",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252325",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252335",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252345",
              "Rainfall": 0
            },
            {
              "Type": "forecast",
              "Date": "201903252355",
              "Rainfall": 0
            }
          ]
        }
      }
    }
  ]
}

これで読めるようになりました。
確認が終わったのでptint(response)は削除しましょう。

続いて変数 response の中身を JSON に変換しましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode()

d = json.loads(response) # 追記

変数 response が JSON に変換されたものが変数 d に 入りました。
これを噛み砕いて説明すると、

変数     代入     json として     読み込む     何を
  d      =       json       .loads     (response)

となります。

この JSON の中にはたくさんのデータが入っていますが、今回必要なのは降水強度のデータのみです。
では降水強度のみ抜き出してみましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode()

d = json.loads(response)

rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall'] # 追記

これは変数 d の中身 ( JSON ) の Feature0 番目 ( dict ( 辞書 )では 0, 1, 2, 3, ... と数えます ) の PropertyWeatherListWeather0 番目の Rainfall の値を変数 rainfall に代入する、という意味になります。
実際に確認してみましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode()

d = json.loads(response)

rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']

print(rainfall) # 追記

$ python weather.py

すると、

0.0

これで無事、現在の降水強度のみを取得することができました!
確認が終わったのでprint(rainfall)は削除してください。

では次に Slack に通知する文を書きましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode()

d = json.loads(response)

rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']

payload_d = {
    'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
} # 追記

今回は { } で括ったものを代入しています。
これは、変数 payload_ddict として代入する、という意味です。
中身は text をキーに '現在の赤羽駅の降水強度は {} mm/h です。' を値として、{} 内に、変数 rainfall の中身を表示、という意味になります。

説明ではわかりにくいですね...。
では実際に payload の中身を確認してみましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode()

d = json.loads(response)

rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']

payload_d = {
    'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
}

print(payload_d) # 追記

$ python weather.py

{'text': '現在の赤羽駅の降水強度は 0.0 mm/h です。'}

このように {} 内に変数 rainfall の中身が代入されます。
確認が終わったのでprint(payload_d)を削除してください。

ではこれを JSON に変換しましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode()

d = json.loads(response)

rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']

payload_d = {
    'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
}

data = json.dumps(payload_d).encode('utf-8') # 追記

これを細かく説明するとこうなります。

変数    代入      JSON として変換      何を       文字コード
data      =        json    .dumps    (payload_d)    .encode('utf-8')

次にこのデータを Slack に届ける準備をしましょう。

weather.py
import json
import urllib

REQUEST_URL = '作成したリクエスト URL'

WEB_HOOK_URL = '取得した Web hook URL'

reqg = urllib.request.Request(REQUEST_URL)
    with urllib.request.urlopen(reqg) as res:
        response = res.read()

response = response.decode()

d = json.loads(response)

rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']

payload_d = {
    'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
}

data = json.dumps(payload_d).encode('utf-8')

reqp = urllib.request.Request(WEB_HOOK_URL, data, method='POST') # 追記
with urllib.request.urlopen(reqp) as res: # 追記
        body = res.read().decode('utf-8') # 追記


データを届ける ( POST ) ときも urllib を使います。
データを取得したときと似ていますね。
違うところは 1 行目の method='POST' と 2 行目の decode('utf-8') になります。

method='POST' は HTTP メソッドの指定になります。今回は Slack に届けてもらいたいので POST ですね。
decode('utf-8') は文字コードの指定になります。これで Slack 側でもちゃんと読めるようになります。

以上で完成です!
試しに実行してみましょう!

$ python weather.py

スクリーンショット 2019-03-27 22.15.12_edited-1.jpg

このような通知が来れば成功です!

最後に

とても長くなってしまいましたが、最後までお付き合いいただきありがとうございました!
コードはこれで完成しましたが、デプロイがまだなので、次回 本番編 ということでそちらに記事を書かせていただきます。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2