ホームページ >バックエンド開発 >Python チュートリアル >あなたのマーケティングメールはスパムになってしまいますか?それを調べるためのツールを構築しました

あなたのマーケティングメールはスパムになってしまいますか?それを調べるためのツールを構築しました

Susan Sarandon
Susan Sarandonオリジナル
2024-12-31 09:47:10169ブラウズ

電子メール マーケティング キャンペーンを実行する場合、最大の課題の 1 つは、メッセージがスパム フォルダーではなく受信トレイに確実に届くようにすることです。

この投稿では、あなたのメールがスパムとしてマークされるかどうか、またスパムとしてマークされる理由を検証できるツールを構築します。
このツールは API 形式でオンラインでデプロイされるため、ワークフローに統合できます。

スパム検証の背後にある秘密

Apache SpamAssassin は、Apache Software Foundation によって管理されているオープンソースのスパム検出プラットフォームであり、多くの電子メール クライアントや電子メール フィルタリング ツールでメッセージをスパムとして分類するために広く使用されているツールです。

多数のルール、ベイジアン フィルタリング、およびネットワーク テストを使用して、特定の電子メールにスパムの「スコア」を割り当てます。一般に、スコア 5 以上のメールはスパムとしてフラグが立てられるリスクが高くなります。

Apache SpamAssassin はスパム検出ソフトウェアであるため、電子メールがスパムとしてフラグ付けされるかどうかを判断するために使用することもできます。

SpamAssassin のスコアリングは透明性があり、十分に文書化されているため、電子メールのどの側面が高いスパム スコアを引き起こしているかを正確に特定し、文章を改善するために自信を持って使用できます。

SpamAssassin を使用してメールを検証する方法

SpamAssassin は Linux システム上で実行するように設計されています。 Linux OS をインストールして実行するには、Linux OS を使用するか、Docker コンテナを作成する必要があります。

Debian または Ubuntu システムでは、次のコマンドを使用して SpamAssassin をインストールします。

apt-get update && apt-get install -y spamassassin
sa-update

sa-update コマンドは、SpamAssassin のルールが最新であることを保証します。

インストールすると、電子メール メッセージを SpamAssassin のコマンドライン ツールにパイプすることができます。出力には、スパム スコアを含む注釈付きバージョンの電子メールが含まれており、どのルールがトリガーされるかが説明されています。

典型的な使用法は次のようになります:

spamassassin -t < input_email.txt > results.txt

results.txt には、以下のように、SpamAssassin のヘッダーとスコアを含む処理された電子メールが含まれます。

X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on 254.254.254.254
X-Spam-Level: 
X-Spam-Status: No, score=0.2 required=5.0 tests=HTML_MESSAGE,
    MIME_HTML_ONLY,MISSING_MID,NO_RECEIVED,
    NO_RELAYS autolearn=no autolearn_force=no version=4.0.0

// ...

