使用 AI 和 Google 腳本在 Gmail 垃圾郵件資料夾中尋找合法電子郵件

已發表: 2024-06-08

Gmail 中的誤報並不常見,但也有可能發生,這意味著重要的電子郵件可能會錯誤地進入您的垃圾郵件資料夾。 當您每天處理數百封垃圾郵件時,識別這些合法電子郵件變得更加困難。

您可以在 Gmail 中建立過濾器,這樣來自特定寄件者或帶有某些關鍵字的電子郵件就不會被標記為垃圾郵件。 但這些過濾器顯然不適用於來自新的或未知寄件者的電子郵件。

在 Gmail 垃圾郵件中尋找錯誤分類的郵件

如果我們使用人工智慧來分析 Gmail 中的垃圾郵件並預測哪些郵件可能是誤報,會怎麼樣? 有了這個錯誤分類的電子郵件列表,我們可以自動將這些電子郵件移至收件匣或產生報告以供手動審核。

以下是從 Gmail 產生的範例報告。 它包括垃圾郵件分數較低的電子郵件列表,這些電子郵件可能是合法的,應移至收件匣。 該報告還包括以您的首選語言顯示的電子郵件內容摘要。

Gmail Spam Summary

首先,開啟此 Google 腳本並將其複製到您的 Google 雲端硬碟中。 切換到 Apps 腳本編輯器並提供您的電子郵件地址、OpenAI API 金鑰以及電子郵件摘要的首選語言。

從下拉清單中選擇reportFalsePositives函數,然後按一下播放按鈕運行腳本。 它將搜尋您的 Gmail 帳戶中未讀的垃圾郵件,使用 OpenAI 的 API 進行分析,並向您發送垃圾郵件分數較低的電子郵件報告。

如果您想定期自動執行此腳本,請前往 Google Apps 腳本編輯器中的「觸發器」選單,並設定時間驅動的觸發器以每天執行此腳本一次,如下所示。 您也可以選擇一天中希望接收報告的時間。

Google Script - Time Trigger

AI 垃圾郵件分類的工作原理 - 技術部分

如果您想知道該腳本是如何運作的,這裡有一個簡短的概述:

Gmail 腳本使用 Gmail API 搜尋 Gmail 帳戶中未讀的垃圾郵件。 然後,它將電子郵件內容傳送到 OpenAI 的 API,以對垃圾郵件評分進行分類並以您的首選語言產生摘要。 垃圾郵件分數較低的電子郵件可能是誤報,可以移至收件匣。

1. 使用者配置

您可以提供用於傳送報告的電子郵件地址、您的 OpenAI API 金鑰、您首選的 LLM 模型以及電子郵件摘要的語言。

 // Basic configuration const USER_EMAIL = '[email protected]' ; // Email address to send the report to const OPENAI_API_KEY = 'sk-proj-123' ; // API key for OpenAI const OPENAI_MODEL = 'gpt-4o' ; // Model name to use with OpenAI const USER_LANGUAGE = 'English' ; // Language for the email summary

2. 在 Gmail 垃圾郵件資料夾中尋找未讀電子郵件

我們使用紀元時間來尋找過去 24 小時內到達且仍未閱讀的垃圾郵件。

 const HOURS_AGO = 24 ; // Time frame to search for emails (in hours) const MAX_THREADS = 25 ; // Maximum number of email threads to process const getSpamThreads_ = ( ) => { const epoch = ( date ) => Math . floor ( date . getTime ( ) / 1000 ) ; const beforeDate = new Date ( ) ; const afterDate = new Date ( ) ; afterDate . setHours ( afterDate . getHours ( ) - HOURS_AGO ) ; const searchQuery = ` is:unread in:spam after: ${ epoch ( afterDate ) } before: ${ epoch ( beforeDate ) } ` ; return GmailApp . search ( searchQuery , 0 , MAX_THREADS ) ; } ;

3. 為 OpenAI 模型建立提示

