第二步:探索技术可行性

我的理解

技术可行性探索的核心动作是:先让 GPT 列出多个实现方案及其优缺点,再结合自身场景选取最契合的方案,而不是被动接受 GPT 的第一个建议。本课揭示了一个关键陷阱:GPT 的知识截止日期会导致它对新版 API 和库一无所知,默认回退到旧接口从而生成无法运行的代码。破解之道是将最新 API 文档或示例代码放入 prompt,让 GPT 临时“学习”——这就是文档管理的直接起源。将 GenAI 调用方式从 GUI 迁移到 API,是本步骤最关键的能力跃升,它打开了以编程方式自动化任意 GenAI 任务的大门。

相关链接


原文

Lesson 30 of 68 第二步:探索技术可行性 / Step 2: Explore the technical feasibility 技术路线选型

我们已经有了一个能提升生产力的好产品创意。这个工具遵循一个简单的三步流程:

拉取最新邮件:从我们的 Gmail 收件箱中获取最近的 10 封邮件。

判断是否涉及相关主题:检查这些邮件是否涉及我们感兴趣的主题。在本例中,我们以 GenAI 为例。如果某封邮件与 GenAI 相关,就被视为重要邮件。这一判定标准也可以替换为其他主题或条件。

对重要邮件进行通知:一旦发现重要邮件,就通知我们。

根据每个人的背景与专长不同,某些步骤可能比其他步骤看起来更容易。如果我们对某一步的技术难度不太确定,事先让 GPT 帮忙识别潜在难点并讨论备选方案,往往是个好主意。这里我们只需向 GPT 描述我们想构建什么,并请它做出评估。

示例 Prompt

=======================================================

I want to build a tool to identify the emails mentioning GenAI in my Gmail inbox. Run this every 5 minutes so I can receive notifications on those emails to potentially respond right away. Is it easy to do? What are the options?

=======================================================

示例回复

=======================================================

构建一个工具来监控你的 Gmail 收件箱中是否出现“GenAI”这类特定关键词,并每 5 分钟通知你一次,这完全是可行的。下面是实现思路和可选方案的概要:

使用 Google Apps Script(Gmail 插件)

Setup:编写一个 Google Apps Script,定期在 Gmail 中搜索包含关键词“GenAI”的邮件。

Configuration:使用 GmailApp.search() 方法找到符合条件的邮件。

Notifications:可以使用 Google Apps Script 的 MailApp,或 Slack/Webhooks 等其他服务来发送通知。

Automation:设置定时触发器,每 5 分钟执行一次脚本。

Pros:原生集成,搭建简单,运行在云端。

Cons:能处理的复杂度有限,需要 JavaScript 知识。

使用 Gmail API 的 Python 脚本

Setup:在 Google Cloud 中启用 Gmail API,并获取所需凭证。

Code:编写一个 Python 脚本,通过 OAuth2 完成认证并访问你的 Gmail 收件箱。

Functionality:使用 API,并通过类似 “subject:GenAI” 的查询参数搜索包含“GenAI”的邮件。

Notifications:与你偏好的通知系统集成,例如邮件、短信或即时消息。

Automation:用 Cron(Linux/macOS)或任务计划程序(Windows)等任务调度工具来安排该 Python 脚本的运行。

Pros:灵活强大,可直接复用现有的 Gmail API 方法。

Cons:搭建工作更多,需要 Python 编程知识。

第三方自动化工具(Zapier、Integromat 等)

Setup:使用与 Gmail 集成的自动化工具。

Configuration:创建一个工作流,定期检查 Gmail 中是否有包含“GenAI”的邮件。

Notifications:在自动化工具中配置你偏好的通知方式(如短信、Slack)。

Pros:无需编程,搭建迅速。

Cons:可定制性可能有限,或需要付费订阅。

实现的通用步骤:

从上述选项中选择一个偏好的方案。

按需配置必要的权限、凭证和 API。

实现搜索并识别提及“GenAI”邮件的逻辑。

