Amazonアソシエイトでユーザー追加をしたときに送られてくる確認メールにDKIM-Signatureが2つ入っていて、前の記事のLambda関数では動作しなかったので、別のものを参考に作り直した。
参考にしたもの
- https://gist.github.com/skylander86/d75bf010c7685bd3f951d2b6c5a32e7b
- 3年前のものでいくつか動作しないところがあったので変更した
- handler関数名をdefaultのlambda_handlerに変更
- message_from_fileからmessage_from_stringに変更(StreamingBodyがうまく受け取れないので)
- raw_mailをmessage_from_stringに合わせてstringに変更
Lambda関数
正規表現であちこちこねくり回すよりシンプルになった。
from email import message_from_string
import json
import logging
import os
import re
import boto3
from botocore.exceptions import ClientError
FORWARD_MAPPING = {
'xxxxxxx@example.com': ['xxxxxxxx@gmail.com'],
}
VERIFIED_FROM_EMAIL = os.environ['VERIFIED_FROM_EMAIL'] # An email that is verified by SES to use as From address.
SES_INCOMING_BUCKET = os.environ['SES_INCOMING_BUCKET'] # S3 bucket where SES stores incoming emails.
s3 = boto3.client('s3')
ses = boto3.client('ses')
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
record = event['Records'][0]
assert record['eventSource'] == 'aws:ses'
o = s3.get_object(Bucket=SES_INCOMING_BUCKET, Key=record['ses']['mail']['messageId'])
raw_mail = o['Body'].read().decode('utf-8')
msg = message_from_string(raw_mail)
del msg['DKIM-Signature']
del msg['Sender']
del msg['Return-Path']
original_from = msg['From']
del msg['From']
msg['From'] = re.sub(r'\<.+?\>', '', original_from).strip() + ' <{}>'.format(VERIFIED_FROM_EMAIL)
if not msg['Reply-To']: msg['Reply-To'] = original_from
msg['Return-Path'] = VERIFIED_FROM_EMAIL
msg_string = msg.as_string()
for recipient in record['ses']['receipt']['recipients']:
forwards = FORWARD_MAPPING.get(recipient, [])
if not forwards:
logger.warning('Recipent <{}> is not found in forwarding map. Skipping recipient.'.format(recipient))
continue
#end if
for address in forwards:
try:
o = ses.send_raw_email(Destinations=[address], RawMessage=dict(Data=msg_string))
logger.info('Forwarded email for <{}> to <{}>. SendRawEmail response={}'.format(recipient, address, json.dumps(o)))
except ClientError as e: logger.error('Client error while forwarding email for <{}> to <{}>: {}'.format(recipient, address, e))