Maison >développement back-end >Tutoriel Python >Votre e-mail marketing finira-t-il dans le spam ? Nous avons créé un outil pour le découvrir

Votre e-mail marketing finira-t-il dans le spam ? Nous avons créé un outil pour le découvrir

Susan Sarandon
Susan Sarandonoriginal
2024-12-31 09:47:10169parcourir

Lors de l'exécution de campagnes de marketing par e-mail, l'un des plus grands défis consiste à garantir que vos messages parviennent dans la boîte de réception plutôt que dans le dossier spam.

Dans cet article, nous allons créer un outil qui pourra valider si votre e-mail sera marqué comme spam et pourquoi il est marqué ainsi.
Cet outil serait sous forme d'API et déployé en ligne, afin de pouvoir être intégré à votre workflow.

Le secret derrière la validation du spam

Apache SpamAssassin est une plate-forme open source de détection de spam gérée par Apache Software Foundation, qui est un outil largement utilisé par de nombreux clients de messagerie et outils de filtrage de courrier électronique pour classer les messages comme spam.

Il utilise une multitude de règles, un filtrage bayésien et des tests réseau pour attribuer un « score » de spam à un e-mail donné. En règle générale, un e-mail ayant un score de 5 ou plus présente un risque élevé d'être signalé comme spam.

Puisqu'Apache SpamAssassin est un logiciel de détection de spam, il peut également être utilisé pour savoir si votre e-mail sera signalé comme spam.

Le score de SpamAssassin est transparent et bien documenté, vous pouvez l'utiliser en toute confiance pour identifier exactement les aspects de votre courrier électronique qui provoquent des scores de spam élevés et améliorer votre rédaction.

Comment valider votre e-mail à l'aide de SpamAssassin

SpamAssassin est conçu pour fonctionner sur les systèmes Linux. Vous aurez besoin d'un système d'exploitation Linux ou créerez un conteneur Docker pour l'installer et l'exécuter.

Sur les systèmes Debian ou Ubuntu, installez SpamAssassin avec :

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

La commande sa-update garantit que les règles de SpamAssassin sont à jour.

Une fois installé, vous pouvez diriger un message électronique vers l'outil de ligne de commande de SpamAssassin. Le résultat comprend une version annotée de l'e-mail avec les scores de spam et explique quelles règles sont déclenchées.

Une utilisation typique pourrait ressembler à ceci :

spamassassin -t < input_email.txt > results.txt

results.txt contiendra alors l'e-mail traité avec les en-têtes et les scores de SpamAssassin, comme ci-dessous :

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

Envelopper SpamAssassin en tant qu'API

SpamAssassin n'atteint son potentiel maximum que lorsqu'il est encapsulé sous forme d'API, car cette forme le rend plus flexible et permet l'intégration dans divers flux de travail.

Imaginez ceci : avant de cliquer sur « Envoyer » sur votre e-mail, le contenu est d'abord envoyé à l'API SpamAssassin. Ce n'est que s'il détermine que l'e-mail ne répond pas aux critères de spam qu'il est autorisé à continuer.

Créons une API simple qui accepte ces champs de courrier électronique : sujet, html_body et text_body. Il transmettra les champs à SpamAssassin et renverra le résultat de la validation.

Exemple d'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}

Dans le code ci-dessus, nous avons défini une fonction d'assistance, extract_analysis_details, pour extraire uniquement les raisons de notation du rapport de résultats complet. Vous pouvez encore améliorer cette fonction, par exemple en filtrant certaines règles du résultat.

La réponse contiendra les détails de l’analyse des résultats de SpamAssassin.

Prenons cette entrée comme exemple :

sujet

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

html_body

spamassassin -t < input_email.txt > results.txt

text_body

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

La réponse serait comme ceci :

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}

Vous voyez ? "Cher gagnant" est détecté car il est couramment utilisé dans les courriers indésirables.

Déployer l'API en ligne

L'exécution de SpamAssassin nécessite un environnement Linux avec le logiciel installé. Traditionnellement, vous pourriez avoir besoin d'une instance EC2 ou d'un droplet DigitalOcean à déployer, ce qui peut être coûteux et fastidieux, surtout si votre utilisation est faible.

Quant aux plates-formes sans serveur, elles ne vous permettent tout simplement pas d'installer des packages système comme SpamAssassin.

Leapcell peut parfaitement gérer ce travail.

Avec Leapcell, vous pouvez déployer n'importe quel package système comme SpamAssassin, tout en gardant le service sans serveur - vous ne payez que pour les invocations, ce qui est généralement moins cher.

Déployer l'API sur Leapcell est très simple. Vous n'avez pas besoin de configurer d'environnement. Déployez simplement une image Python et remplissez correctement le champ "Build Command".

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

Une fois déployé, vous disposerez d'une API pour la validation du spam. Chaque fois que l'API est invoquée, elle exécutera SpamAssassin, évaluera l'e-mail et renverra le score.

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

À lire sur notre blog

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:PROJET- ( MASH AI )Article suivant:PROJET- ( MASH AI )