集成通知系统。

对工具进行调度或自动化,使其每 5 分钟运行一次。

每种方案各有取舍,最终选择取决于你的技术能力、定制需求以及对相关平台的熟悉程度。

=======================================================

注意我们专门要求 GPT 给出多个不同方案,这体现了我们想要探索多种技术方向的意图。GPT 在回应中提出了若干潜在解决方案,并罗列了各自的优缺点。基于这份评估,我们可以提前判断这个任务是切实可行的,对 GPT 来说也可能比较容易。每个方案适用于不同的场景。

这里我们选择 Google Apps Script 方案,因为它由 Google 提供,对 Gmail 认证、邮件读取和定时任务调度有完善的内置支持,能为我们节省大量时间。

然而,由于 GenAI 具有不确定性,尽管 Google Apps Script 是这个任务非常合适的工具,GPT 也未必每次都会提及它。这暴露出一个隐患:GPT 在给出还不错的方案上表现优秀(比如建议使用 Python,这也确实可行),但在某些具体场景下,它可能错过最便捷、最高效的选择,例如这里的 Google Apps Script。

如果你在构建工具时对其他备选方案保持好奇,主动向 GPT 追问,就可能了解到 Google Apps Script,并进一步询问它是否适合本工具。把 GPT 当作学习工具来使用,能在构建实际工具的过程中持续积累对 GenAI 的整体认知与经验。

以编程方式调用 GPT 的能力

回到技术框架本身,根据 GPT 的回复,整体方案已经比较清晰。我们可以按照 GPT 的建议,使用 Gmail 的全文搜索来查找与 GenAI 相关的邮件。或者,更好的做法是先抓取最近的 10 封邮件,再以编程方式调用 GPT 来判断每封邮件是否与 GenAI 相关。这种从使用 GPT 网页界面转向使用其 API 的转变,让流程更加适合机器处理、便于自动化。这是一块重要的能力基石,因为它打开了用 GPT 能力来自动化任务的大门。我们在这一课中所构建的内容,可以在后续课程以及日常工作中反复复用。

当我们从 GPT 得到“某封邮件与 GenAI 相关”的肯定结果后,可以按 GPT 的建议使用 MailApp 将该邮件转发到另一个地址,并对该地址开启实时通知;或者只对 Gmail 的优先收件箱开启通知,并把这条消息移动到那里。Slack 集成与 webhook 也都很容易实现,可以作为很好的练习。

现在,让我们直接询问 GPT:在 Google Apps Script 中如何调用 OpenAI 的 GPT API:

示例 Prompt

=======================================================

How to tell a given email is related to GenAI in Google Apps Scripts? We’d like to invoke OpenAI’s GPT API to do it.

=======================================================

示例回复(仅代码部分):

=======================================================

/**

  • Classifies the email content using OpenAI’s GPT API

  • @param {string} emailContent - Text of the email to classify

  • @returns {string} - GPT’s response with the classification

*/

function classifyWithGPT(emailContent) {

// Replace with your OpenAI API key

const apiKey = ‘YOUR_OPENAI_API_KEY’;

// GPT-4 or GPT-3.5 endpoint settings

const endpoint = ‘https://api.openai.com/v1/completions’;

const prompt = Determine whether the following email is related to GenAI: ”${emailContent}”. Respond only “Yes” or “No”.;

const requestData = {

model: ‘text-davinci-003’, // Adjust the model name accordingly

prompt: prompt,

max_tokens: 10,

temperature: 0.0 // Low temperature for more deterministic output

};

const options = {

method: ‘post’,

contentType: ‘application/json’,

headers: {

‘Authorization’: Bearer ${apiKey}

},

payload: JSON.stringify(requestData)

};

// Make the API request using UrlFetchApp

const response = UrlFetchApp.fetch(endpoint, options);

const jsonResponse = JSON.parse(response.getContentText());

// Extract the GPT classification from the response

return jsonResponse.choices[0].text.trim();

}

