Spam Email Check mit dem OpenAI API

Vorab einige Hinweise: Der nachfolgende Artikel bezieht sich auf ein ‚Proof of Concept‘ und ist nicht als fertiges Produkt zu verstehen! Er zeigt welch faszinierende Möglichkeiten es heutzutage gibt und kann unter Umständen als Rumpf für eine eigene Entwicklung verwendet werden.

Wichtige Hinweise:

  • Wenn Ihr Eure Programme mit Hilfe von OpenAI intelligent machen wollt, so geht das im Moment immer nur mit einem API Key. Um diesen zu bekommen benötigt Ihr einen Account bei OpenAI und müsst Eure Kreditkartendaten hinterlegen, so dass, je nach dem wie intensiv Ihr OpenAI nutzt, ein bestimmter Betrag monatlich von der Karte abgebucht werden kann.

  • Die Kosten hängen davon ab welches Model Ihr wie intensiv nutzt! Über die Preise könnt Ihr Euch hier informieren und wie Ihr den API Key bekommt hier.

  • Im dargestellten Code wird der gesamte Body der Email zum eingestellten Model übertragen. Das ist natürlich datenschutztechnisch höchst fragwürdig! Ihr müsst für Euch selbst einschätzen, ob ihr es riskieren wollt, für Tests dieses Risiko einzugehen.

Was ist das Besondere an diesem Artikel?

Der Ansatz eine KI und hier insbesondere ChatGPT, also GPT 3.5 oder GPT 4, zur Überprüfung von Emails nach Spam zu verwenden und die Programmierung des dafür notwendigen Programms ebenfalls durch ChatGPT in Python!

Die Idee

Wir sind ja vermutlich alle nicht davor verschont gelegentlich von Spam Emails betroffen zu sein. Ich habe mich zwar daran gewöhnt und nutze bei meinem Email Programm Thunderbird die Möglichkeit solche Emails als Junk zu markieren, so dass ähnliche Emails vielleicht in Zukunft automatisch heraus gefiltert werden. Trotzdem bekomme ich nach wie vor viele Spam Emails. Beim Nachdenken darüber wie ich der Flut her werden könnte, ist mir die Idee gekommen einfach einmal ChatGPT zu fragen, ob der Body der Email auf Spam hindeutet!

Also warum nicht die geballte Intelligenz von GPT-3.5 oder GPT-4 nutzen um endgültig und eindeutig zu wissen, ob eine Email Spam ist oder nicht? Bei genauerer Überlegung stellt sich die Frage ob das wirklich so eine tolle Idee ist. Denn vermutlich ist ChatGPT nicht auf derartige Aufgaben trainiert und zum anderen stellt sich die Frage, was passiert, würde jeder Email Anwender jede seiner Emails mit ChatGPT auf Spam testen? Das würde ChatGPT vermutlich total überlasten!

Trotzdem ist es eine sehr interessante Frage und sollte auf jeden Fall einmal ausprobiert werden. Und die dabei verwendeten Techniken könnte man auch einsetzen, um eine speziell für Spam trainierte KI auf einem Server aufzusetzen, der das dann für eine geringe Gebühr erledigt. Gerade für Firmen könnte es interessant sein, innerhalb der Firma über solch einen Server zu verfügen, mit dem es dann möglich ist kostengünstig Emails auf Spam hin zu überprüfen.

Im nachfolgenden Text solltet Ihr beim Lesen immer darauf achten, dass ich hier ChatGPT auf 2 verschiedenen Ebenen verwende. Einmal nutze ich über Firefox die Webseite und erarbeite interaktiv mit GPT-4 den Programmcode. Und zum anderen nutzt dann dieser Programmcode die API von OpenAI!

Implementierung

Aber leichter gedacht als getan. Zuerst wollte ich ein Plugin für Thunderbird entwickeln. Mit Plugins kenne ich mich aber überhaupt nicht aus und bat darum ChatGPT mir einen Vorschlag zu entwickeln. Tatsächlich gelang es ChatGPT auch ein in JavaScript geschriebenes Plugin zu bauen, welches von Thunderbird akzeptiert wurde. Aber in Details bekam ich es in der kurzen Zeit, die ich dafür aufwenden wollte, nicht hin. Leider habe ich dazu keine Beispiele mehr und kann sie Euch nicht zeigen.

Da ich wusste dass ChatGPT ziemlich gut mit Python ist, habe ich es anschließend damit probiert. Und siehe da, so gelang es mir relativ schnell einen funktionierenden Prototyp zu bekommen. Das ist jetzt kein komplett fertiges Tool für Euch, aber ein funktionierender Rumpf auf dem ihr aufbauen könnt. Das meiste habe ich mir von ChatGPT geben lassen und selbst nur noch einige Details nachgearbeitet.

Wenn Ihr Eure Programme mit Hilfe von OpenAI intelligent machen wollt, so geht das im Moment immer nur mit einem API Key. Um diesen zu bekommen benötigt Ihr einen Account bei OpenAI und müsst Eure Kreditkartendaten hinterlegen, so dass, je nach dem wie intensiv Ihr OpenAI nutzt, ein bestimmter Betrag monatlich von der Karte abgebucht werden kann.

