アルパカログ

Python 作って楽しい「Slack Bot」で学ぶ初めてのWeb API

2019年1月25日
🔖Python🔖プログラミング

天気予報や地図情報など、世の中の多くのWebサービスがWeb APIを提供しています。

プログラミング初学者にとって、Slack Botの開発はWeb APIを学ぶのにちょうど良い題材です。

このエントリでは、PythonプログラムからWeb APIを経由してSlack Botに発言させる方法を説明します。

完成のイメージ

最初に完成のイメージを確認しておきましょう。

次のような感じです。

An image from Notion

Botの名前、発言内容は自由に変更することができます。

それでは実際に作り方を見ていきましょう。

1. Slack App作成

まず最初にSlack Botを登録します。

Slackのワークスペースを持っていない方は、下記から無料で作成することができます。

会社で使っているSlackワークスペースしかない方も、個人開発用に作成すると良いでしょう。

ワークスペースを作成したら、ブラウザで下記URLにアクセスしてアプリ管理画面を開きます。

アプリを新規作成します。

An image from Notion

Botの名前を入力して、Botが参加するワークスペースを選びます。

ワークスペースは先ほど作成した個人開発用のワークスペースを選択しましょう。

An image from Notion

英語ばかりのページが現れますが驚かないでください。

「Incoming Webhooks」を選びます。

An image from Notion

初期ではOffになっているので、Incoming WebhooksをOnにします。

An image from Notion

Onにするとページが下に伸びるので、下までスクロールして新しいWebhookを追加します。

An image from Notion

Botにどのチャンネルで喋らせるか許可を与える画面になるので、チャンネルを選んで許可します。

An image from Notion

これでBotに喋らせるためのあなた専用のURL(Webhook URL)ができました。

Webhook URLは後ほどPythonプログラムから使用します。

Webhook URLは人に教えないでください。

An image from Notion

2. Pythonプログラミング

Pythonのプログラムを書く前に、全体像を説明します。

下の図を見てください。

Slackというポストに手紙(メッセージ)を投函すると、メッセージが相手に届きます。

ポスト全体がSlackで、投函口がIncoming Webhooks、宛先がWebhook URLです。

An image from Notion

先ほどまでは図のポストにあたる部分を作りました。

これから書くのは、ポストに手紙を投函するPythonプログラムです。

post.pyを作成し、下記のPythonプログラムを書きましょう。

webhook_urlは自分のWebhook URLに置き換えてください。

import json
import urllib.request

webhook_url = 'https://hooks.slack.com/services/xxxxxx'

data = {'text': 'トヤーン'}

req = urllib.request.Request(webhook_url)
req.add_header('Content-type', 'application/json')

with urllib.request.urlopen(req, json.dumps(data).encode('utf-8')) as f:
    print(f.read().decode('utf-8'))

保存して実行してみましょう。

指定したチャンネルで発言できれば成功です!

3. Web APIのために知るべきこと

Pythonプログラムが思ったより短いことに驚かれたかもしれません。

しかしプログラムを理解するには、その長さ以上にたくさんのことを学ぶ必要があります。

ここでは、プログラムを理解する上でどんなことを学べば良いのか、項目別に簡単に頭出しをします。

推薦図書もあわせてご紹介します。

JSON

プログラムの冒頭でjsonモジュールを読み込んでいます。

JSONとはCSVのようなデータフォーマットの一種で、Web APIで頻繁に使われています。

CSVは縦・横の2次元しか表わせないのに対し、JSONは入れ子(ネスト)を表現できるため、何次元のデータでも表すことができます。

HTTPリクエスト

urllib.requestモジュールは、HTTPリクエストを扱うために読み込んでいます。

HTTPリクエストを理解するには、学ばなければならないことが多すぎて、本を1冊読んでしまった方が早いくらいです。

ぜひ「Webを支える技術」を読んでください。

今回作成したPythonプログラムは、Webhook URLに対してメッセージ内容のデータをHTTPリクエストで送信しています。

データフォーマットにはJSONが使われています。

UTF-8

「UTF-8」や「文字コード」という言葉は聞いたことがあるかもしれません。

現在のWebではUTF-8が広く使われています。

「文字コード」はその複雑さのためか、曖昧な理解なまま「文字コード」という言葉が使われてしまっているケースがあります。

文字コードを正しく理解するためには、「文字集合(文字セット)」と「符号化方式(エンコーディング)」について知る必要があります。

UTF-8は、Unicode文字セットのエンコーディングの1つです。

Pythonにおける文字列の扱い

Python3では、文字列はUnicodeで表現されます。

しかし、Web APIのような外部とデータをやりとりする際は、内部的な表現である文字列型から、Webで一般的に使用されるUTF-8のバイト列型に変換(エンコード)する必要があります。

文字コードが混同しやすいテーマであるのに加え、文字列型をバイト列型に変換する必要があることが、ややこしさに拍車をかけています。

理解するのに時間がかかるかもしれませんが、日本語を扱う上では避けて通れない道です。

API仕様

Slackへの投稿内容は、プログラムの次の部分で指定されているというのはわかると思います。

data = {'text': 'トヤーン'}

しかし、キーが'text'なのは誰が決めたのでしょうか?

それは、Web APIごとに定められています。

例えば今回使ったSlackのIncoming Webhooksなら、下記のページで説明されています。

別のサービスのWeb APIを使うときは当然、データのフォーマットが違います。

Web APIのドキュメントがあるので、APIを使用する際はドキュメントをよく確認しましょう。

最後に

今回作成したプログラムを、自分なりに改変して遊んでみましょう。

例えば、次のような新機能を付け足してみてください。

などなど。

何かわからないことがあったら、お近くのエンジニアを捕まえて聞いてみてくださいね。

以上です。

このエントリでは、PythonプログラムからWeb APIを経由してSlack Botに発言させる方法を説明しました。

タグ