=======================================================

这里很容易就能发现问题:GPT 仍然在使用一个非常老旧的模型 GPT-3(text-davinci-003)。这会导致 API 不匹配,即便我们把模型名替换成 gpt-3.5-turbo,也仍然会报错。每个 GPT 模型都有一个知识截止日期。截至 2024 年 5 月,最新的 GPT 模型其知识截止日期为 2023 年 4 月。在那个时间点,关于使用 Google Apps Script 调用 GPT-4,甚至是 GPT-3.5 API 的在线文档或示例程序都还非常少。这就导致当下的 ChatGPT 对如何调用 GPT-4 API 知之甚少,并默认回到 GPT-3 上。

这是否意味着对于 GPT 不了解的库或 API,我们就无法借助 AI 辅助编程了呢?这听上去是个相当严重的限制!幸运的是,我们有一些实用而巧妙的技巧来绕过它。一种行之有效的方法是把 API 文档放进 prompt 中。这样 GPT 可以利用其推理与归纳能力,临时学习这些 API,并基于所提供的信息来编写程序。

下一课我们会深入解释其底层原理与最佳实践。眼下,我们可以先解锁自己——访问 OpenAI 的官方 Python 库(不一定要是 JavaScript!),把一个示例文件中展示该 API 用法的内容放进 prompt。

示例 Prompt

=======================================================

How to tell a given email is related to GenAI in Google Apps Scripts? We’d like to invoke OpenAI’s GPT API to do it. Here is an example Python file: <Content of https://github.com/openai/openai-python/blob/main/examples/demo.py>

=======================================================

示例回复:

要在 Google Apps Script 中借助 OpenAI 的 GPT API 来识别与生成式 AI 相关的邮件,你可以采用与上面这段 Python 代码类似的结构,只是把它翻译成 JavaScript,并适配到 Google Apps Script 的运行环境中。

步骤:

搭建 Google Apps Script:

在你的 Google Workspace 中创建一个新的 Apps Script 项目。

确保你拥有访问 Gmail 的相应权限。

配置 OpenAI API Key:

将你的 OpenAI API key 安全地存储在脚本中或作为环境变量。如果直接写在脚本里,请确保你的脚本是受保护的。

获取邮件:

使用 GmailApp 服务获取相关邮件。

使用 OpenAI API 分析邮件:

在 Apps Script 中通过 UrlFetchApp 调用 OpenAI GPT API,对邮件内容进行分析。

function analyzeEmailsWithOpenAI() {

const OPENAI_API_KEY = “YOUR_API_KEY”; // Replace with your OpenAI API key

const SEARCH_QUERY = ‘subject:“Generative AI” OR “OpenAI” OR “GPT”’; // Adjust as needed

// Search for emails in Gmail

const threads = GmailApp.search(SEARCH_QUERY);

const messages = GmailApp.getMessagesForThreads(threads);

// Function to analyze email content using OpenAI GPT-4

function analyzeEmailContent(emailContent) {

const requestPayload = {

model: “gpt-4”,

messages: [

{

role: “user”,

content: Is this email related to generative AI?\n\n${emailContent},

},

],

};

const options = {

method: “post”,

contentType: “application/json”,

headers: { Authorization: Bearer ${OPENAI_API_KEY} },

payload: JSON.stringify(requestPayload),

};

// Make the API call

const response = UrlFetchApp.fetch(

https://api.openai.com/v1/chat/completions”,

options

);

const data = JSON.parse(response.getContentText());

return data.choices[0].message.content.trim();

}

// Loop through each email message

messages.flat().forEach((message) => {

const emailContent = message.getPlainBody();

const analysis = analyzeEmailContent(emailContent);

// Log the analysis result

Logger.log(Analysis result for email: ${analysis});

});

}

=======================================================

现在这段代码看起来不错。正如 GPT 在回复中所提到的,我们需要获取一个 API Key。这是一个相对直接的过程,但其中也有一些细节。我们将其留作练习,由你来完成。