Damit das Programm überhaupt arbeiten kann, müsst Ihr Euren API Key am besten unter ‚Systemeigenschaften→Umgebungsvariablen’ als Systemvariable mit dem Namen ‚OPENAI_API_KEY‘ einrichten! Für mich ist das ideal, da ich so leicht auf den Key von allen von mir verwendeten Programmiersprachen aus zugreifen kann. Zum Beispiel von Lazarus und Python aus. Theoretisch könnt Ihr den Key auch direkt im Programm eingeben, aber das ist definitiv nicht so cool! Bzw. wenn Ihr einmal Euren Key ändern müsst, müsst Ihr auch alle Eure Programme anpassen.

Ich zeige Euch hier nur wie es generell funktioniert. Ihr könnt damit experimentieren und das Programm beliebig erweitern. Zum Beispiel könntet Ihr als Spam erkannte Emails automatisch löschen.

Das Programm teilt sich in 2 Teile auf.

email_client.py

Damit wird direkt der Emailserver angesprochen, die dort noch nicht abgeholten Emails gelesen, der Body jeder einzelnen Email extrahiert und mit Hilfe der zweiten Python Datei ‚email_client_gpt.py‘ zu ChatGPT zum Prüfen gesendet. Ich bekomme dann ein ‚[Ja]‘ oder ein ‚[Nein]‘ zurück.

import imaplib
import email
from email.header import decode_header
from typing import Tuple
from email_client_gpt import generate_chat_completion

def processBody (body_text):
    system_message = "Du bist ein Spam Email Checker und antwortest nur mit den Zeichen '[Ja]' für ist Scam Email oder mit '[Nein]' falls nicht!"
    question = "Ist diese Email ein Scam: '" + body_text + "'?"
    response_text = generate_chat_completion(question, system_message=system_message)
    print (response_text)
    
def scanEmails (username, password, imap_url):
    print(username)
    # Verbindung zum IMAP-Server herstellen
    mail = imaplib.IMAP4_SSL(imap_url)
    mail.login(username, password)
    mail.select('inbox')
    # E-Mails abrufen
    status, messages = mail.search(None, 'ALL')
    if status == 'OK':
        for num in messages[0].split():
            status, data = mail.fetch(num, '(RFC822)')
            if status == 'OK':
                # Hier gehen wir sicher, dass die Daten vom Typ bytes sind
                for response_part in data:
                    if isinstance(response_part, Tuple):
                        msg = email.message_from_bytes(response_part[1])
                        subject, encoding = decode_header(msg['subject'])[0]
                        if isinstance(subject, bytes):
                            subject = subject.decode(encoding) if encoding else subject.decode()
                        print('Subject:', subject)

                        # E-Mail-Body extrahieren
                        if msg.is_multipart():
                            for part in msg.walk():
                                if part.get_content_type() == "text/plain":
                                    body = part.get_payload(decode=True)
                                    body_text = body.decode(encoding, errors='replace') if encoding else body.decode(errors='replace')
                                    processBody(body_text)
                        else:
                            body = msg.get_payload(decode=True)
                            body_text = body.decode(encoding, errors='replace') if encoding else body.decode(errors='replace')                        #print('Body:', body_text)
                            processBody(body_text)
    else:
        print("Failed to retrieve messages.")

    # Logout
    mail.logout()
    print()
    
scanEmails('email@steinlaus.de', 'password', 'server')

email_client_gpt.py

Dies ist der Teil der mit ChatGPT kommuniziert. Ihr könnt Ihn auch für andere Aufgaben verwenden.

In Zeile 8 könnt Ihr ein anderes Model auswählen, indem Ihr ‚gpt-3.5-turbo-16k‘ durch den Namen eines anderen Model ersetzt. Aber vorsichtig: Andere Models können andere Preise haben und schnell seid Ihr beim Test ein paar Cent (oder gar Dollar) zu viel los geworden!

import os
import requests
import json

API_KEY = os.getenv("OPENAI_API_KEY")
API_ENDPOINT = "https://api.openai.com/v1/chat/completions"

def generate_chat_completion(question, system_message=None, model="gpt-3.5-turbo-16k", temperature=1, max_tokens=None):
    messages = []
    if system_message:
        messages.append({"role": "system", "content": system_message})
    
    new_message = {"role": "user", "content": question}
    messages.append(new_message)
    
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {API_KEY}",
    }

    data = {
        "model": model,
        "messages": messages,
        "temperature": temperature,
    }


    if max_tokens is not None:
        data["max_tokens"] = max_tokens

    response = requests.post(API_ENDPOINT, headers=headers, data=json.dumps(data))

    if response.status_code == 200:
        return response.json()["choices"][0]["message"]["content"]
    else:
        raise Exception(f"Error {response.status_code}: {response.text}")
  

Viel Spaß beim Experimentieren und Ausprobieren!

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert