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

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

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

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

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

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

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

On Wed, Nov 2, 2011 at 10:34 AM, Message Platform <[email protected]> wrote:
## In replies all text above this line is added to your message conversation ##

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

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

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

Ответ 1

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

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

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

Ответ 2

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

Интересно, что даже инженеры 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.

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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

Test https://regex101.com/r/xO8nI1/2