练习

=======================================================

创建你自己的 OpenAI API Key,并替换上面程序中的 “YOUR_API_KEY”。挑选合适的工具来帮助你弄清楚具体怎么做。

提示:搜索引擎可能是最好的工具,因为相关的在线资源——包括视频——一定非常丰富。Copilot 是次优选择,因为它会进行真实的网页搜索,并具备较好的上下文理解能力。ChatGPT 等同类 LLM 并不适合做这件事,因为自其上一次知识截止日期以来,OpenAI 的网页界面很可能已经发生了某些变化。

=======================================================

如果我们真的拿到了一个 API key 并运行这段代码,可能一切顺利,也可能遇到一些问题。在我的情形中,我的邮件过长,超出了 API 的限制。于是我把错误信息复制并粘贴回 ChatGPT,它给我提供了一份新版本的程序。之后,我就能得到如下输出:

示例输出

=======================================================

Analysis result for email: No, this email is not related to generative AI. It appears to be a notification regarding various Reddit posts in different subreddits.

Analysis result for email: Yes, this email is related to OpenAI, which is known for its work in generative AI models.

Analysis result for email: Yes, this email is related to generative AI as it mentions Phi 3 with 4 billion parameters beating GPT 3.5 Turbo with around 175 billion parameters in a benchmark test. This indicates advancements in generative AI models.

======================================================= 看上去效果非常好,说明 GPT 能够读取我们邮件的内容并理解其含义。不过,我们还需要对代码做一些小的调整,使其更贴合我们的需求:

移除搜索关键词,让它获取最近的邮件,而不是主题中包含特定关键词的邮件。我们可以让 GPT 来做,也可以自己直接删除搜索关键词,看看效果如何。

更换模型,从又慢又贵的 GPT-4 切换为 GPT-3.5-Turbo,以获得更好的性能与成本效益。

调整输出,返回 true 或 false,而非自然语言,从而便于后续处理。

对于第三点,一种处理方式是修改 prompt,要求 GPT 只输出 “yes” 或 “no”,然后我们做简单的字符串匹配即可。另一种方法是使用 GPT-4-Turbo 中的 JSON 模式,让 GPT 始终输出 JSON 字符串,从而大大简化自动化处理。但 GPT-4 Turbo 对我们这个应用来说有些杀鸡用牛刀,因此这里我们采用前一种方法。

下面是我们可以使用的 prompt:

示例 prompt:

=======================================================

How to tell a given email is related to GenAI in Google Apps Scripts? We’d like to invoke OpenAI’s GPT API to do it. Here is an example Python file: <Content of https://github.com/openai/openai-python/blob/main/examples/demo.py>

We can retrieve the 10 latest emails. If the email is too long (>10000 chars), truncate it. When asking GPT, we can ask it to only output “yes” or “no”. Our function needs to return true or false. Print the function’s result and the email title so I can see what’s going on. Use the model “gpt-3.5-turbo”.

=======================================================

示例输出(仅代码部分):

=======================================================

function isGenAIEmail(email) {

const openAiApiKey = ‘YOUR_OPENAI_API_KEY’; // Replace with your OpenAI API key

const truncatedBody = email.body.substring(0, 10000); // Truncate if over 10,000 characters

const prompt = `

The following email may or may not be related to Generative AI. Tell me “yes” if it is related, “no” if it isn’t.

Email content: ”${truncatedBody}”

`;

const requestData = {

model: “gpt-3.5-turbo”,

messages: [

{ “role”: “user”, “content”: prompt }

],

max_tokens: 10,

temperature: 0

};

const options = {

method: ‘post’,

contentType: ‘application/json’,

headers: {

‘Authorization’: Bearer ${openAiApiKey}

},

payload: JSON.stringify(requestData)

};

const response = UrlFetchApp.fetch(‘https://api.openai.com/v1/chat/completions’, options);

const jsonResponse = JSON.parse(response.getContentText());

const reply = jsonResponse.choices[0].message.content.trim().toLowerCase();

return reply === ‘yes’;

}

function checkLatestEmailsForGenAI() {

const threads = GmailApp.search(“newer_than:10d”); // Adjust the search criteria as needed

const messages = GmailApp.getMessagesForThreads(threads);

messages.flat().forEach(message => {

const email = {

subject: message.getSubject(),

body: message.getPlainBody()

};

const isRelatedToGenAI = isGenAIEmail(email);

console.log(Email Subject: "${email.subject}");

console.log(Is related to GenAI: ${isRelatedToGenAI});

});

}

var jsonResponse = JSON.parse(response.getContentText());

// Extract and return GPT’s response

return jsonResponse.choices[0].text;

}

