Получите фактическое сообщение электронной почты, которое человек только что написал, исключая любой цитируемый текст

на сайте есть два уже существующих вопроса. Один для Python, один для Java.

Я хочу иметь возможность делать почти то же самое (в PHP). Я создал почтовый прокси, где два человека могут иметь корреспонденцию вместе электронной почты с уникальным адресом электронной почты. Проблема, которую я нахожу, заключается в том, что когда человек получает электронное письмо и нажимает ответ, я изо всех сил стараюсь точно захватить текст, который он написал, и отбросить цитируемый текст из предыдущей переписки.

Я пытаюсь найти решение, которое будет работать как для HTML-писем, так и для электронной почты с открытым текстом, потому что я отправляю оба.

у меня тоже есть возможность, если это поможет вставить <*****RESPOND ABOVE HERE*******> тег, если необходимо в электронной почте это означает, что я могу отбросить все, что ниже.

что бы вы мне посоветовали? Всегда добавляйте этот тег в HTML-копию и копию открытого текста, а затем хватайте все выше него?

Я все равно остался бы со сценарием, зная, как каждый почтовый клиент создает ответ. Потому что, например, Gmail сделает это:

On Wed, Nov 2, 2011 at 10:34 AM, Message Platform <35227817-7cfa-46af-a190-390fa8d64a23@dev.example.com> wrote:
## In replies all text above this line is added to your message conversation ##

любые предложения или рекомендации лучших практик?

или я должен просто взять 50 самых популярных почтовых клиентов, и начните создавать пользовательские Regex для каждого. Затем для каждого из этих клиентов также bizallion разные настройки локали, так как я предполагаю, что локаль пользователя также повлияет на то, что добавлено.

или я должен просто удалить предыдущую строку всегда, если он содержит дату?.. и т. д.

7 ответов


есть много библиотек, которые могут помочь вам извлечь ответ / подпись из сообщения:

Я также читал, что MailGun предлагает услугу для анализа входящей электронной почты и размещения ее содержимого на URL по вашему выбору. Он автоматически удаляет цитируемый текст из ваших писем:http://blog.mailgun.com/handle-incoming-emails-like-a-pro-mailgun-api-2-0/

надеюсь, что это поможет!


к сожалению, вы находитесь в мире больно, если вы хотите, чтобы попытаться очистить электронную почту тщательно (удаление все, что не является частью самого ответа электронной почты). The идеал способ был бы, как вы предлагаете, написать регулярное выражение для каждого популярного почтового клиента/службы, но это довольно смешной объем работы, и я рекомендую быть ленивым и тупым об этом.

интересно, даже инженеры Facebook иметь проблемы с это проблема, и Google имеет патент о методе "обнаружения цитируемого текста".

есть три решения, которые вы могли найти приемлемые:

Оставьте Его В Покое

первое решение-просто оставить все в сообщении. Большинство почтовых клиентов делают это, и никто не жалуется. Конечно, онлайн-системы сообщений (например, "сообщения" Facebook) выглядят довольно странно, если у них есть ответы в стиле начала. Один хитрый способ сделать эта работа хорошо, чтобы сделать сообщение с любыми цитируемыми строками свернутыми и включить небольшую ссылку на "развернуть цитируемый текст".

отделите ответ от старого сообщения

второе решение, как вы упомянули, заключается в том, чтобы поместить разграничительное сообщение в верхней части ваших сообщений, например --------- please reply above this line ----------, а затем очистите эту строку и что-нибудь ниже при обработке ответов. Многие системы делают это, и это не самое худшее в мире... но это делает ваш электронная почта выглядит более "автоматизированной" и менее личной (на мой взгляд).

Удалить Цитируемый Текст

последнее решение - просто удалить любую новую строку, начинающуюся с >, что, по-видимому, является цитируемой строкой из ответа по электронной почте. Большинство почтовых клиентов используют этот метод указания цитируемого текста. Вот некоторые регулярные выражения (в PHP), которые будут делать именно это:

$clean_text = preg_replace('/(^\w.+:\n)?(^>.*(\n|$))+/mi', '', $message_body);

есть некоторые проблемы с использованием этого проще метод:

  • многие почтовые клиенты также позволяют людям цитировать более ранние электронные письма и предварять эти строки цитатами > а также, Так что вы будете зачистки котировки.
  • обычно над цитируемым письмом есть строка с чем-то вроде On [date], [person] said. Эту строку трудно удалить, потому что она не отформатирована одинаково среди разных почтовых клиентов, и она может быть одной или двумя строками выше цитируемого текста, который вы удалили. Я реализовал этот метод обнаружения, с умеренным успех, в моем PHP Imap библиотека.

конечно, тестирование является ключевым, и компромиссы могут стоить того для вашей конкретной системы. YMMV.


возможно, полезная: quotequail это библиотека Python, которая помогает идентифицировать цитируемый текст в электронных письмах


Afaik, (стандартные) письма должны цитировать весь текст, добавляя " > " перед каждой строкой. Который вы можете удалить с помощью strstr (). В противном случае, вы пытались перенести этот пример Java на php? Это не что иное, как регулярное выражение.

даже такие страницы, как Github и Facebook, имеют эту проблему.


просто идея: у вас есть текст, который был первоначально отправлен, поэтому вы можете найти его и удалить его и дополнительный окружающий шум из ответа. Это не тривиально, потому что дополнительные разрывы строк, HTML-элементы, символы ">" добавляются почтовым клиентским приложением.

Регулярное выражение определенно лучше, если оно работает, потому что оно простое и отлично режет исходный текст, но если вы обнаружите, что оно часто не работает, это может быть резервным методом.


https://mailgun.com предлагает ответ extaction (удаление цитируемого контента), а также извлечение подписи как облако на основе ser. Я еще не проверял, но выглядит многообещающе.


Я согласен, что цитируемый текст или ответ-это просто текст. Так что точного способа достать его нет. В любом случае вы можете использовать regexp replace как это.

$filteringMessage = preg_replace('/.*\n\n((^>+\s{1}.*$)+\n?)+/mi', '', $message);