2
1

More than 3 years have passed since last update.

メールでGitHubに新規issueを追加する

Last updated at Posted at 2019-09-08

メールの受け口にAmazon SESを使うようリファクタリングしました [2020/04/26] → 記事はこちら

はじめに

メールしか使えない環境からGitHubに新規issueを追加できるようになると便利、というニッチな個人的ニーズがあり、やってみました。

方針

まず、メールで何らかのプログラムをキックする方法を考えます。自由に使えるドメインとメールサーバがあれば何でもできそうですが、そうでない場合、メール受信を起点とするWEBサービスを作る選択肢ってそうたくさんはなさそうです。
というわけで、今回は、IFTTTに用意されている「Email」サービスを使ってみます。IFTTTのトリガーとして使うことができて、IFTTTアカウントに紐付けられたメールアドレスからIFTTTの所定のメールアドレス宛にメールを送ることで、IFTTTのアクションをキックできます。

IFTTTの「GitHub」サービスを使ったissue追加の課題

IFTTTには「GitHub」サービスも用意されているので、トリガーを「Email」、アクションを「GitHub」にすれば確かに目的のレシピは作れます。この場合、IFTTTに送りつけたメールのタイトルと本文で新規issueを追加できます。
01.png
が、、、これを実際に使ってみると、追加された新規issueにはメール本文の改行がなぜか反映されません。
GitHubのissueはMarkdownが使えるところが便利ポイントなので、改行が消えてしまうこのレシピでは使い物になりません。

というわけで「Webhooks」サービス

IFTTTのサービスの中にニーズを満たすものがないときは「Webhooks」サービスの出番です。新規issueの追加はGitHub REST API v3を使えばできるので、トリガーを「Email」、アクションを「Webhooks」にして、自作のWEBサービスでGitHubへissueを追加することにします。
IFTTTのレシピにするとこんな感じ。
02.png

実装

小さなWEBサービスなので、Amazon API GatewayAWS Lambdaと、この環境向けのPythonフレームワークであるchaliceを使って簡単に作ってしまいます。

説明をすっ飛ばして、コードは以下だけ。
中で使っているいくつかの環境変数(os.environ['hoge'])をchaliceの設定ファイル(.chalice/config.json)で設定する必要はありますが、chalice deployのコマンド一発でWEBサービスが動き出します。API GatewayやLambdaの管理コンソールに触る必要は全くありません。

app.py
from chalice import Chalice
import logging, os, json
import urllib.request

# setup logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# setup chalice
app = Chalice(app_name='hook2issue')


@app.route('/', methods=['POST'])
def index():
    json_body = app.current_request.json_body
    logger.info("request body: {}".format(json_body))

    key = json_body['key']
    subject = json_body['subject']
    body = json_body['body']

    if key != os.environ['IFTTT_WEBHOOKS_KEY']:
        logger.warning("wrong key: {}".format(key))

    else:
        url = 'https://api.github.com/repos/{}/{}/issues?access_token={}'.format(
            os.environ['GITHUB_OWNER'],
            os.environ['GITHUB_REPOSITORY'],
            os.environ['GITHUB_ACCESS_TOKEN']
        )
        headers = {
            'Content-Type': 'application/json'
        }
        body = {
            'title': subject,
            'body': body
        }
        req = urllib.request.Request(
            url,
            data=json.dumps(body).encode('utf-8'),
            method='POST',
            headers=headers
        )
        try:
            with urllib.request.urlopen(req) as res:
                logger.info(res.read().decode("utf-8"))
        except Exception as e:
            logger.exception("Error in request: %s", e)

    # 200OK
    return {}

ちなみに、上記の自作WEBサービスに合わせて、IFTTTの「Webhooks」は以下のような感じで設定します。
03.png
これで所望の動きをしてくれるのですが、ハマリポイントが一点だけ。
「Body (optional)」の注意書きに、Surround any text with "<<>>" to escape the contentとあるのですが、きちんと文字列をエスケープするには"<<<>>>"で囲ってあげる必要があります。運良くこのことが書かれたWEB記事を見つけられたので良かったですが、もう少しで諦めるところでした。。。

おわりに

メールはもはやレガシーな手段になってしまった感がありますが、それでもなお、メールしかまともに使えない環境もあるにはあります。メールを起点にしたWEBサービス連携の一つのパターンとして、他にも使えるものが何か作れそうです。

参考

2
1
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
2
1