=======================================================

这个函数本身能完成我们想要的事情,但测试代码遗漏了“只获取最近 10 封邮件”的需求。此外,我们还需要手动停止程序的执行。

至此,我们已经拥有一个可以工作的函数,用来调用 OpenAI 的 API,借助 GPT 完成我们交付给它的任务。这个例子的意义远比看起来要深远。下一课我们会更深入地探讨这一点。

English Original Tech Route Selection

We now have a good product idea to improve our productivity. The tool follows a simple three-step process:

Pull the Latest Emails: It retrieves the latest 10 emails from our Gmail inbox.

Check for Relevant Topics: It checks whether any emails are on topics we are interested in. For this example, we use GenAI. If an email is about GenAI, it is considered important. This criterion can be substituted with other topics or criteria.

Notify for Important Emails: If any important emails are found, we will be notified.

Depending on our background and expertise, some steps might seem easier than others. If we’re unsure about the technical difficulty of each step, it’s always a good idea to ask GPT to identify potential challenges beforehand and discuss alternative solutions. Here, we simply describe what we are trying to build to GPT and ask for its assessment.

Example Prompt

=======================================================

I want to build a tool to identify the emails mentioning GenAI in my Gmail inbox. Run this every 5 minutes so I can receive notifications on those emails to potentially respond right away. Is it easy to do? What are the options?

=======================================================

Example response

=======================================================

Building a tool to monitor your Gmail inbox for specific keywords like “GenAI” and notify you every five minutes is definitely feasible. Here’s an outline of the approach and available options:

Using Google Apps Script (Gmail Add-ons)

Setup: Write a Google Apps Script to run a periodic search in Gmail for emails containing the keyword “GenAI”.

Configuration: Use the GmailApp.search() method to find emails matching your criteria.

Notifications: You could use Google Apps Script’s MailApp or other services like Slack/Webhooks for notifications.

Automation: Set up a timed trigger to execute the script every 5 minutes.

Pros: Native integration, simple to set up, runs in the cloud.

Cons: More limited in complexity, requires JavaScript knowledge.

Python Script with Gmail API

Setup: Enable the Gmail API in Google Cloud and get the necessary credentials.

Code: Write a Python script to authenticate using OAuth2 and access your Gmail inbox.

Functionality: Utilize the API to search for emails containing “GenAI” using query parameters like “subject:GenAI”.

Notifications: Integrate with your preferred notification system like email, SMS, or instant messaging.

Automation: Schedule the Python script using a task scheduler like Cron (Linux/macOS) or Task Scheduler (Windows).

Pros: Flexible and powerful, use existing Gmail API methods.

Cons: Requires more setup, Python programming knowledge needed.

Third-Party Automation Tools (Zapier, Integromat, etc.)

Setup: Use automation tools that integrate with Gmail.

Configuration: Create a workflow that periodically checks Gmail for emails containing “GenAI”.

Notifications: Configure your preferred notification method within the automation tool (e.g., SMS, Slack).

Pros: No programming required, quick setup.

Cons: May have limited customizability or require a subscription.

General Steps to Implement:

Choose a preferred approach from the options above.

Configure the necessary permissions, credentials, and APIs if required.

