この記事で分かること
- BOT(ボット)を使うシステムとwebhookの関係が分かる
- webhookとトンネリングサービスの関係が分かる
- トンネリングサービスの利用方法が分かる
- Pythonプログラムでトンネリングサービスの実装方法が分かる
Pythonでwebhookを受信する概要
社内LANなどインターネットから切り離されたネットワークを使っている場合に、外部(インターネット)からイベントを受信したい場合があります。例えば、チャットシステムのBOTなどのWebhookシステムなどは、チャット送信が一旦インターネット上のサービスで受信され、そこから所望のURLへと転送されるようになっていることが多いです。
ところが、メッセージを受信して処理するシステムが社内ネットワークのみで動作している場合は、このメッセージイベントを受信することができません。なぜなら、社内ネットワーク(イントラネット)と公共のネットワーク(インターネット)の間には、外部からのアクセスを遮断するファイヤーウォールがあるからです。
そのような場合には、ngrokのトンネリングサービスを利用することができます。トンネリングサービスとは、社内ネットワークと公共のネットワークをつなぐセッションを社内ネットワーク側から作り、その公共ネットワーク側に受信したデータを、社内ネットワークに取り込むというしくみのことです。
この記事では、トンネリングサービスの代表であるngrokの使い方を説明することによって、webhookを受信する方法を説明します。
Pythonでwebhookを受信する前提環境
webhookを受信する前提環境は、下の記事で説明している私の環境と同じ環境で確認しています。
また、レンタルサーバなどのLinuxサーバを使っている場合は、下の記事でプログラミングする環境の作り方を説明しています。
もし、まだプログラムする環境ができていない方は、先にこちらの記事を読んで、プログラミングできる環境をつくることをおすすめします。
Pythonでwebhookを受信するサンプルプログラム
ngrokのインストール
まず、下記にアクセスしてシステムに応じた「ngrok」の実行ファイルをインストールします。
ngrok - secure introspectable tunnels to localhost
ngrokのインストール手順は、
- ダウンロード
- zip解凍&インストール
- アカウントを作って、"Connect your account"を押下
になります。
Pythonでwebhookを受信するサンプルプログラム
さきほどインストールした「ngrok」をPythonプログラムから実行して、webhookを受信するサンプルプログラムを説明します。サンプルプログラムは、次のような順番で説明します。
- ライブラリのインポート
- Linuxコマンドの実行
- ngrokの開始するプログラム
- ngrokの開始実行処理
1.ライブラリのインポート
ここでは、webhookを受信する処理の為のライブラリのインポート処理を行います。webhookを受信する為には、次のライブラリをインポートします。
- 非同期処理を行う「subprocess」
- Linuxのコマンドを扱う「shlex」
import subprocess
import shlex
- ライブラリ「subprocess」をインポートする。
- ライブラリ「shlex」をインポートする。
2.Linuxコマンドの実行
ここでは、LinuxコマンドをPythonプログラムから呼び出す関数を定義します。その関数名を「exe_linux_command」とし、引数に、任意のLinuxコマンドのテキスト「commad」を取ります。
PythonプログラムからLinuxコマンドを呼び出す具体的な方法は、下の記事で解説していますので、こちらも合わせて読んでください。
def exe_linux_command(command):
tokens = shlex.split(command)
p = subprocess.Popen(tokens)
for line in iter(p.stdout.readline,b''):
print(line.rstrip().decode("utf8"))
return
- 関数「exe_linux_command」を定義宣言する。
- 変数「tokens」を「shlex」ライブラリの関数「split」の引数に変数「command」を指定した場合の戻り値で初期化する。
- 変数「p」をライブラリ「subprocesss」の関数「Popen」の戻り値で初期化する。
- 変数「p」に対して出力を確認する関数「stdout.readline」の結果を、変数「line」に格納しながら、以下の処理を繰り返す
- 「line」の内容を表示する。
- 関数「exe_linux_command」から戻る(リターンする)。
3.ngrokの開始するプログラム
ここでは、カレントディレクトリの配下の「tools」というディレクトリに「ngrok」をインストールしたとして、「ngrok」を開始する方法を説明します。
また、このURLは公共ネットワーク側にあります。このURLからトンネリングした社内ネットワーク側にhttpリクエストを受け取るためのHTTPサーバを立てる必要があります。この「HTTPサーバを立てる方法」に関しては、下記の記事を読んでください。
下のプログラムでは、例としてhtttpサーバーのポート4000番を指定しています。ngrokを開始すると、URLが発行されます。このURLをWebhookで指定するメッセージの転送先に設定することで、webhookからのメッセージを受け取ることができます。webhookからのメッセージはngrokから発行されたURL宛に送信されますが、送信されるメッセージはHTTPリクエストの形をしています。
def start_ngrok():
ret = exe_linux_command('/tools/ngrok http 4000')
print(ret)
- 関数「start_ngrok」を定義宣言する。
- 変数「ret」を文字列「/tools/ngrok http 4000」を引数に指定した関数「exe_linux_command」の戻り値で初期化する。
- 変数「ret」の内容を表示する。
4.ngrokの開始実行処理
サンプルプログラムの開始として、上で定義した関数「start_ngrok」を呼び出します。
if __name__ == '__main__':
start_ngrok()
関数「start_ngrok」を呼び出す。