この記事関して
テスト自動化ツールT-DASHでメールの二要素認証を突破するカスタム動作を作成しました。
下記のような認証コードを基にログインしたい場合
作成したテストシナリオ
今回の作成したSyncファイル
■参考
プロジェクトファイルをインポートしよう
カスタム動作ファイルをインポートしよう
最新のメールの本文を取得する
MailLibrary.py
def get_email_body_python(imap_server, username, password):
"""
最新のメールの本文を取得する。
Args:
imap_server (str): IMAPサーバーのアドレス
username (str): ユーザー名
password (str): パスワード
Returns:
str: メール本文
"""
# IMAPサーバーに接続
mail = imaplib.IMAP4_SSL(imap_server)
# ログイン
mail.login(username, password)
# メールボックスを選択
mail.select("inbox")
# すべてのメールのUIDを取得
status, messages = mail.uid('search', None, "ALL")
mail_ids = messages[0].split()
# 最新のメールを取得する場合
latest_email_uid = mail_ids[-1]
# メールのUIDを使用して、メールのデータを取得
status, msg_data = mail.uid('fetch', latest_email_uid, '(RFC822)')
# メールをパース
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_bytes(response_part[1])
# メールのヘッダーをデコードして表示
def decode_mime_words(s):
return ''.join(
word.decode(encoding or 'utf-8') if isinstance(word, bytes) else word
for word, encoding in email.header.decode_header(s))
subject = decode_mime_words(msg["Subject"])
print("Subject:", subject)
from_ = decode_mime_words(msg.get("From"))
print("From:", from_)
# メールの本文を取得
# メールがマルチパートの場合(HTMLメールや添付ファイルが含まれる場合)
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
content_disposition = str(part.get("Content-Disposition"))
# テキストの本文を取得
# text/plain かつ添付ファイルではないものを指定する。
if content_type == "text/plain" and "attachment" not in content_disposition:
payload = part.get_payload(decode=True)
if payload:
charset = part.get_content_charset()
if charset is None:
result = chardet.detect(payload)
charset = result['encoding']
try:
body = payload.decode(charset)
print("Body:", body)
except Exception as e:
print(f"Failed to decode part: {e}")
# メールがマルチパートでない場合(テキストメールの場合など)
else:
payload = msg.get_payload(decode=True)
if payload:
charset = msg.get_content_charset()
if charset is None:
result = chardet.detect(payload)
charset = result['encoding']
try:
body = payload.decode(charset)
print("Body:", body)
except Exception as e:
print(f"Failed to decode body: {e}")
# ログアウト
mail.logout()
return body
メール本文の内容を正規表現で成形する
正規表現チェッカーなどでメール本文に対してどの値を抜き出したいか調整してください。
https://weblabo.oscasierra.net/tools/regex/
正規表現で\は2つ書く必要があります。Pythonに渡す際のエスケープの問題で
※T-DASH上では¥¥表示されます
■手順
「認証コード:(\\d{6})」での正規表現でメール本文の内容を成形する
■OK
「認証コード:(\\d{6})」
■NG
「認証コード:(\d{6})」
MailLibrary.py
def extract_pattern(mail_body, pattern):
"""
メール本文から指定された正規表現パターンに一致する部分を抽出します。
Args:
mail_body (str): メール本文
pattern (str): 抽出したい正規表現パターン
Returns:
str: 抽出された文字列または None
"""
match = re.search(pattern, mail_body)
if match:
return match.group(1)
else:
BuiltIn().fail(f'正規表現 "{pattern}" に一致する値が見つかりませんでした。')
二要素認証情報を入力する
メール本文の内容を正規表現で成形する
で取得した値は${6桁数字の二要素}
という変数に保持されるので、認証欄に入力する操作をしてください。
最後に
・robotframework-imaplibraryも使用してみましたが本文のエンコードがされないのでPythonで自作しました。
・IMAPのサーバー情報を公開していないメーラーも多いので汎用的には使いづらいかもしれません。(OutlookやGmailは公開されていないぽい・・)