Implement the logic to search for and identify emails mentioning “GenAI”.

Integrate the notifications system.

Schedule or automate the tool to run every 5 minutes.

Each option has its own trade-offs, so your choice will depend on your technical skills, customization needs, and familiarity with the required platforms.

=======================================================

Note how we specifically ask GPT to provide different options. This reflects our intention to explore various tech directions. In response, GPT introduces several potential solutions, outlining their pros and cons. Based on this assessment, we can make an early determination that this task is practical and potentially easy for GPT. Each solution fits a different scenario.

Here, we select the Google Apps Script approach because it is provided by Google and offers extensive built-in support for Gmail authentication, message retrieval, and automatic task scheduling, saving us a lot of time.

However, due to the nondeterministic nature of GenAI, GPT may or may not mention Google Apps Script, despite it being a great tool for this task. This reveals a pitfall: while GPT is excellent at suggesting decent solutions (e.g., using Python, which would work well), it might miss the most convenient and efficient option in specific cases, like Google Apps Script.

If you have the curiosity to ask GPT about other alternatives when building tools, you might learn about Google Apps Script and then inquire whether it’s a good route for this tool. Using GPT as a learning tool can help build general expertise and experience in GenAI during the process of creating actual tools.

Invoke GPT’s Capability Programmatically

Coming back to the technical framework, based on GPT’s response, the overall framework is clear. We could follow GPT’s suggestion to use Gmail’s full-text search to find emails related to GenAI. Alternatively, a better approach is to fetch the latest 10 emails, and call GPT programmatically to determine if the email is about GenAI. This shift from using GPT’s web GUI to using its API makes the process more computer-friendly and automatable. This is an important building block, as it opens the door to automating tasks using GPT’s capabilities. What we build in this lesson can be reused in later lessons and in our daily work.

After we receive a positive response from GPT that an email is related to GenAI, we can use MailApp, as GPT suggested, to forward the email to another address. We can turn on real-time notifications for that address. Alternatively, we can enable notifications only for the priority inbox in Gmail and move the message there. Slack integration and webhooks are also easy to implement and can be good exercises.

Now, let’s directly ask GPT how to invoke OpenAI’s GPT API in Google Apps Script:

Example Prompt

=======================================================

How to tell a given email is related to GenAI in Google Apps Scripts? We’d like to invoke OpenAI’s GPT API to do it.

=======================================================

Example Response (code only):

=======================================================

/**

  • Classifies the email content using OpenAI’s GPT API

  • @param {string} emailContent - Text of the email to classify

  • @returns {string} - GPT’s response with the classification

*/

function classifyWithGPT(emailContent) {

// Replace with your OpenAI API key

const apiKey = ‘YOUR_OPENAI_API_KEY’;

// GPT-4 or GPT-3.5 endpoint settings

const endpoint = ‘https://api.openai.com/v1/completions’;

const prompt = Determine whether the following email is related to GenAI: ”${emailContent}”. Respond only “Yes” or “No”.;

const requestData = {

model: 'text-davinci-003',  // Adjust the model name accordingly

prompt: prompt,

max_tokens: 10,

temperature: 0.0  // Low temperature for more deterministic output

};

const options = {

method: 'post',

contentType: 'application/json',

headers: {

  'Authorization': Bearer ${apiKey}

},

payload: JSON.stringify(requestData)

};

// Make the API request using UrlFetchApp

const response = UrlFetchApp.fetch(endpoint, options);

const jsonResponse = JSON.parse(response.getContentText());

// Extract the GPT classification from the response

return jsonResponse.choices[0].text.trim();

}

=======================================================

It’s easy to spot the problem here. GPT is still using a very old model, GPT-3 (text-davinci-003). This causes an API mismatch and will result in an error even if we replace the model name with gpt-3.5-turbo. Each GPT model has a knowledge cutoff date. The latest GPT model as of May 2024 has a knowledge cutoff date of April 2023. At that time, there were very few online documents or sample programs, especially those using Google Apps Script to invoke GPT-4 or even GPT-3.5 APIs. This results in the current ChatGPT not knowing much about how to invoke GPT-4 APIs and defaulting to GPT-3.