Content analysis details:   (0.2 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 0.1 MISSING_MID            Missing Message-Id: header
-0.0 NO_RECEIVED            Informational: message has no Received headers
-0.0 NO_RELAYS              Informational: message was not relayed via SMTP
 0.0 HTML_MESSAGE           BODY: HTML included in message
 0.1 MIME_HTML_ONLY         BODY: Message only has text/html MIME parts

SpamAssassin を API としてラップする

SpamAssassin は、API としてカプセル化された場合にのみ最大限の可能性を発揮します。この形式により柔軟性が高まり、さまざまなワークフローへの統合が可能になります。

これを想像してください。メールで「送信」をクリックする前に、コンテンツはまず SpamAssassin API に送信されます。電子メールがスパム基準を満たしていないと判断した場合にのみ、続行が許可されます。

件名、html_body、text_body の電子メール フィールドを受け入れる簡単な API を作成しましょう。フィールドを SpamAssassin に渡し、検証結果を返します。

APIの例

from fastapi import FastAPI
from datetime import datetime, timezone
from email.utils import format_datetime
from pydantic import BaseModel
import subprocess

def extract_analysis_details(text):
    lines = text.splitlines()

    start_index = None
    for i, line in enumerate(lines):
        if line.strip().startswith("pts rule"):
            start_index = i
            break

    if start_index is None:
        print("No content analysis details found.")
        return []

    data_lines = lines[start_index+2:]
    parsed_lines = []
    for line in data_lines:
        if line.strip() == "":
            break
        parsed_lines.append(line)

    results = []
    current_entry = None

    split_line = lines[start_index+1]
    pts_split, rule_split, *rest = split_line.strip().split(" ")

    pts_start = 0
    pts_end = pts_start + len(pts_split)

    rule_start = pts_end + 1
    rule_end = rule_start + len(rule_split)

    desc_start = rule_end + 1

    for line in parsed_lines:
        pts_str = line[pts_start:pts_end].strip()
        rule_name_str = line[rule_start:rule_end].strip()
        description_str = line[desc_start:].strip()

        if pts_str == "" and rule_name_str == "" and description_str:
            if current_entry:
                current_entry["description"] += " " + description_str
        else:
            current_entry = {
                "pts": pts_str,
                "rule_name": rule_name_str,
                "description": description_str
            }
            results.append(current_entry)

    return results

app = FastAPI()

class Email(BaseModel):
    subject: str
    html_body: str
    text_body: str

@app.post("/spam_check")
def spam_check(email: Email):
    # assemble the full email
    message = f"""From: example@example.com
To: recipient@example.com
Subject: {email.subject}
Date: {format_datetime(datetime.now(timezone.utc))}
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="__SPAM_ASSASSIN_BOUNDARY__"

--__SPAM_ASSASSIN_BOUNDARY__
Content-Type: text/plain; charset="utf-8"

{email.text_body}

--__SPAM_ASSASSIN_BOUNDARY__
Content-Type: text/html; charset="utf-8"

{email.html_body}

--__SPAM_ASSASSIN_BOUNDARY__--"""

    # Run SpamAssassin and capture the output directly
    output = subprocess.run(["spamassassin", "-t"],
                            input=message.encode('utf-8'),
                            capture_output=True)

    output_str = output.stdout.decode('utf-8', errors='replace')
    details = extract_analysis_details(output_str)
    return {"result": details}

上記のコードでは、完全な結果レポートから採点理由のみを抽出するためのヘルパー関数、extract_analysis_details を定義しました。たとえば、結果から特定のルールを除外するなど、この機能をさらに改善できます。

応答には、SpamAssassin の結果の分析詳細が含まれます。

この入力を例として見てみましょう:

件名

apt-get update && apt-get install -y spamassassin
sa-update

html_body

spamassassin -t < input_email.txt > results.txt

テキスト本文

X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on 254.254.254.254
X-Spam-Level: 
X-Spam-Status: No, score=0.2 required=5.0 tests=HTML_MESSAGE,
    MIME_HTML_ONLY,MISSING_MID,NO_RECEIVED,
    NO_RELAYS autolearn=no autolearn_force=no version=4.0.0

// ...

Content analysis details:   (0.2 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 0.1 MISSING_MID            Missing Message-Id: header
-0.0 NO_RECEIVED            Informational: message has no Received headers
-0.0 NO_RELAYS              Informational: message was not relayed via SMTP
 0.0 HTML_MESSAGE           BODY: HTML included in message
 0.1 MIME_HTML_ONLY         BODY: Message only has text/html MIME parts

応答は次のようになります:

from fastapi import FastAPI
from datetime import datetime, timezone
from email.utils import format_datetime
from pydantic import BaseModel
import subprocess

def extract_analysis_details(text):
    lines = text.splitlines()

    start_index = None
    for i, line in enumerate(lines):
        if line.strip().startswith("pts rule"):
            start_index = i
            break

    if start_index is None:
        print("No content analysis details found.")
        return []

    data_lines = lines[start_index+2:]
    parsed_lines = []
    for line in data_lines:
        if line.strip() == "":
            break
        parsed_lines.append(line)

    results = []
    current_entry = None

    split_line = lines[start_index+1]
    pts_split, rule_split, *rest = split_line.strip().split(" ")

    pts_start = 0
    pts_end = pts_start + len(pts_split)

    rule_start = pts_end + 1
    rule_end = rule_start + len(rule_split)

    desc_start = rule_end + 1

    for line in parsed_lines:
        pts_str = line[pts_start:pts_end].strip()
        rule_name_str = line[rule_start:rule_end].strip()
        description_str = line[desc_start:].strip()

        if pts_str == "" and rule_name_str == "" and description_str:
            if current_entry:
                current_entry["description"] += " " + description_str
        else:
            current_entry = {
                "pts": pts_str,
                "rule_name": rule_name_str,
                "description": description_str
            }
            results.append(current_entry)

    return results

app = FastAPI()

class Email(BaseModel):
    subject: str
    html_body: str
    text_body: str

@app.post("/spam_check")
def spam_check(email: Email):
    # assemble the full email
    message = f"""From: example@example.com
To: recipient@example.com
Subject: {email.subject}
Date: {format_datetime(datetime.now(timezone.utc))}
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="__SPAM_ASSASSIN_BOUNDARY__"

--__SPAM_ASSASSIN_BOUNDARY__
Content-Type: text/plain; charset="utf-8"

{email.text_body}

--__SPAM_ASSASSIN_BOUNDARY__
Content-Type: text/html; charset="utf-8"

{email.html_body}

--__SPAM_ASSASSIN_BOUNDARY__--"""

    # Run SpamAssassin and capture the output directly
    output = subprocess.run(["spamassassin", "-t"],
                            input=message.encode('utf-8'),
                            capture_output=True)

    output_str = output.stdout.decode('utf-8', errors='replace')
    details = extract_analysis_details(output_str)
    return {"result": details}

わかりますか? 「勝者様」はスパムメールでよく使用されるため、検出されます。

API をオンラインでデプロイする

SpamAssassin を実行するには、ソフトウェアがインストールされた Linux 環境が必要です。従来は、デプロイに EC2 インスタンスまたは DigitalOcean ドロップレットが必要になる場合がありましたが、特に使用量が少ない場合は、コストがかかり、面倒な作業になる可能性があります。

サーバーレス プラットフォームに関しては、SpamAssassin のようなシステム パッケージをインストールできません。

Leapcell はこの仕事を完璧に処理できます。

Leapcell を使用すると、SpamAssassin のようなシステム パッケージをデプロイしながら、サービスをサーバーレスに保つことができます。料金は呼び出しに対してのみ発生し、通常は安くなります。

Leapcell への API のデプロイは非常に簡単です。環境をセットアップする必要はありません。 Python イメージをデプロイし、「Build Command」フィールドに適切に入力するだけです。

Will Your Marketing Email End Up in Spam? We Built a Tool to Find Out

デプロイすると、スパムを検証するための API が作成されます。 API が呼び出されるたびに、SpamAssassin が実行され、電子メールにスコアが付けられ、スコアが返されます。

Will Your Marketing Email End Up in Spam? We Built a Tool to Find Out

ブログをお読みください

以上があなたのマーケティングメールはスパムになってしまいますか?それを調べるためのツールを構築しましたの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。