lambda link

```
import json
import boto3
import urllib.request
import urllib.parse  # URLエンコード用
from datetime import datetime, timezone, timedelta  # timedeltaをインポート

# SNSクライアントを初期化（メール通知用）
sns_client = boto3.client('sns')

# SNSトピックのARNを指定してください
SNS_TOPIC_ARN = 'arn:aws:sns:your-region:your-account-id:your-topic-name'

# ワークフロー（TeamsのWebhookなど）のURLを設定してください
WORKFLOW_URL = 'https://your-workflow-url'

def extract_metrics(configuration):
    """
    メトリクス情報を抽出して文字列にフォーマットします
    """
    metrics = configuration.get('metrics', [])
    metric_list = []
    for metric in metrics:
        metric_info = metric.get('metricStat', {}).get('metric', {})
        namespace = metric_info.get('namespace', '')
        metric_name = metric_info.get('name', '')
        dimensions = metric_info.get('dimensions', {})
        dimensions_str = ', '.join([f"{k}={v}" for k, v in dimensions.items()])
        metric_list.append(f"{namespace}/{metric_name} ({dimensions_str})")
    return '; '.join(metric_list)

def format_timestamp(timestamp_str):
    """
    タイムスタンプ文字列を日本標準時（JST）にフォーマットします
    """
    if timestamp_str:
        try:
            # タイムスタンプを解析（タイムゾーン情報を含む）
            timestamp = datetime.strptime(timestamp_str, '%Y-%m-%dT%H:%M:%S.%f%z')
            # 日本標準時（UTC+9）のタイムゾーンを作成
            jst_timezone = timezone(timedelta(hours=9))
            # タイムゾーンを日本標準時に変換
            jst_time = timestamp.astimezone(jst_timezone)
            return jst_time.strftime('%Y-%m-%d %H:%M:%S %Z')
        except ValueError as e:
            print(f"タイムスタンプの解析エラー: {e}")
            return 'N/A'
    else:
        return 'N/A'

def send_email(message, subject):
    """
    SNSを使用してメールを送信します
    """
    response = sns_client.publish(
        TopicArn=SNS_TOPIC_ARN,
        Message=message,
        Subject=subject
    )
    print('メールを送信しました。メッセージID:')
    print(response['MessageId'])

def send_to_workflow(card_content):
    """
    ワークフローにデータを送信します
    """
    headers = {
        'Content-Type': 'application/json'
    }
    request = urllib.request.Request(WORKFLOW_URL, data=json.dumps(card_content).encode('utf-8'), headers=headers)
    try:
        with urllib.request.urlopen(request) as response:
            response_body = response.read()
            print('ワークフローへのデータ送信に成功しました。')
    except Exception as e:
        print(f"ワークフローへのデータ送信エラー: {e}")

def lambda_handler(event, context):
    """
    AWS Lambdaのエントリポイント
    """
    # デバッグ用にイベントを出力
    print("Received event: " + json.dumps(event))

    # CloudWatch Alarmからのイベントを解析
    alarm_data = event.get('alarmData', {})
    alarm_name = alarm_data.get('alarmName', '')
    state = alarm_data.get('state', {})
    reason = state.get('reason', '')
    timestamp = state.get('timestamp', '')
    region = event.get('region', '')
    configuration = alarm_data.get('configuration', {})
    metrics = extract_metrics(configuration)

    # タイムスタンプをフォーマット
    occurrence_time = format_timestamp(timestamp)

    # アラームのコンソールリンクを作成
    alarm_url = create_alarm_url(region, alarm_name)

    # 小文字に変換して比較を容易にする
    reason_lower = reason.lower()
    alarm_name_lower = alarm_name.lower()

    # メッセージの初期化
    subject = ''
    message = ''
    workflow_data = {}

    # メンションするユーザーの情報を設定（必要に応じて）
    mention_name = 'lihao'       # 要提案のユーザーの表示名
    mention_id = 'user-id'       # 要提案のユーザーのID（AAD Object IDなど）

    # 第一段階のフィルタリング：reasonに特定のキーワードが含まれるかチェック
    if ('no datapoints' in reason_lower) or ('insufficient data' in reason_lower) or ('unknown' in reason_lower):
        # 固定形式のメールAを送信 - データ不明
        subject = '【データ不明】アラームが発生しました'
        message = f'''発生時間：{occurrence_time}
発生アラーム名：{alarm_name}
発生メトリクス：{metrics}

理由：
{reason}

詳細はdevops環境のAWS Cloudwatchコンソールでご確認ください。
リンク：{alarm_url}'''
        # Adaptive Cardを作成（メンションを含む）
        workflow_data = create_adaptive_card_with_mention(subject, occurrence_time, alarm_name, metrics, reason, alarm_url, mention_name, mention_id)

    else:
        # 第二段階のフィルタリング：alarmNameに特定のキーワードが含まれるかチェック
        if 'warning' in alarm_name_lower:
            # 固定形式のメールBを送信 - 警告
            subject = '【警告】アラームが発生しました'
        elif 'danger' in alarm_name_lower:
            # 固定形式のメールCを送信 - 危険
            subject = '【危険】重大なアラームが発生しました'
        else:
            # 固定形式のメールDを送信 - アラーム状態
            subject = '【アラーム状態】アラームが発生しました'

        message = f'''発生時間：{occurrence_time}
発生アラーム名：{alarm_name}
発生メトリクス：{metrics}

理由：
{reason}

詳細はdevops環境のAWS Cloudwatchコンソールでご確認ください。
リンク：{alarm_url}'''
        # Adaptive Cardを作成（メンションを含む）
        workflow_data = create_adaptive_card_with_mention(subject, occurrence_time, alarm_name, metrics, reason, alarm_url, mention_name, mention_id)

    # SNSメールを送信
    send_email(message, subject)

    # ワークフローにデータを送信
    send_to_workflow(workflow_data)

def create_alarm_url(region, alarm_name):
    """
    CloudWatchアラームのコンソールURLを生成します
    """
    # アラーム名をURLエンコード
    encoded_alarm_name = urllib.parse.quote(alarm_name)
    # コンソールのURLを作成
    url = f'https://{region}.console.aws.amazon.com/cloudwatch/home?region={region}#alarmsV2:alarm/{encoded_alarm_name}'
    return url

def create_adaptive_card_with_mention(title, occurrence_time, alarm_name, metrics, reason, alarm_url, mention_name, mention_id):
    """
    Adaptive Cardを作成し、メンションを含めます
    """
    mention_text = f"<at>{mention_name}</at>"

    card = {
        "type": "message",
        "attachments": [
            {
                "contentType": "application/vnd.microsoft.card.adaptive",
                "contentUrl": None,
                "content": {
                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                    "type": "AdaptiveCard",
                    "version": "1.4",
                    "msteams": {
                        "entities": [
                            {
                                "type": "mention",
                                "text": mention_text,
                                "mentioned": {
                                    "id": mention_id,
                                    "name": mention_name
                                }
                            }
                        ]
                    },
                    "body": [
                        {
                            "type": "TextBlock",
                            "text": f"{mention_text} {title}",
                            "size": "Large",
                            "weight": "Bolder",
                            "color": "Attention",
                            "wrap": True
                        },
                        {
                            "type": "FactSet",
                            "facts": [
                                {
                                    "title": "発生時間：",
                                    "value": occurrence_time
                                },
                                {
                                    "title": "発生アラーム名：",
                                    "value": alarm_name
                                },
                                {
                                    "title": "発生メトリクス：",
                                    "value": metrics
                                }
                            ]
                        },
                        {
                            "type": "TextBlock",
                            "text": "理由：",
                            "weight": "Bolder",
                            "wrap": True
                        },
                        {
                            "type": "TextBlock",
                            "text": reason,
                            "wrap": True
                        },
                        {
                            "type": "TextBlock",
                            "text": "詳細はdevops環境のAWS Cloudwatchコンソールでご確認ください。",
                            "wrap": True
                        },
                        {
                            "type": "TextBlock",
                            "text": f"[リンクはこちら]({alarm_url})",
                            "wrap": True
                        }
                    ]
                }
            }
        ]
    }
    return card
```