为了账号安全,请及时绑定邮箱和手机立即绑定

使用Gemini和Google Apps Script简化Gmail及其附件处理流程

摘要(在学术论文中,通常放在文章开头,简要介绍全文内容)

名为MimeTypeApp的新库简化了使用Gmail消息和附件进行文本分析等任务的操作。它将不支持的格式转换成可无缝集成到Google Apps Script和Gemini中的格式,从而实现与Google Apps Script和Gemini的无缝集成。

这是介绍

最近,我发布了MimeTypeApp,这是一个 Google Apps 脚本库,简化了对 Gmail 消息及其附件的解析,以便与 Gemini API 一起使用。Ref 此库解决了关键挑战:Gmail 附件包含多种 MIME 类型,而 Gemini API 当前仅支持有限的 MIME 类型格式进行处理。MimeTypeApp 通过提供将不支持的 MIME 类型格式转换为与 Gemini 兼容格式的功能来弥合这一差距。使用 MimeTypeApp,您可以简化您的工作流程,这些工作流程涉及解析 Gmail 消息及其附件,以执行诸如文本提取、总结或使用 Gemini API 进行情感分析等任务。此报告介绍了一个示例脚本,展示了如何利用 MimeTypeApp 实现这些功能。通过利用 Google Apps 脚本的集成功能,MimeTypeApp 允许您创建强大的应用程序,这些应用程序可以无缝地连接 Gmail、电子表格(用于存储结果或提取的数据)和 Gemini API,实现强大的应用程序。

流动

这是一个脚本的流程图。该脚本是通过Google应用脚本来运行的。

  1. 从Gmail中检索邮件。
  2. 从每封邮件中检索元数据、邮件正文和附件文件。
  3. 如果邮件中有附件,就把附件转换成PDF格式。
  4. 将转换后的文件(包括邮件正文)上传到Gemini。
  5. 使用Gemini API摘要邮件正文和附件内容。
  6. 将结果放到数据表里。
使用指南
1. 获取一个API密钥。

请访问https://ai.google.dev/gemini-api/docs/api-key并创建您的API密钥。同时,在API控制台中启用生成语言API。此API密钥将用于运行以下脚本。

这份官方文件你也可以看一下哦。Ref

2. 示例脚本

在这种情况下,你可以通过复制一个 Google 表格来拿到脚本。这个表格里就有你要的脚本。复制的网址如下:

https://docs.google.com/spreadsheets/d/1D3GB0KCnBcZdd7OF0iLiYR_of0RY2xTyzlr5bgLtAdw/copy
这是一个可以复制的Google表格链接。

当你打开这个电子表格时,你可以看到一个名为“Data”的表单,其中包含标题行。

当你打开脚本编辑器时,你可以看到这些脚本文件。

3. 配置 API 密钥

请打开脚本编辑器,在 Code.gs 中将您的 API 密钥设置为 apiKey

第四 剧本

