使用 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 的范围分配垃圾邮件分数。响应应采用 JSON 格式。

 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 邮件