我們使用電子郵件建立 OpenAI 模型的提示。 此提示要求 AI 模型分析電子郵件內容並以 0 到 10 的範圍指派垃圾郵件分數。

 const SYSTEM_PROMPT = ` You are an AI email classifier. Given the content of an email, analyze it and assign a spam score on a scale from 0 to 10, where 0 indicates a legitimate email and 10 indicates a definite spam email. Provide a short summary of the email in ${ USER_LANGUAGE } . Your response should be in JSON format. ` ; const MAX_BODY_LENGTH = 200 ; // Maximum length of email body to include in the AI prompt const getMessagePrompt_ = ( message ) => { const body = message . getPlainBody ( ) . replace ( / https?:\/\/[^\s>]+ / g , '' ) . replace ( / [\n\r\t] / g , ' ' ) . replace ( / \s+ / g , ' ' ) . trim ( ) ; // remove all URLs, and whitespace characters return [ ` Subject: ${ message . getSubject ( ) } ` , ` Sender: ${ message . getFrom ( ) } ` , ` Body: ${ body . substring ( 0 , MAX_BODY_LENGTH ) } ` , ] . join ( '\n' ) ; } ;

4.呼叫OpenAI API取得垃圾郵件評分

我們將訊息提示傳遞給 OpenAI API 並取得垃圾郵件分數和電子郵件內容摘要。 垃圾郵件分數用於確定電子郵件是否誤報。

tokens變數追蹤 OpenAI API 呼叫中使用的令牌數量,並包含在電子郵件報告中。 您可以使用此資訊來監控您的 API 使用情況。

 let tokens = 0 ; const getMessageScore_ = ( messagePrompt ) => { const apiUrl = ` https://api.openai.com/v1/chat/completions ` ; const headers = { 'Content-Type' : 'application/json' , Authorization : ` Bearer ${ OPENAI_API_KEY } ` , } ; const response = UrlFetchApp . fetch ( apiUrl , { method : 'POST' , headers , payload : JSON . stringify ( { model : OPENAI_MODEL , messages : [ { role : 'system' , content : SYSTEM_PROMPT } , { role : 'user' , content : messagePrompt } , ] , temperature : 0.2 , max_tokens : 124 , response_format : { type : 'json_object' } , } ) , } ) ; const data = JSON . parse ( response . getContentText ( ) ) ; tokens += data . usage . total_tokens ; const content = JSON . parse ( data . choices [ 0 ] . message . content ) ; return content ; } ;

5. 處理垃圾郵件並透過電子郵件發送報告

您可以手動執行此 Google 腳本,也可以設定 cron 觸發器以定期自動執行它。 它將垃圾郵件標記為已讀,這樣就不會再次處理它們。

 const SPAM_THRESHOLD = 2 ; // Threshold for spam score to include in the report const reportFalsePositives = ( ) => { const html = [ ] ; const threads = getSpamThreads_ ( ) ; for ( let i = 0 ; i < threads . length ; i += 1 ) { const [ message ] = threads [ i ] . getMessages ( ) ; const messagePrompt = getMessagePrompt_ ( message ) ; // Get the spam score and summary from OpenAI const { spam_score , summary } = getMessageScore_ ( messagePrompt ) ; if ( spam_score <= SPAM_THRESHOLD ) { // Add email message to the report if the spam score is below the threshold html . push ( ` <tr><td> ${ message . getFrom ( ) } </td> <td> ${ summary } </td></tr> ` ) ; } } threads . forEach ( ( thread ) => thread . markRead ( ) ) ; // Mark all processed emails as read if ( html . length > 0 ) { const htmlBody = [ ` <table border="1"> ` , '<tr><th>Email Sender</th><th>Summary</th></tr>' , html . join ( '' ) , '</table>' , ] . join ( '' ) ; const subject = ` Gmail Spam Report - ${ tokens } tokens used ` ; GmailApp . sendEmail ( USER_EMAIL , subject , '' , { htmlBody } ) ; } } ;

另請參閱:驗證您的 Gmail 郵件