Does this mean we cannot use AI-assisted programming for any libraries or APIs that GPT doesn’t know about? That sounds like a severe limitation! Fortunately, there are practical and clever tricks to get around this. One effective method is to include the API’s documentation in the prompt. This way, GPT can use its inference and deduction capabilities to learn about the API on the fly and write programs using the given information.

We will explain the underlying principles and best practices in the next lesson. For now, we can unblock ourselves by going to the official Python library of OpenAI (it doesn’t have to be JavaScript!) and including the content of an example file showing the API’s usage in the prompt.

Example Prompt

=======================================================

How to tell a given email is related to GenAI in Google Apps Scripts? We’d like to invoke OpenAI’s GPT API to do it. Here is an example Python file: <Content of https://github.com/openai/openai-python/blob/main/examples/demo.py>

=======================================================

Example Response:

To identify emails related to generative AI using the OpenAI GPT API from Google Apps Script, you would follow a structure similar to the Python code you provided but translated to JavaScript and adapted to the Google Apps Script environment.

Steps:

Set up Google Apps Script:

Create a new Apps Script project in your Google Workspace.

Ensure you have the right permissions to access Gmail.

Set up OpenAI API Key:

Store your OpenAI API key securely in the script or as an environment variable. If using it directly, ensure your script is protected.

Fetch Emails:

Use the GmailApp service to retrieve relevant emails.

Analyze Emails Using OpenAI API:

Invoke the OpenAI GPT API via UrlFetchApp in Apps Script to analyze the email content.

function analyzeEmailsWithOpenAI() {

const OPENAI_API_KEY = “YOUR_API_KEY”; // Replace with your OpenAI API key

const SEARCH_QUERY = ‘subject:“Generative AI” OR “OpenAI” OR “GPT”’; // Adjust as needed

// Search for emails in Gmail

const threads = GmailApp.search(SEARCH_QUERY);

const messages = GmailApp.getMessagesForThreads(threads);

// Function to analyze email content using OpenAI GPT-4

function analyzeEmailContent(emailContent) {

const requestPayload = {

  model: "gpt-4",

  messages: [

    {

      role: "user",

      content: Is this email related to generative AI?\n\n${emailContent},

    },

  ],

};

const options = {

  method: "post",

  contentType: "application/json",

  headers: { Authorization: Bearer ${OPENAI_API_KEY} },

  payload: JSON.stringify(requestPayload),

};

// Make the API call

const response = UrlFetchApp.fetch(

  "https://api.openai.com/v1/chat/completions",

  options

);

const data = JSON.parse(response.getContentText());

return data.choices[0].message.content.trim();

}

// Loop through each email message

messages.flat().forEach((message) => {

const emailContent = message.getPlainBody();

const analysis = analyzeEmailContent(emailContent);

// Log the analysis result

Logger.log(`Analysis result for email: ${analysis}`);

});

}

=======================================================

The code looks good now. As mentioned in GPT’s response, we need to obtain an API Key. This is a straightforward process, though it does have its own nuances. We will leave this as an exercise for you to complete.

Exercise

=======================================================

Create your OpenAI API Key and replace the “YOUR_API_KEY” in the program above. Choose the proper tool to help you figure out how to do it.

Hint: search engine might be the best tool given there must be many online resources, even including videos, to introduce how to do that. Copilot is the second best bet, because it does an actual web search and has the best context. ChatGPT and similar LLMs are not good tools for this purpose. Because it’s likely the OpenAI’s web interface changed somehow since their last knowledge cut off date.

=======================================================

If we actually get an API key and run the code, we may find it works well or encounter some issues. In my case, my email was too long and exceeded the API’s limit. So, I copied the error message and pasted it back into ChatGPT, which provided me with a new version of the program. After that, I was able to get outputs like:

