使用 Google Apps 脚本删除 Gmail 电子邮件的附件

Posted

技术标签:

【中文标题】使用 Google Apps 脚本删除 Gmail 电子邮件的附件【英文标题】:Remove an attachment of a Gmail email with Google Apps Script 【发布时间】:2018-03-08 03:29:57 【问题描述】:

使用 Google Apps 脚本 (http://script.google.com),我从 the docs 知道如何发送、转发、移动到垃圾邮件等,但我没有找到 如何删除电子邮件,即:

    保留文本内容(html 或纯文本都可以) 保留原发件人,保留收件人 保留原始消息日期/小时(重要!) 删除附件

如果无法通过 API,有没有办法将消息重新发送给自己,同时保留 1、2 和 3?


注意:GmailAttachment 类看起来很有趣,并且允许列出收件人:

var threads = GmailApp.getInboxThreads(0, 10);
 var msgs = GmailApp.getMessagesForThreads(threads);
 for (var i = 0 ; i < msgs.length; i++) 
   for (var j = 0; j < msgs[i].length; j++) 
     var attachments = msgs[i][j].getAttachments();
     for (var k = 0; k < attachments.length; k++) 
       Logger.log('Message "%s" contains the attachment "%s" (%s bytes)',
                  msgs[i][j].getSubject(), attachments[k].getName(), attachments[k].getSize());
     
   
 

但我不知道如何删除附件。

注意:我已经研究了许多其他解决方案,我已经阅读了几乎所有关于此的文章(具有专用 Web 服务的解决方案,具有本地客户端,如 Thunderbird + 附件提取器插件等) ,但没有一个真的很酷。这就是为什么我一直在寻找通过 Google Apps 脚本手动执行此操作的解决方案。

【问题讨论】:

你能提供小提琴吗? 【参考方案1】:

看起来消息必须是re-created-ish:

消息是不可变的:它们只能被创建和删除。除了应用于给定消息的标签之外,不能更改任何消息属性。

将Advanced Gmail Service 与Gmail API insert() 一起使用,您可以使用以下方法破解它:Gmail.Users.Messages.insert(resource, userId)

此高级服务must be enabled使用前。

示例:[在EMAIL_ID 中填写email_id 或任何您想获取电子邮件的方式]

function removeAttachments () 
  // Get the `raw` email
  var email = GmailApp.getMessageById("EMAIL_ID").getRawContent();

  // Find the end boundary of html or plain-text email
  var re_html = /(-*\w*)(\r)*(\n)*(?=Content-Type: text\/html;)/.exec(email);
  var re = re_html || /(-*\w*)(\r)*(\n)*(?=Content-Type: text\/plain;)/.exec(email);

  // Find the index of the end of message boundary
  var start = re[1].length + re.index;
  var boundary = email.indexOf(re[1], start);

  // Remove the attachments & Encode the attachment-free RFC 2822 formatted email string
  var base64_encoded_email = Utilities.base64EncodeWebSafe(email.substr(0, boundary));
  // Set the base64Encoded string to the `raw` required property
  var resource = 'raw': base64_encoded_email

  // Re-insert the email into the user gmail account with the insert time
  /* var response = Gmail.Users.Messages.insert(resource, 'me'); */

  // Re-insert the email with the original date/time 
  var response = Gmail.Users.Messages.insert(resource, 'me', 
                      null, 'internalDateSource': 'dateHeader');

  Logger.log("The inserted email id is: %s",response.id)

这将从电子邮件中删除附件并将其重新插入您的邮箱。

编辑/更新:新的正则表达式可用于仅处理 html 和纯文本电子邮件 - 现在应该可以处理多个边界字符串

【讨论】:

是的,在All Mail 文件夹中,它将显示插入发生时的电子邮件和时间 - 一旦打开消息,它将基本上反映原始(时间/日期/发件人/等),减去附件。该示例功能齐全,API 需要来自脚本的enabled 和占位符中的email_id 来测试它。 me 是一个特殊的值,用来表示经过身份验证的用户 它采用raw格式的原始电子邮件;删除附件信息并将其放回 gmail-box。插入时,会将一行Received: ... 值添加到电子邮件标题的第一个索引中。该行包含新的 insert 元数据 - 它是从 gmailapi.google.com with HTTPREST 和日期/时间收到的。邮件/电子邮件的其余部分与原始邮件完全相同(减去附件) - 查看它是否是您要查找的内容的最佳方法是对其进行测试。发送电子邮件 - 等待几分钟(这样你就可以看到时间戳) - 在上面运行示例 我删除了所有过时的 cmets。日期时间问题 100% 解决了 :) 我编辑了你的答案。 最后一个问题:边界正则表达式 --\w+-- 对我的消息不准确。见***.com/questions/46596020/… @Basj 更新的正则表达式现在应该适用于大多数(如果不是全部)电子邮件边界字符串 - 包括您的示例

以上是关于使用 Google Apps 脚本删除 Gmail 电子邮件的附件的主要内容,如果未能解决你的问题,请参考以下文章

在 Google Apps 脚本中使用高级 Gmail 服务创建与表情符号兼容的 Gmail 草稿

使用 Google Apps 脚本在 Gmail 中创建本机过滤器

如何使用 Google Apps 脚本获取 Gmail 用户的个人资料图片?

Google Apps 脚本 Google Sheets Gmail 处理新电子邮件 追加行数组

Google Apps 脚本 - 将 gmail 中的数据提取到电子表格中

无法通过Google Apps脚本显示授权对话框