PR

ローカル環境から AWS へ!Gmail スケジュール連携ツール移行ガイド – 第3段階:Gmail からのメール本文の解析とスケジュール情報の抽出

モニタにPythonコードが表示され、AWSのロゴとGmail、Google Calendarのアイコンが配置されたイメージ。サーバーレス移行と連携処理の概念を示す。 技術・IT
AWS LambdaによるGmail連携スケジュール管理のサーバーレス化イメージ

前回の第2段階では、AWS Lambda を使って Gmail から未読メールを取得し、件名・送信者・本文の情報を取得する処理を構築しました。

今回は、取得したメールの本文を解析し、スケジュール情報(開始・終了時刻、タイトル、参加者、場所)を抽出する処理を実装します。Garoon などのスケジュール通知メールに対応するため、正規表現(Regex)を活用して、柔軟に情報を取り出す仕組みを作っていきます。

前回の記事はこちら↓

1. メール本文の構造と解析のアプローチ

Garoon から送られてくるスケジュール通知メールには、日本語で「日時:」「参加者:」「施設:」などの項目が記載されています。これらは形式が一貫していない場合もあるため、正確に情報を取り出すには正規表現が有効です。

そのため、正規表現(Regular Expression, regex)を使って、柔軟に情報を抽出していくのが適しています。

正規表現は、特定のパターンに合致する文字列を検索したり、抽出したりするための記法です。最初は少し難しく感じるかもしれませんが、使いこなせるようになると、テキスト処理が非常に効率的に行えるようになります。

また、メールの形式には以下の2種類があります。

  • プレーンテキスト(text/plain)
  • HTMLメール(text/html)

本記事では、プレーンテキスト形式 (text/plain) のメール本文を対象とし、以下の情報を抽出します。

  • 場所(本文中の「施設」)
  • スケジュールタイトル(件名から)
  • 開始・終了日時(本文中の「日時」項目)
  • 参加者(本文中の「参加者」)

2. メール本文を解析する関数 (garoon_mail_parser.py) の作成

まず、新しいファイル garoon_mail_parser.py を作成します。

Lambda のコードエディタで左のファイルツリーから「+」をクリックし、
「新しいファイルの作成」→ garoon_mail_parser.py と入力して作成します。

以下のコードをファイルに記述してください:

Python

import re
from datetime import datetime

def parse_garoon_mail_new(body, subject):
    """Garoon のメール本文と件名を解析してスケジュール情報を抽出します (新しい形式に対応)。"""
    schedule_info = {
        'start_time': None,
        'end_time': None,
        'title': None,
        'attendees': [],
        'location': ''
    }

    # 件名からタイトルを抽出
    title_match = re.search(r'\[(登録|変更|削除)\] (.*)', subject)
    if title_match:
        schedule_info['title'] = title_match.group(2).strip()
    else:
        schedule_info['title'] = subject.replace('[登録]', '').replace('[変更]', '').replace('[削除]', '').strip()
    
    print(f"件名: {schedule_info['title']}")

    # 日本語形式の日時を抽出
    datetime_match = re.search(
        r'日時\s*:\s*(\d{4}年\d{2}月\d{2}日)[((][^))]+[))]?\s+(\d{2}:\d{2})\s*〜\s*(\d{4}年\d{2}月\d{2}日)[((][^))]+[))]?\s+(\d{2}:\d{2})',
        body
    )

    if datetime_match:
        start_date_str = datetime_match.group(1)
        start_time_str = datetime_match.group(2)
        end_date_str = datetime_match.group(3)
        end_time_str = datetime_match.group(4)

        start_dt = datetime.strptime(start_date_str + ' ' + start_time_str, '%Y年%m月%d日 %H:%M')
        end_dt = datetime.strptime(end_date_str + ' ' + end_time_str, '%Y年%m月%d日 %H:%M')

        schedule_info['start_time'] = start_dt.strftime('%Y-%m-%dT%H:%M:%S+09:00')
        schedule_info['end_time'] = end_dt.strftime('%Y-%m-%dT%H:%M:%S+09:00')

    # 参加者の抽出
    attendees_match = re.search(r'参加者\s*:\s*(.*)', body)
    if attendees_match:
        attendees_str = attendees_match.group(1).strip()
        attendees = [name.strip() for name in attendees_str.split(',') if name.strip()]
        schedule_info['attendees'] = attendees

    # 施設(場所)の抽出
    location_match = re.search(r'施設\s*:\s*(.*)', body)
    if location_match:
        schedule_info['location'] = location_match.group(1).strip()

    return schedule_info

