从所有先前的消息和元数据中提取电子邮件消息本身(Sendgrid Parse API/PHP)?

Posted

技术标签:

【中文标题】从所有先前的消息和元数据中提取电子邮件消息本身(Sendgrid Parse API/PHP)?【英文标题】:Extract email message itself from all its prior messages and meta data (Sendgrid Parse API/PHP)? 【发布时间】:2013-02-01 17:19:20 【问题描述】:

我正在使用Sendgrid and their Parse API 发送/接收电子邮件。 Parse API 允许一个网络应用程序以 $_POST 的形式接收电子邮件,但问题是在 $_POST 中我希望能够从其先前的消息和链接在一起的元数据中提取消息本身。

为了向您展示我在下图中的意思,我只想捕获文本,“尝试从 GMAIL 从 12373 发送到 12373”,而不是下面的所有垃圾。如果那不可能,是否有人对如何解析电子邮件正文($_POST['text'])有任何建议,以便我可以分离出邮件本身?

问题在于,取决于电子邮件客户端(gmail、outlook 等),我不清楚日期信息,在这种情况下:“2013 年 1 月 23 日,星期三...”,将允许关注消息本身。如果所有电子邮件客户端都将日期放在消息下方,那么我似乎可以设计一个花哨的正则表达式来查找换行符,然后是日期或其他内容。想法?

【问题讨论】:

【参考方案1】:

你有几个选择:

1) 插入拆分电子邮件的令牌

您可以执行--- reply above this line --- 之类的操作,然后删除该令牌下方的所有内容。

2) 使用电子邮件回复解析库

有一个非常好的done by github,但它是用红宝石编写的。有一个 php port 虽然这可能对您的需要有好处:

完整的工作代码

<?php
  require_once 'application/third_party/EmailReplyParser-master/src/autoload.php';
  $email = new \EmailReplyParser\Email();
  $reply = $email->read($_POST['text']);            
  $message=$reply[0]->getContent();
  $message=preg_replace('~On(.*?)wrote:(.*?)$~si', '', $message); 
  //Last line is needed for some email clients, e.g., some university e-mails: foo@bar.edu but not Gmail or Hotmail, to get rid of "On Jan 23...wrote:" 
  //This failure to remove "On Jan 23...wrote:" is a known issue and is documented in their README

 ?>

【讨论】:

-@Swift,这太棒了,是的,我正在尝试模仿 Github 所做的事情,所以我将查看这个解析库!感谢您的提示。 -@Swift,一个问题:反斜杠是怎么回事?我以前从未见过用于实例化类的方法。 反斜杠是 PHP 命名空间的一部分 php.net/manual/en/language.namespaces.php Github 对这两种方法都做了一点,所以我会混合搭配。 PHP 端口EmailReplyParser 最近已重构,运行良好。它用于生产,并完成工作。【参考方案2】:

根本无法保证从电子邮件消息中解析引用的消息线程,因此您不会找到适用于所有情况的正则表达式或任何其他代码。没有标准来定义回复的格式,并且您已经观察到不同的邮件客户端使用不同的约定。许多,事实上,将允许用户编辑引用的文本。此外,用户可以粘贴不相关的消息,无论是否带有标题,从而形成混合匹配的格式。

如果您可以记录并保留所有消息的发送和接收历史记录,那么您可以(通常但不总是)使用 In-Reply-To 标头(请参阅RFC-5322)来定位上一条消息通过匹配它的 Message-ID 标头,并在正文上进行差异并删除重复的文本运行。很明显,一些电子邮件系统这样做是为了改进他们的演示文稿,但我不知道有任何可用的开源代码。

【讨论】:

我看到另一个答案指向 github 库,我在发布答案时并不知道。我确实坚持这样一个事实,即没有保证的方法,但我希望它对你有用。【参考方案3】:

// 剪切引用的文字,https://regex101.com/r/xO8nI1/5

    $message = preg_replace('/(On\s.*<\n)0,1(.*\n(\n)0,1((^>+\s?.*$)+\n?)+)/mi', '', $message);

【讨论】:

【参考方案4】:

用英语以外的语言回复怎么样?我们提出了添加标记的解决方案,但不是为每封电子邮件翻译它(基于用户的语言),我们将一些不可见的字符放入其中(准确地说是零宽度空间 U+200B)。基于“On...”正则表达式,它容易出错,它可以轻松剪切一些电子邮件内容。

【讨论】:

以上是关于从所有先前的消息和元数据中提取电子邮件消息本身(Sendgrid Parse API/PHP)?的主要内容,如果未能解决你的问题,请参考以下文章

使用 SMTP PHPMailer 将不同的消息发送到不同的电子邮件帐户

Slackbot 可以从私人频道中提取消息并在另一个 Slack 频道中发布吗?

Apache Flume - 由多个使用者从单个消息队列中提取数据

iOS:如何从磁盘上的照片文件中提取缩略图和元数据

如何将Amazon SQS与Dynamodb集成

电子邮件消息的可能 mimetype 层次结构是啥?