Example output

=======================================================

Analysis result for email: No, this email is not related to generative AI. It appears to be a notification regarding various Reddit posts in different subreddits.

Analysis result for email: Yes, this email is related to OpenAI, which is known for its work in generative AI models.

Analysis result for email: Yes, this email is related to generative AI as it mentions Phi 3 with 4 billion parameters beating GPT 3.5 Turbo with around 175 billion parameters in a benchmark test. This indicates advancements in generative AI models.

======================================================= This looks great. It indicates GPT was able to read the content of our emails and make sense of it. However, we still need to make some small changes to the code to better meet our needs:

Remove the search keywords so it retrieves the latest emails rather than those with specific keywords in the subject. We can either ask GPT to do this or simply remove the search keywords ourselves to see if it works.

Change the model from the slow and expensive GPT-4 to GPT-3.5-Turbo for better performance and cost-efficiency.

Adjust the output to return a true or false value instead of natural language, making it easier for further processing.

For the last issue, one way to handle it is to modify the prompt and request the GPT to only output “yes” or “no.” Then we can simply perform string matching. Another approach is using the special JSON mode in GPT-4-Turbo, where GPT always outputs a JSON string, making automation much easier. However, GPT-4 Turbo might be overkill for our application here. So, we will use the former approach.

Here’s how we can prompt GPT:

Example prompt:

=======================================================

How to tell a given email is related to GenAI in Google Apps Scripts? We’d like to invoke OpenAI’s GPT API to do it. Here is an example Python file: <Content of https://github.com/openai/openai-python/blob/main/examples/demo.py>

We can retrieve the 10 latest emails. If the email is too long (>10000 chars), truncate it. When asking GPT, we can ask it to only output “yes” or “no”. Our function needs to return true or false. Print the function’s result and the email title so I can see what’s going on. Use the model “gpt-3.5-turbo”.

=======================================================

Example output (code only):

=======================================================

function isGenAIEmail(email) {

const openAiApiKey = ‘YOUR_OPENAI_API_KEY’; // Replace with your OpenAI API key

const truncatedBody = email.body.substring(0, 10000); // Truncate if over 10,000 characters

const prompt = `

The following email may or may not be related to Generative AI. Tell me “yes” if it is related, “no” if it isn’t.

Email content: ”${truncatedBody}”

`;

const requestData = {

model: “gpt-3.5-turbo”,

messages: [

{ “role”: “user”, “content”: prompt }

],

max_tokens: 10,

temperature: 0

};

const options = {

method: ‘post’,

contentType: ‘application/json’,

headers: {

‘Authorization’: Bearer ${openAiApiKey}

},

payload: JSON.stringify(requestData)

};

const response = UrlFetchApp.fetch(‘https://api.openai.com/v1/chat/completions’, options);

const jsonResponse = JSON.parse(response.getContentText());

const reply = jsonResponse.choices[0].message.content.trim().toLowerCase();

return reply === ‘yes’;

}

function checkLatestEmailsForGenAI() {

const threads = GmailApp.search(“newer_than:10d”); // Adjust the search criteria as needed

const messages = GmailApp.getMessagesForThreads(threads);

messages.flat().forEach(message => {

const email = {

subject: message.getSubject(),

body: message.getPlainBody()

};

const isRelatedToGenAI = isGenAIEmail(email);

console.log(Email Subject: "${email.subject}");

console.log(Is related to GenAI: ${isRelatedToGenAI});

});

}

var jsonResponse = JSON.parse(response.getContentText());

// Extract and return GPT’s response

return jsonResponse.choices[0].text;

}

=======================================================

This function is able to get exactly what we want, but the testing code missed the requirement of only retrieving the latest 10 emails. Additionally, we have to manually stop the execution.

We now have a working function to call the OpenAI API, using GPT to accomplish tasks we delegate to it. This example has far deeper significance than it appears. Let’s explore this in more detail in the next lesson.