Dmarcのレポートの確認が面倒!〜自動でFailだけをチャットに通知

レポートの確認が面倒
メールのセキュリティを高めるため、Dmarc等の設定を行いました。レポートが毎日2通くらい来ます。
それくらいはいいのですが、圧縮された形式でxmlファイルがきます。解凍して、xmlのチェックめんどくさいです。
レポートの確認を簡単にするために
“dmarkのレポートが圧縮されたメールで毎日きます。その内容をダウンロードして解凍して、failなど気にすべき内容が届いたらその内容を要約して、Googleworkspaceのチャットに通知する方法を教えて下さい"
以下のステップでスクリプトを作成します。
- Gmailから抽出: 特定の条件(件名や送信元)でDMARCレポートのメールを検索。
- 解凍と解析: 添付ファイル(
.zipまたは.gz)を解凍し、XMLの内容を読み取る。 - 判定:
dkimやspfがfailになっている件数をカウント。 - 通知: 問題がある場合のみ、Google Chat のスペースに要約を送信。
実際には以下の流れ
- Google Chat の設定 (Webhook URLの取得)
- Google Apps Script の作成
- 自動実行(トリガー)の設定
Webhookから
Webhook(ウェブフック)は、特定のイベント(フォーム送信、チャット投稿など)が発生した際に、Webサービスが自動的に別のサービスへリアルタイムにデータを送信(通知)する仕組みです。
Google Chat の設定 (Webhook URLの取得)
まず、通知先となるGoogle Chatの準備をします。
- 通知したいスペースを開きます。
- スペース名の横の ▽ をクリックし、「アプリと統合」 > 「Webhookを追加」 を選択します。
- 名前(例: DMARC Bot)を入力して保存し、発行された Webhook URL をコピーしておきます。
アプリの統合から。

webhookを使いしました。

このWebhookのURLをGASのコードに含めます。
Gasのコードを書いてもらう
Dmarc Reportの宛先に来たメールを1週間分エラー通知してと頼みました。
/**
* DMARCレポート自動解析・Google Chat通知スクリプト
* 実行日の前日に届いたレポートを対象にします
*/
function processDmarcReports() {
// --- 設定項目 ---
const TARGET_EMAIL = "dmarc-reports@ngy.biz"; // 対象の受信アドレス
const CHAT_WEBHOOK_URL = "ここにGoogle ChatのWebhook URLを貼り付け";
// ----------------
// 1. 実行日の前日の日付を取得 (YYYY/MM/DD形式)
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const dateString = Utilities.formatDate(yesterday, "JST", "yyyy/MM/dd");
// 2. Gmailを検索 (宛先、日付、添付ファイルの有無)
const query = `to:${TARGET_EMAIL} after:${dateString} has:attachment`;
const threads = GmailApp.search(query);
if (threads.length === 0) {
console.log(`${dateString} 以降のDMARCレポートは見つかりませんでした。`);
return;
}
threads.forEach(thread => {
const messages = thread.getMessages();
messages.forEach(message => {
// メールの受信日時が「昨日」であることを厳密にチェック(念のため)
const msgDate = message.getDate();
if (msgDate < yesterday) return;
const attachments = message.getAttachments();
attachments.forEach(attachment => {
let xmlContent = "";
const fileName = attachment.getName().toLowerCase();
try {
// 3. 圧縮ファイルの解凍 (.zip または .gz)
if (fileName.endsWith(".zip")) {
const unzipped = Utilities.unzip(attachment);
xmlContent = unzipped[0].getDataAsString();
} else if (fileName.endsWith(".gz")) {
xmlContent = Utilities.ungzip(attachment).getDataAsString();
} else if (fileName.endsWith(".xml")) {
xmlContent = attachment.getDataAsString();
}
if (xmlContent) {
// 4. XMLの解析と通知
analyzeAndNotify(xmlContent, CHAT_WEBHOOK_URL, message.getSubject());
}
} catch (e) {
console.error(`ファイル名 ${fileName} の処理中にエラー: ${e.message}`);
}
});
});
// 二重通知防止のため、処理したスレッドに既読をつける、またはラベルを貼ることを推奨
thread.markRead();
});
}
/**
* XMLを解析して fail があれば Google Chat に送信する
*/
function analyzeAndNotify(xmlString, webhookUrl, subject) {
const document = XmlService.parse(xmlString);
const root = document.getRootElement();
// 名前空間を考慮せず要素を取得(DMARC XMLはシンプルなためgetChildrenで対応可能)
const records = root.getChildren("record");
let totalFail = 0;
let failDetails = "";
records.forEach(record => {
const row = record.getChild("row");
const policyEvaluated = row.getChild("policy_evaluated");
const spf = policyEvaluated.getChild("spf").getText();
const dkim = policyEvaluated.getChild("dkim").getText();
const sourceIp = row.getChild("source_ip").getText();
// SPF または DKIM が fail の場合をカウント
if (spf === "fail" || dkim === "fail") {
totalFail++;
// 通知が長くなりすぎないよう、直近数件のみ詳細を表示
if (totalFail <= 10) {
failDetails += `\n・IP: ${sourceIp} (SPF: ${spf}, DKIM: ${dkim})`;
}
}
});
// 5. 不合格(fail)があった場合のみ Google Chat へ通知
if (totalFail > 0) {
const payload = {
"text": `⚠️ *DMARC Alert*\n*Subject:* ${subject}\n*Result:* Fail が ${totalFail} 件検出されました。\n*Details:* ${failDetails}` + (totalFail > 10 ? "\n(他多数...)" : "")
};
const options = {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify(payload)
};
UrlFetchApp.fetch(webhookUrl, options);
}
}
通知された
無事、実行したら、通知されました!GoogleWorkspaceのチャットに。
Failがちょびちょび出ています!

要因分析もお願いする
どこでエラーが出ているかは、わかりましたが、要因分析もお願いしてみました。

実行時間を指定 〜トリガーの追加
通知はされましたが、毎回自分で実行はしないと思うので、時間が来たら自動的に通知するようにします。
土曜日の夜中に起動して、通知するようにトリガーを設定しました。

実行する関数を選択して、時間を指定していきます。

そしてトリガーが発動したら1週間分エラーレポートが、土曜日に通知されるはずです。
土曜日の朝を迎えての実行結果
朝起きたら、通知されていました!効率化!
過去のFailは出ていますが、最近は、エラー出てなさそう。やったね。また来週の土曜日にどんな通知が来るか楽しみです。これで毎日来るDmarcレポートをついチェックして、時間を無駄にしてしまうことは無さそうです。

感想
毎日来るレポートが圧縮ファイルでは耐えきれませんので、効率化できてよかったです。
こういった複数回のちょっと処理はどんどんAIがなんとかしてくれますね。まあAIというかGASですが。
そんなところで