この garoon_mail_parser.py には、この関数はメール本文と件名から、以下の情報を抽出します:

  • 場所
  • 開始日時・終了日時(ISO形式)
  • 件名(タイトル)
  • 参加者

3. main.py から解析関数を呼び出す

次に、main.py を編集し、取得したメール本文を garoon_mail_parser.py の解析関数に渡してスケジュール情報を抽出する処理を追加します。

main.pylambda_handler 関数内の、メール本文を取得した部分に以下のコードを追加します。

Python

lambda_handler 内で、メール本文を取得した後に追加:

for email_id in email_ids:
    msg = fetch_email_data(mail, email_id)
    if msg:
        subject = decode_subject(msg)
        sender = get_sender_email(msg)
        body = get_email_body(msg)
        print(f"ログ: メールを受信しました (ID: {email_id.decode()}, 件名: {subject}, 送信者: {sender})")
        print(f"ログ: メール本文:\n{body}")

        schedule_info = {}
        if sender == secrets.get("garoon_sender"):
            schedule_info = parse_garoon_mail_new(body, subject)
            print(f"ログ: 解析されたスケジュール情報: {schedule_info}")

            # 次の第4段階で Google Calendar に登録する処理を記述

この修正では、以下の処理を追加しています。

  1. メールの送信者が Garoon の送信者 (secrets.get("garoon_sender")) と一致する場合に、本文と件名の解析を行います。
  2. parse_garoon_mail_new 関数を呼び出し、メール本文 (body) と件名 (subject) を渡して解析を行います。
  3. 解析されたスケジュール情報を schedule_info 変数に格納し、ログに出力します。
  4. 抽出したタイトルは、メールの件名から取得するようにしています(必要に応じて本文からも抽出するロジックを追加してください)。

また、main.py の冒頭に、garoon_mail_parser.py から必要な関数をインポートする行を追加します。

Python

import os
import json
from gmail_connector import connect_gmail, select_inbox, search_unread_emails, fetch_email_data, logout_gmail, get_email_body, get_sender_email, decode_subject
from garoon_mail_parser import parse_garoon_mail_new  # ← この行を追加
import boto3

重要: garoon_mail_parser.py で定義した parse_garoon_mail_new 関数を main.py で使用するために、上記の import 文を追加しています。これにより、main.py から parse_garoon_mail_new 関数を呼び出すことができるようになります。

4. 正規表現の調整とエラーハンドリング

メールの本文の形式は、Garoon のバージョンや設定によって異なる可能性があります。もし、上記で記述した正規表現でうまく情報が抽出できない場合は、実際のメール本文の構造に合わせて正規表現を調整する必要があります。

正規表現のテストには、オンラインの正規表現チェッカーなどを利用すると便利です。

ここでは日時解析部分に基本的なエラーハンドリングを実装していますが、他の抽出処理にも必要に応じて追加してください。

以下のようなツールを使うと便利です:

5. Lambda 関数の再デプロイとテスト

main.pygaroon_mail_parser.py を編集したら、Lambda 関数を再度デプロイしてください。その後、実際に Garoon からスケジュール通知メールを送信し、Lambda 関数がトリガーされてログに解析された情報が出力されるか確認してください。

CloudWatch Logs を確認し、解析ログ (ログ: 解析された情報: ...) が正しく出力されているか確認しましょう。もし、期待通りの情報が抽出できていない場合は、garoon_mail_parser.py の正規表現を見直す必要があります。

まとめ

この第3段階では、取得した Gmail のメール本文を解析し、正規表現を使ってスケジュール情報(開始日時、終了日時、タイトル、参加者、場所)を抽出する基本的な処理を実装しました。

メール本文の形式に合わせて正規表現を調整することが、このステップの重要なポイントとなります。

次の第4段階では、抽出したスケジュール情報を Google Calendar に登録する処理を実装していきます。

コメント

タイトルとURLをコピーしました