ngrokとPythonでWebhookを受信してjson出力
背景
私が所属するチームでは海外のとあるSaaSプロダクトを取扱してます。
そのSaaSでは、利用上発生するイベントをトリガーにWebhookを実行することができます。
今回はそちらを簡単に受信してファイル出力するところまでを目指します。
利用するもの
- ngrok(エングロック)
- Python
- 某SaaSのWebhook(json形式でPOSTされます)
PythonでWebhookを受けるローカルサーバーを立てる
サーバーに到達したリクエストを処理するため、http.server
クラスのBaseHTTPRequestHandler
を利用します。
do_POST()
を主に使っていきます。
私は以下のような感じで書きました。
POSTされる内容(Request Payroad)自体がjson形式なので、そのままファイル出力してます。
ターミナル等で実行しておきます。
# -*- coding:utf-8 -*-
import http.server
import socketserver
import datetime
from urllib.parse import parse_qs, urlparse
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_POST(self):
print('path = {}'.format(self.path))
parsed_path = urlparse(self.path)
print('parsed: path = {}, query = {}'.format(parsed_path.path, parse_qs(parsed_path.query)))
print('headers\r\n-----\r\n{}-----'.format(self.headers))
content_length = int(self.headers['content-length'])
#Body書き出し
now = datetime.datetime.now()
file_name = 'wbhk_out_' + now.strftime('%Y%m%d_%H%M%S') + '.json'
req_body = self.rfile.read(content_length).decode("utf-8")
with open(file_name, 'w') as f:
f.write(req_body)
self.send_response(200)
self.send_header('Content-Type', 'text/plain; charset=utf-8')
self.end_headers()
self.wfile.write(b'Hello from do_POST')
with socketserver.TCPServer(("", 80), MyHandler) as httpd:
httpd.serve_forever()
ngrok
ngrokはローカルホストで稼働するアプリケーションなどを外部公開してくれるサービスです。
わざわざWebサーバー組んだりサーバーレス使ったりっていう手間なくWebアプリが公開できちゃうんですね。お手軽な範囲でしたら無償で使えます。
インストール
まずはサインアップ後、nrgokをダウンロードします。Windows/Mac/Linux/FreeBSDに対応しているようです。私はWindowsで利用しました。
コンソールにログイン後、以下の画面の赤枠部分にトークンが表示されています。
実行準備
ガイドの通りコマンドを叩いてもよいのですが以下の記事を参考にbatファイルを作成しました。
作成したbatファイルは以下の2つです。順に実行します。
ngrok authtoken {YOUR_TOKEN_HERE}
ngrok http 80
2_80listen.bat
を実行すると、以下のように表示されます。
赤枠部分、[https://xxx.jp.ngrok.io] の部分が要はWebhook側から見たエンドポイントのURLになります。ですので、Webhook側(渡しの場合はSaaSサービス)に設定してあげましょう。
テスト・確認
Webhook側からPOSTがあると、Pythonを実行しているターミナルでは以下のような感じで受信状況が分かります。
$ python .\wbhkReciever.py
path = /
parsed: path = /, query = {}
headers
-----
Host: hogehoge.jp.ngrok.io
User-Agent: Java/11.0.11
Content-Length: 699
Accept: text/plain, application/json, application/cbor, application/*+json, */*
Content-Type: application/json
hoge-Header1: Val_hoge-header
hoge-Header2: hogehogehoge
Traceparent: hhogeee
X-Forwarded-For: 11.222.333.44
X-Forwarded-Proto: https
Accept-Encoding: gzip
-----
127.0.0.1 - - [15/Jun/2022 10:11:12] "POST / HTTP/1.1" 200 -
ngrokでもWeb Inspection Interface
が提供されてまして、受信状況を確認することができます。ngrokのドキュメントに記載があります。
http://localhost:4040 にアクセスすると、以下のような感じで確認することができます。
便利ですね!
まとめ
Webhookや、httpリクエストによるGET/POSTの処理を気軽にテストしたいときなどに非常に便利なツールです。無償で使える一方、より高機能且つエンタープライズ向けのプランもあるようです。
Discussion