LambdaでSisimaiを動かしてバウンスメールを解析するテスト

バウンスメール対策として、Sisimaiの利用を考えていました。ここで結論です。LambdaでSisimaiによるバウンスメール解析の仕組みが作れそうでした。LambdaでSisimaiを動かすような記事は見つからなかったのでアウトプットしてみることにしました。 libsisimai.org

"SisimaiはbounceHammerの後継となるバウンスメール(エラーメール)解析ライブラリ" です。

クックパッド開発者ブログにある以下の記事を興味深く読みました。 techlife.cookpad.com

読んだ結果、わりと壮大な仕組みなので、現在であればもう少し小さく仕組みを実現できるのではないかと思って試してみた記事です。できるだけマネージドな仕組みの上で実現したいのですが、バウンスメール解析のSaaSでピンとくるものはなさそうだったのでこの記事の内容を試しています。(できればコードは書きたくないのでマネージドバウンスメール解析SaaSほしい)

Sisimaiは標準入力、変数経由などいくつかの動かし方ができるのと、依存関係が少ないのでLambdaで動くのではないか?と思って試しました。デプロイのことは考えるのが面倒だったので最小の工数でやってみています。

手順

  • AWSのマネジメントコンソールでsisimai-ruby-testってfunctionを作っておきます。
  • 手元で以下のlambda_function.rbのコードを書きます

変数f の中身はsisimai作者のazumaさんが開発・デバッグ用に提供してくれているメールの中身をブチ込んでみています。検証用なのでいかにも雑です。(ここをS3 Eventの中身にすると、SES+S3で受信している仕組みで使えそうです。 https://github.com/sisimai/set-of-emails/blob/master/maildir/bsd/lhost-sendmail-32.eml

require 'json'
require 'sisimai'

def lambda_handler(event:, context:)
    f = 'Return-Path: <MAILER-DAEMON@nyaan.example.co.jp>
Received: from localhost (localhost)
    by nyaan.example.co.jp (V8/cf) id t91ECGic009238;
    Thu, 1 Oct 2015 23:12:16 +0900
Date: Thu, 1 Oct 2015 23:12:16 +0900
From: Mail Delivery Subsystem <poostmaster@example.co.jp>
Message-Id: <201510011412.t91ECGic009238@nyaan.example.co.jp>
To: <shironeko@example.co.jp>
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
    boundary="t91ECGic009238.1443708736/nyaan.example.co.jp"
Subject: Returned mail: see transcript for details
Auto-Submitted: auto-generated (failure)

This is a MIME-encapsulated message

--t91ECGic009238.1443708736/nyaan.example.co.jp

The original message was received at Thu, 1 Oct 2015 23:12:15 +0900
from c135.kyoto.example.ne.jp [192.0.2.78]

   ----- The following addresses had permanent fatal errors -----
<nyaaan@neko.example.jp>
    (reason: 550 5.1.1 Requested action not taken: mailbox unavailable)

   ----- Transcript of session follows -----
... while talking to inbound-smtp.us-west-2.amazonaws.com.:
>>> RCPT To:<nyaaan@neko.example.jp>
<<< 550 5.1.1 Requested action not taken: mailbox unavailable
550 5.1.1 <nyaaan@neko.example.jp>... User unknown
>>> DATA
<<< 503 Error: need RCPT command

--t91ECGic009238.1443708736/nyaan.example.co.jp
Content-Type: message/delivery-status

Reporting-MTA: dns; nyaan.example.co.jp
Received-From-MTA: DNS; c135.kyoto.example.ne.jp
Arrival-Date: Thu, 1 Oct 2015 23:12:15 +0900

Final-Recipient: RFC822; nyaaan@neko.example.jp
Action: failed
Status: 5.1.1
Remote-MTA: DNS; inbound-smtp.us-west-2.amazonaws.com
Diagnostic-Code: SMTP; 550 5.1.1 Requested action not taken: mailbox unavailable
Last-Attempt-Date: Thu, 1 Oct 2015 23:12:16 +0900

--t91ECGic009238.1443708736/nyaan.example.co.jp
Content-Type: message/rfc822

Return-Path: <shironeko@example.co.jp>
Received: from [192.0.2.43] (c135.kyoto.example.ne.jp [192.0.2.78])
    (authenticated bits=0)
    by nyaan.example.co.jp (V8/cf) with ESMTP id t91ECEic009234
    for <nyaaan@neko.example.jp>; Thu, 1 Oct 2015 23:12:15 +0900
X-SenderID: Sendmail Sender-ID Filter v1.0.0 nyaan.example.co.jp t91ECEic009234
Authentication-Results: nyaan.example.co.jp; sender-id=pass header.from=shironeko@example.co.jp; auth=pass (CRAM-MD5); spf=pass smtp.mfrom=shironeko@example.co.jp
From: "Shironeko, Nyaaan" <shironeko@example.co.jp>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Subject: Nyaaaan
Message-Id: <4CB0AF09-E358-4D06-82B8-B8344B55CE02@example.co.jp>
Date: Thu, 1 Oct 2015 23:12:10 +0900
To: nyaaan@neko.example.jp
Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\))
X-Mailer: Apple Mail (2.1878.6)

