0時に寝て4時と5時に起きて6時に起きた。最近は4時から1時間ごとに起きたりする。メールの送信処理のリファクタリングのコードレビューが長く続いていてなかなかややこしい。

mailhog の web api を使って検索する

メール送信の結合テストに mailhog というツールを使っている。smtp サーバーとしてメールを受け付けて web ui でそのメールの内容を確認できる機能をもっている。さらに web api で任意のメール取り出すこともできる。パスワードリセットの一時トークンをメールで送信するため、結合テストで一連のパスワードリセットを検証するにはメールから一時トークンを取り出さないといけない。そこで mailhog の出番だ。

検索 api を使うと任意のメールをフィルターできる。例えば、送り先のメールアドレスで検索するときは次のようにリクエストする。

$ curl -s "http://localhost:8025/api/v2/search?kind=to&query=myuser1@example.com" | jq .

うちらのやり方はメールのメッセージ ID に意図した uuid をセットしている。メールのメッセージから指定した uuid を含んでいるかを検索することで任意のメールをフィルターできる。

$ curl -s "http://localhost:8025/api/v2/search?kind=containing&query=28c9391f-25a5-4a8f-9035-7b8d5ac2d0f4" | jq .

それを結合テストのテストコードから呼び出すようにユーティリティを作ると次のようなコードになる。

import (
	"github.com/mailhog/data"
)

type mmSearchResult struct {
	Total int            `json:"total"`
	Count int            `json:"count"`
	Start int            `json:"start"`
	Items []data.Message `json:"items"`
}

func searchMail(
	host string, kind string, query string,
) (*mmSearchResult, error) {
	q := url.Values{}
	q.Set("kind", kind)
	q.Set("query", query)
	u := &url.URL{
		Scheme:   "http",
		Host:     host,
		Path:     "/api/v2/search",
		RawQuery: q.Encode(),
	}
	url := u.String()
	slog.Debug("mailhog search endpoint", "url", url)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("http create new request error. err: %s", err)
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("http request error. err: %s", err)
	}
	if res.StatusCode >= 400 {
		return nil, fmt.Errorf("returned response code is %d", res.StatusCode)
	}
	var r mmSearchResult
	if err := convertBody(res, &r); err != nil {
		return nil, fmt.Errorf("failed to convert: %s", err)
	}
	return &r, nil
}

歯医者

17時から歯科検診へ行ってきた。歯科検診をしてくれた今回のスタッフはおそらく初めてだったと思うが、手際がよくていつもよりもストレスが少なかった気がした。うちのチームのメンバーは朝方なので8時過ぎにはだいたいみんな始業し始める。なので、朝よりも夜にいない方がメンバーにとってよいだろうと考えて、朝一 (9時) に歯医者へ行くよりも最終 (17時) に行くようにしている。

pycamp ふりかえり

先週末の Python Boot Camp のふりかえり。ここまでがスタッフのお仕事なので一般的な kpt でイベントのふりかえりをした。仕事じゃないし、大きなトラブルもなかったし、参加者の評判 (アンケートの内容) もよかったので概ねよい内容だったと思う。テキストの改善点は直接 issue に追加してほしいと言われたので報告した。是非も含めてスタッフに判断してほしいので私が直すつもりはない。