MimeTypeApp.gsGeminiWithFiles.gs 的代码可以在 这里这里 查阅。在这里,我们展示一下 Code.gs 中的代码如下。

    /**

* 首先,请设置您的 Gemini API 密钥。
     */
    const apiKey = "###";

    /**

* 这是一个使用 Gemini 和 Google Apps Script 解析包含附件文件的电子邮件的示例脚本。

* 解析的数据将放入活动电子表格中的 Data 工作表中。

* 作者: Tanaike
     */
    function run() {
      // 从电子表格中获取当前的数据。
      const ss = SpreadsheetApp.getActiveSpreadsheet();
      const dataSheet = ss.getSheetByName("Data");
      const lastRowDataSheet = dataSheet.getLastRow();
      const rows = dataSheet.getRange("A2:G" + lastRowDataSheet).getValues();
      const messageIds = rows.map(([, id]) => id);
      const lastRow = rows[rows.length - 1];
      const now = Date.now();
      let startTime = now - (60 * 60 * 1000);
      if (lastRow[0] && lastRow[0] instanceof Date) {
        startTime = lastRow[0].getTime();
      }

      // 设置 Gemini API。
      const responseSchema = {
        description: "结果值的 JSON 模式。",
        type: "array",
        items: {
          type: "object",
          properties: {
            filename: { type: "string", description: "文件名" },
            summary: { type: "string", description: "生成的摘要" },
          }
        }
      };
      const forGeminiObject = { apiKey, model: "models/gemini-1.5-flash-002", responseMimeType: "application/json", responseSchema };

      // 处理自上次处理后收到的电子邮件。当脚本第一次运行时,处理一小时前收到的电子邮件。当然,您可以根据情况编辑此搜索查询。
      const threads = GmailApp.search(`after:${Math.floor(startTime / 1000)}`);

      const v = threads.reduce((ar, thread) => {
        thread.getMessages().forEach(message => {
          const id = message.getId();
          if (!messageIds.includes(id)) {
            const value = [message.getDate(), id, message.getSubject(), message.getFrom()];
            const body = message.getBody();
            const blobs = [Utilities.newBlob(body, MimeType.HTML, "HTMLBody_GmailMessage.html")];

            // 获取 Google 文档文件的附件。
            const ats = [...body.matchAll(/"https:\/\/drive\.google\.com\/open\?id\=(.*?)"/g)];
            if (ats.length > 0) {
              const fileIds = ats.map(([, id]) => id);
              blobs.push(...new MimeTypeApp().setFileIds(fileIds).getAs({ mimeType: MimeType.PDF }));
            }

            // 获取非 Google 文档文件的附件。
            const attachments = message.getAttachments();
            if (attachments.length > 0) {
              const validMimeTypes = [MimeType.PLAIN_TEXT, MimeType.PDF, MimeType.PNG, MimeType.JPEG, "audio/mpeg", "video/mp4"];
              const validFiles = attachments.filter(b => validMimeTypes.includes(b.getContentType()));
              if (validFiles.length > 0) {
                blobs.push(...validFiles);
              }
              const invalidFiles = attachments.filter(b => !validMimeTypes.includes(b.getContentType()));
              if (invalidFiles.length > 0) {
                blobs.push(...new MimeTypeApp().setBlobs(invalidFiles).getAs({ mimeType: MimeType.PDF }));
              }
            }

            // 使用 Gemini 生成内容。
            const g = new GeminiWithFiles(forGeminiObject);
            const fileList = g.setBlobs(blobs).uploadFiles();
            const q = [
              `执行以下步骤:`,
              `1. 理解每个上传的文件。`,
              `2. 生成每个文件的 50 字以内摘要。`,
            ].join("\n");
            const res = g.withUploadedFilesByGenerateContent(fileList).generateContent({ q });
            value.push(res.find(({ filename }) => filename == "HTMLBody_GmailMessage.html")?.summary || "");
            const attach = res.filter(({ filename }) => filename != "HTMLBody_GmailMessage.html");
            value.push(attach.length > 0 ? attach.map(({ filename, summary }) => `${filename}: ${summary}`).join("\n") : "");
            value.push(`https://mail.google.com/mail/#search/rfc822msgid:${encodeURIComponent(message.getHeader("Message-ID"))}`);
            ar.push(value);
            console.log(`邮件 ${id} 已处理。`);
          }
        });
        return ar;
      }, []);
      if (v.length > 0) {
        dataSheet.getRange(lastRowDataSheet + 1, 1, v.length, v[0].length).setValues(v);
      } else {
        console.log("没有电子邮件。");
      }
    }

    /**

* 为活动的电子表格创建自定义菜单。
     */
    function onOpen() {
      SpreadsheetApp.getUi().createMenu("运行").addItem("运行脚本", "run").addToUi();
    }

在生成邮件正文和附件描述时,我们使用了配置如下所示的Gemini API:

  • 模型: models/gemini-1.5-flash-002
  • 响应 MIME 类型: application/json
  • 响应结构:
{
  "description": "结果值的 JSON 架构描述。",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "filename": { "type": "string", "description": "文件名" },
      "summary": { "type": "string", "description": "生成的概要" }
    }
  }
}

在这个情况下,可以进行批处理。这样一来,邮件正文及其所有附件都可以用一个 API 调用来处理。

为什么要使用**responseSchema**:

根据目前的观察,responseSchema 接近目前观察,似乎比直接将 JSON 架构纳入提示内容中产生更可靠的结果。不过,需要注意的是,这在未来 API 更新中可能会发生变化。

5. 测试阶段

当你运行 run 函数时,如果你有多个邮件的话,你将会看到以下结果,

电子邮件的正文和附件文件会被汇总,并放入数据表中。当你再次运行 run 函数时,会检索上次运行之后的电子邮件。您也可以通过“消息链接”直接查看邮件。

此外,这些汇总后的数据也可以用于包含附件的电子邮件的语义查找。

要说明:额外的信息

当你设置run函数由时间驱动的触发器执行时,邮件可以被自动解析并导入到Google电子表格中。

  • 这是由imagen3生成的图片。
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消