nyaaan

--t91ECGic009238.1443708736/nyaan.example.co.jp--

'
    v = Sisimai.make(f)
    v.each do |e|
      puts e.action
      puts e.deliverystatus
      puts e.reason
      puts e.diagnosticcode
      puts e.softbounce
    end
end
  • Gemfileを書きます
# frozen_string_literal: true

source "https://rubygems.org"

gem 'sisimai', '~> 4.25', '>= 4.25.7'
  • bundle installをします sisimaiが依存するojがNative extentionなのでAmazon Linux2上でビルドする必要があるのでこういう工夫が必要です。

docker run -v (pwd):/var/task -it lambci/lambda:build-ruby2.5 bundle install --path vendor/bundle

(かつての同僚が書いた記事に救われました。いい記事ですね。このチームでの楽しかったな~ Ruby on Lambdaで実現する、Eightの大規模画像処理基盤 - Sansan Builders Box

  • Zipをアップロードする形でLambdaにデプロイします

aws lambda update-function-code --function-name sisimai-ruby-test --zip-file fileb://function.zip

  • 空のeventを渡してLambdaをテスト実行します。下のJSONがSisimaiが返してくれた結果です。
[
   {
     "catch": "",
     "token": "b314cc8582c5f78c3381dbaf4b5e86d706d1c505",
     "lhost": "c135.kyoto.example.ne.jp",
     "rhost": "inbound-smtp.us-west-2.amazonaws.com",
     "alias": "",
     "listid": "",
     "reason": "userunknown",
     "action": "failed",
     "origin": "<MEMORY>",
     "subject": "Nyaaaan",
     "messageid": "4CB0AF09-E358-4D06-82B8-B8344B55CE02@example.co.jp",
     "replycode": "550",
     "smtpagent": "Sendmail",
     "softbounce": 0,
     "smtpcommand": "DATA",
     "destination": "neko.example.jp",
     "senderdomain": "example.co.jp",
     "feedbacktype": "",
     "diagnosticcode": "550 5.1.1 Requested action not taken: mailbox unavailable 503 Error: need RCPT command",
     "diagnostictype": "SMTP",
     "deliverystatus": "5.1.1",
     "timezoneoffset": "+0900",
     "addresser": "shironeko@example.co.jp",
     "recipient": "nyaaan@neko.example.jp",
     "timestamp": 1443708736
   }
 ]

とてもお手軽でしたね。SES+S3でメール受信して、S3 EventをトリガーにしてSisimaiが動いてバウンスメール解析するという仕組みを動かせそうな気持ちになってきました。よかったですね。

認定スクラムマスターになれました

こんにちは id:hokkai7go です。これまでSREチームでのスクラムの話をしてきておりましたが、スクラムマスターとしては無免許でした。社内のすくすく開発会(スクラムに興味のある人達の集まり)や知人に相談してやってきていたものの、スクラムについて深く知りたいと思う気持ちがありました。

blog.hokkai7go.jp

blog.hokkai7go.jp

そんな中、つい先日認定スクラムマスター研修を受けることができ、(試験に合格したので)無事に認定をもらうことができました。

研修を受けてみての感想

もともとはオフラインでの開催予定でしたがオンライン研修になりました。 講師のJames CoplienさんにはRegional Scrum Gathering Tokyo 2020で一度お会いして直接話すことができていたので、ある程度人となりがわかっていてよかった気がします。どの講師の研修を受けるとよいのかについても、社内のすくすく開発会で事前に相談できたのがよかったと感じています。

blog.hokkai7go.jp

2枚めの写真に私がいます

とてもパワフルな研修でした。4日間にわたって半日溶けると仕事のスケジューリングの面でも、体力もじわじわ削られていきました。しかしこれまで見様見真似でやってきていたことが、以後は自信を持ってやっていけるというのはとても心強いことだなと感じています。また同僚とともに受講できたのもよかったことでした。同僚のおかげで議論や質問が活発になっていきました。

これからの実践が大事だと思うので、今後も社内外のスクラム関連コミュニティに参加して理解を深めていきたいと思います。

鼻うがい

(コロナ禍によるものなのか知らないけども、最近は仕事以外で日本語を書くことから逃げているので敢えてアウトプットしてみようとするものである)

以前、鼻うがいのメリットを説かれても避けていたのだが、一年の中で花粉症と格闘している期間が長い生活を送ってることもあり鼻うがいをやってみることとした。つまり、花粉は吸い込むことがあるものとして、安全な家においては過ごしやすくしようと考えた結果である。

 

近所で買ってきたのは、小林製薬のハナノアだった。

 

 

ドキドキしつつブシュっとやってみると意外と痛くない。体液に近い成分にプラスして少しスースーする洗浄液が心地良い。しかしまだためらいがあるので、噴出させた液が戻ってきてるくらいの感覚でしかなかった。

 

今では慣れてきており、反対の鼻の穴から洗浄液が出てくるくらいになっていたり、洗浄液が無くなったので生理食塩水を自作して使うようになったくらいだ。

気がつけば鼻うがいが大好きになっている自分がいた。花粉がある限り、自分は鼻うがいを続けていくのだろうと思う。

 

お題「#おうち時間」でした

最近気がついたこと

自分が決まって一年半で燃え尽きたり、転職してきたのはなぜなのかと考えてみた。なんとなくそれっぽい答えが得られた気がしている。

入社直後のスタートダッシュタイミングで、期待されることも多いしその期待に応えたいので、やれること、やりたいことの範囲を広げていった結果、やりたくないことの範囲にかかったり、やることが多すぎるようになるのがだいたい一年半経ったくらいなのではないか。というところに至った

話は変わり、最近の課題について。

仕事での自尊感情を得にくい。普通にやっているくらいでは普通の評価しかもらえない、感謝ベースでコミュニケーションがまわっているわけではないので仕事をやった達成感や嬉しさを感じにくい(自分はここらへんを一番大事にしていることが最近わかってきた)。仕事でアガる体験が最近少ない。モチベーションの谷にいる。ここから再びモチベーションを得たいのだが、あまり手立てがわからずに困っている。

ポストモーテムを読む会を始めた

社内でポストモーテムを読む会を始めた。個人の取り組みとして、週に一度30分~1時間でやっている。イメージとしては大学の先生のオフィスアワーのように、とりあえず社内に向けてオープンにしてやっている。誰かを巻き込むことは重要視していないので、自分だけで継続することを大事にしている。目的等は以下の通り。

  • 目的: よりよい障害対応ができるようになる。これを達成できるようになるためにまずはポストモーテムを読む。
  • やり方: 個人の取り組みとして、週に一度30分~1時間でやる。ひっそりとhangoutで配信する
  • 扱う対象: SRE本のポストモーテムの章、社内の障害一覧、社外のポストモーテム、PagerDutyやNewRelicのベストプラクティス、SREcon資料、他業界の資料等

以下は、会を行うたびにScrapboxに取っているメモのテンプレ - 見たやつ - 今後みたいやつ - 新たな発見と提言

これまでに見たもの

最近ようやく社外のポストモーテムを読み始めることができている。良いポストモーテムとはなにかというのが自分の言葉で語れるようになったと感じた頃合いで社内の障害一覧からどれかピックアップして読んでいく活動に入っていきたいと思っている。あまり社外のポストモーテムのリンクを知らないので、これ良かったよというポストモーテムをご存じの方がいたら教えてもらえると嬉しい。

結婚式と新婚旅行でハワイに行ってきた

ハワイに行くのも、一週間仕事を休んで海外のリゾート地に行くのも初めてだった。ハワイはとても良くて滞在時間が足りないくらいだった。仕事に関する通知を軒並みオフにして行ったのもあり、余計に良さを感じた。COVID-19の影響で、空港もラウンジも入国審査も、ホノルル市内もガラガラで待つストレスが極端に少なかったことも良かった。 結婚式の日まではとても天候もよく、式場周辺の公園での撮影も式もすべて良かった。結婚式関係の写真は特に貼りません。

カロリーも大変良く摂りました。エッグベネディクトという料理がうまいことを知った。再現したい。

嵐が来た様子

嵐が来たことで僕が唯一オプショナルツアーで希望した飛行機操縦体験がキャンセルになった(次回ハワイに行く理由にすることにする)ことと、COVID-19の影響がハワイにもやってきて、ハワイ最後の夜はレストランがテイクアウト対応を始めたりと、全てが良い状況と言える訳ではなかった。ちょうど僕らが帰国した頃、ハワイアン航空の一部路線(ちょうど両親が乗ってきた新千歳-ホノルル便など)が欠航となることが発表されたり、数日前まで滞在していたホテルが営業停止することになったりと、かなりギリギリのタイミングだった。

出発前にキャンセルすることも考えたのだが、いつまで延期していいのかわからないことなどから、予定通り行くことにしたのだった。不要不急ではないし。渡航自粛が出る以外のキャンセルだと、キャンセル料を取られることも気になっていた(航空会社のキャンセル料はかからないことがわかっていた)。誰かに言われて行くのをやめてしまったら、ずっと自分たちの気持ちが晴れないだろうなとも思った。こんな状況だったけれどハワイにいくことで、とても解放感を味わうことができたし、リフレッシュすることができたので良かったと思う。

リゾート地でゆっくりするという楽しみが少しわかった気がした。今後はこうしてゆっくりする選択を増やしていきたい。

その他の話題

トイル撲滅活動にリスペクトや感謝をしよう

もとよりトイルという単語自体の意味が苦役であるのだから、トイル撲滅活動つまり苦役に立ち向かう活動については簡単などと軽んじることは行われてはならない。と思う。

むしろ周囲からはリスペクトや感謝が返ってくることを期待すると、トイルと立ち向かった担当者としては思うのである。
SRE本にも、トイルによりキャリアの停滞や、モラルの低下が引き起こされると書いてある。燃え尽きという単語も見えた。
リスペクトや感謝を欠いている態度が続くと、担当者はさらに苦しむこととなり、学習的無力感を増していき、トイルを無視したり、退職リスクを高めることとなるのではないか。

トイル撲滅活動にリスペクトや感謝をしよう。