Как извлечь информацию из Raw Email - PullRequest
0 голосов
/ 17 марта 2019

Что я сделал до сих пор

Я использую пакет POP3 , чтобы читать все мои электронные письма из моего почтового ящика.

Я получил необработанное письмо от функции POP3, показанной в примере ниже. (Я пропустил некоторую информацию)

Выпуск

Я столкнулся с проблемой извлечения информации из нее.

Я использовал mail для извлечения информации, но, к сожалению, этот пакет не может извлечь информацию из необработанного электронного письма.

Ищу помощи

Есть ли какой-либо метод или пакет, который может помочь мне извлечь информацию из необработанного электронного письма?


Методы, которые я пробовал

// Retrieve all the email from your mailbox
msgs, _, error := connection.ListAll()

// Convert a chunk of integer to raw email
data, _ := connection.Retr(msgs[0])

// Extract Email Address
to, _ := mail.ParseAddress(data)

Ошибка, с которой я сталкиваюсь

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x5819ed]

Пример сырой электронной почты

From: 
To: 
Subject: 
Thread-Topic: 
Thread-Index: AdPgWzcFT3FjbSbUT1ycoU2ioB1bKAAAAHuA
X-MS-Exchange-MessageSentRepresentingType: 1
Date: 
Message-ID: 
Accept-Language: en-SG, en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: Internal
X-MS-Exchange-Organization-AuthMechanism: 04
X-MS-Exchange-Organization-AuthSource: 
X-MS-Has-Attach:
X-MS-Exchange-Organization-Network-Message-Id:
    8c1e141b-c3ba-4471-0526-08d5b3b59967
X-MS-TNEF-Correlator:
Content-Type: multipart/alternative;
    boundary="_002_b1a01aa36e1c4b3d9969a7bbb856bd3b"
MIME-Version: 1.0

--_002_b1a01aa36e1c4b3d9969a7bbb856bd3b
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64

PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVy
bjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVt
YXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWlj
cm9zb2Z0LmNvbS9vZmZpY2UvMjAwNC8xMi9vbW1sIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
VFIvUkVDLWh0bWw0MCI+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIg
Y29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4NCjxtZXRhIG5hbWU9IkdlbmVyYXRv
ciIgY29udGVudD0iTWljcm9zb2Z0IFdvcmQgMTUgKGZpbHRlcmVkIG1lZGl1bSkiPg0KPHN0eWxl
PjwhLS0NCi8qIEZvbnQgRGVmaW5pdGlvbnMgKi8NCkBmb250LWZhY2UNCgl7Zm9udC1mYW1pbHk6
IkNhbWJyaWEgTWF0aCI7DQoJcGFub3NlLTE6MiA0IDUgMyA1IDQgNiAzIDIgNDt9DQpAZm9udC1m
YWNlDQoJe2ZvbnQtZmFtaWx5OkRlbmdYaWFuOw0KCXBhbm9zZS0xOjIgMSA2IDAgMyAxIDEgMSAx
IDE7fQ0KQGZvbnQtZmFjZQ0KCXtmb250LWZhbWlseTpDYWxpYnJpOw0KCXBhbm9zZS0xOjIgMTUg
NSAyIDIgMiA0IDMgMiA0O30NCkBmb250LWZhY2UNCgl7Zm9udC1mYW1pbHk6IlxARGVuZ1hpYW4i
Ow0KCXBhbm9zZS0xOjIgMSA2IDAgMyAxIDEgMSAxIDE7fQ0KLyogU3R5bGUgRGVmaW5pdGlvbnMg
Ki8NCnAuTXNvTm9ybWFsLCBsaS5Nc29Ob3JtYWwsIGRpdi5Nc29Ob3JtYWwNCgl7bWFyZ2luOjBj
bTsNCgltYXJnaW4tYm90dG9tOi4wMDAxcHQ7DQoJZm9udC1zaXplOjExLjBwdDsNCglmb250LWZh
bWlseToiQ2FsaWJyaSIsc2Fucy1zZXJpZjt9DQphOmxpbmssIHNwYW4uTXNvSHlwZXJsaW5rDQoJ
e21zby1zdHlsZS1wcmlvcml0eTo5OTsNCgljb2xvcjojMDU2M0MxOw0KCXRleHQtZGVjb3JhdGlv
bjp1bmRlcmxpbmU7fQ0KYTp2aXNpdGVkLCBzcGFuLk1zb0h5cGVybGlua0ZvbGxvd2VkDQoJe21z
by1zdHlsZS1wcmlvcml0eTo5OTsNCgljb2xvcjojOTU0RjcyOw0KCXRleHQtZGVjb3JhdGlvbjp1
bmRlcmxpbmU7fQ0KcC5tc29ub3JtYWwwLCBsaS5tc29ub3JtYWwwLCBkaXYubXNvbm9ybWFsMA0K
CXttc28tc3R5bGUtbmFtZTptc29ub3JtYWw7DQoJbXNvLW1hcmdpbi10b3AtYWx0OmF1dG87DQoJ
bWFyZ2luLXJpZ2h0OjBjbTsNCgltc28tbWFyZ2luLWJvdHRvbS1hbHQ6YXV0bzsNCgltYXJnaW4t
bGVmdDowY207DQoJZm9udC1zaXplOjEyLjBwdDsNCglmb250LWZhbWlseToiVGltZXMgTmV3IFJv
bWFuIixzZXJpZjt9DQpzcGFuLkVtYWlsU3R5bGUxOA0KCXttc28tc3R5bGUtdHlwZTpwZXJzb25h
bC1jb21wb3NlOw0KCWZvbnQtZmFtaWx5OiJDYWxpYnJpIixzYW5zLXNlcmlmOw0KCWNvbG9yOndp
bmRvd3RleHQ7fQ0KLk1zb0NocERlZmF1bHQNCgl7bXNvLXN0eWxlLXR5cGU6ZXhwb3J0LW9ubHk7
DQoJZm9udC1zaXplOjEwLjBwdDsNCglmb250LWZhbWlseToiQ2FsaWJyaSIsc2Fucy1zZXJpZjt9
DQpAcGFnZSBXb3JkU2VjdGlvbjENCgl7c2l6ZTo2MTIuMHB0IDc5Mi4wcHQ7DQoJbWFyZ2luOjcy
LjBwdCA3Mi4wcHQgNzIuMHB0IDcyLjBwdDt9DQpkaXYuV29yZFNlY3Rpb24xDQoJe3BhZ2U6V29y
ZFNlY3Rpb24xO30NCi0tPjwvc3R5bGU+PCEtLVtpZiBndGUgbXNvIDldPjx4bWw+DQo8bzpzaGFw
ZWRlZmF1bHRzIHY6ZXh0PSJlZGl0IiBzcGlkbWF4PSIxMDI2IiAvPg0KPC94bWw+PCFbZW5kaWZd
LS0+PCEtLVtpZiBndGUgbXNvIDldPjx4bWw+DQo8bzpzaGFwZWxheW91dCB2OmV4dD0iZWRpdCI+
DQo8bzppZG1hcCB2OmV4dD0iZWRpdCIgZGF0YT0iMSIgLz4NCjwvbzpzaGFwZWxheW91dD48L3ht
bD48IVtlbmRpZl0tLT4NCjwvaGVhZD4NCjxib2R5IGxhbmc9IkVOLVNHIiBsaW5rPSIjMDU2M0Mx
IiB2bGluaz0iIzk1NEY3MiI+DQo8ZGl2IGNsYXNzPSJXb3JkU2VjdGlvbjEiPg0KPHAgY2xhc3M9
Ik1zb05vcm1hbCI+PG86cD4mbmJzcDs8L286cD48L3A+DQo8L2Rpdj4NCjxicj4NCjxociBhbGln
bj0ibGVmdCIgc3R5bGU9Im1hcmdpbi1sZWZ0OjA7dGV4dC1hbGlnbjpsZWZ0O3dpZHRoOjUwJTto
ZWlnaHQ6MXB4O2JhY2tncm91bmQtY29sb3I6Z3JheTtib3JkZXI6MHB4OyI+DQo8Zm9udCBzdHls
ZT0iY29sb3I6Z3JheTsiIHNpemU9Ii0xIj5UaGlzIGVtYWlsIHdhcyBzY2FubmVkIGJ5IEJpdGRl
ZmVuZGVyPC9mb250Pg0KPC9ib2R5Pg0KPC9odG1sPg0K

--_002_b1a01aa36e1c4b3d9969a7bbb856bd3b
Content-Type: text/calendar; charset="utf-8"; method=REQUEST
Content-Transfer-Encoding: base64

QkVHSU46VkNBTEVOREFSDQpNRVRIT0Q6UkVRVUVTVA0KUFJPRElEOk1pY3Jvc29mdCBFeGNoYW5n
ZSBTZXJ2ZXIgMjAxMA0KVkVSU0lPTjoyLjANCkJFR0lOOlZUSU1FWk9ORQ0KVFpJRDpTaW5nYXBv
cmUgU3RhbmRhcmQgVGltZQ0KQkVHSU46U1RBTkRBUkQNCkRUU1RBUlQ6MTYwMTAxMDFUMDAwMDAw
DQpUWk9GRlNFVEZST006KzA4MDANClRaT0ZGU0VUVE86KzA4MDANCkVORDpTVEFOREFSRA0KQkVH
SU46REFZTElHSFQNCkRUU1RBUlQ6MTYwMTAxMDFUMDAwMDAwDQpUWk9GRlNFVEZST006KzA4MDAN
ClRaT0ZGU0VUVE86KzA4MDANCkVORDpEQVlMSUdIVA0KRU5EOlZUSU1FWk9ORQ0KQkVHSU46VkVW
RU5UDQpPUkdBTklaRVI7Q049SG8gU2lldyBLZWU6TUFJTFRPOkhPX1NpZXdfS2VlQGlwaS1zaW5n
YXBvcmUub3JnDQpBVFRFTkRFRTtST0xFPVJFUS1QQVJUSUNJUEFOVDtQQVJUU1RBVD1ORUVEUy1B
Q1RJT047UlNWUD1UUlVFO0NOPUtvaCBXZWUgSG8NCiBuZzpNQUlMVE86S09IX1dlZV9Ib25nQGlw
aS1zaW5nYXBvcmUub3JnDQpERVNDUklQVElPTjtMQU5HVUFHRT1lbi1VUzpcblxuX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19cblRoaXMgZW1haWwNCiAgd2FzIHNjYW5uZWQgYnkgQml0
ZGVmZW5kZXJcbg0KVUlEOjA0MDAwMDAwODIwMEUwMDA3NEM1QjcxMDFBODJFMDA4MDAwMDAwMDA0
MDEzMTY0NzlFRTBEMzAxMDAwMDAwMDAwMDAwMDAwDQogMDEwMDAwMDAwMzQ5NDcwQUMzMzQ0NzM0
MDk5QzM0OEE0M0E0M0ZCREMNClNVTU1BUlk7TEFOR1VBR0U9ZW4tVVM6SFIgT3JpZW50YXRpb246
IEtvaCBXZWUgSG9uZyAoQU0gLSBEaWdpdGFsIFBsYXRmb3Jtcw0KICkNCkRUU1RBUlQ7VFpJRD1T
aW5nYXBvcmUgU3RhbmRhcmQgVGltZToyMDE4MDUwN1QxNDAwMDANCkRURU5EO1RaSUQ9U2luZ2Fw
b3JlIFN0YW5kYXJkIFRpbWU6MjAxODA1MDdUMTUzMDAwDQpDTEFTUzpQVUJMSUMNClBSSU9SSVRZ
OjUNCkRUU1RBTVA6MjAxODA1MDdUMDA1ODA2Wg0KVFJBTlNQOk9QQVFVRQ0KU1RBVFVTOkNPTkZJ
Uk1FRA0KU0VRVUVOQ0U6Mw0KTE9DQVRJT047TEFOR1VBR0U9ZW4tVVM6Q29ubmVjdGlvbg0KWC1N
SUNST1NPRlQtQ0RPLUFQUFQtU0VRVUVOQ0U6Mw0KWC1NSUNST1NPRlQtQ0RPLU9XTkVSQVBQVElE
OjEzMDY0MTMwMjYNClgtTUlDUk9TT0ZULUNETy1CVVNZU1RBVFVTOlRFTlRBVElWRQ0KWC1NSUNS
T1NPRlQtQ0RPLUlOVEVOREVEU1RBVFVTOkJVU1kNClgtTUlDUk9TT0ZULUNETy1BTExEQVlFVkVO
VDpGQUxTRQ0KWC1NSUNST1NPRlQtQ0RPLUlNUE9SVEFOQ0U6MQ0KWC1NSUNST1NPRlQtQ0RPLUlO
U1RUWVBFOjANClgtTUlDUk9TT0ZULURJU0FMTE9XLUNPVU5URVI6RkFMU0UNCkJFR0lOOlZBTEFS
TQ0KREVTQ1JJUFRJT046UkVNSU5ERVINClRSSUdHRVI7UkVMQVRFRD1TVEFSVDotUFQxNU0NCkFD
VElPTjpESVNQTEFZDQpFTkQ6VkFMQVJNDQpFTkQ6VkVWRU5UDQpFTkQ6VkNBTEVOREFSDQo=

--_002_b1a01aa36e1c4b3d9969a7bbb856bd3b

1 Ответ

3 голосов
/ 17 марта 2019

Теория

Сообщения электронной почты форматируются с использованием в основном одного из следующих двух форматов.

Самый старый из них определяется как RFC 5322 (изначально это былоRFC 822, но с тех пор он был обновлен).

Этот формат не поддерживает сообщения, использующие кодировки символов, отличные от ASCII, и не поддерживает общедоступные выражения «вложения».

Для исправленияВ этой ситуации был изобретен набор стандартов, широко известный как MIME .Стандарты в этом наборе определяют:

  • Способы использования кодировок не-ASCII.
  • Способы составления составных сообщений.

Два самых интересных стандарта MIME: RFC 2045 и RFC 2046 .

Стандарты, включенные в MIME, были специально разработаны для того, чтобы сделать MIME-закодированный материал, все еще совместимый с RFC 822 - это, среди прочего, позволило не изменять MTA для поддержки нового формата сообщений.

Практика

Библиотеки, реализованные в различныхЯзыки программирования для работы с различными битами, определенными MIME, обычно следуют тенденции самого MIME и способны прозрачно обрабатывать «простые» письма в формате RFC 822 и MIME.

Для обработки сообщений в формате MIME,Go предлагает в своей стандартной библиотеке три пакета:

иеще один, net/textproto, для работы с заголовками в стиле MIME (также используется в HTTP, IMAP / POP3 и т. д.).

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

Основной подход к синтаксическому анализу

Основной подход к синтаксическому анализу сообщений электронной почты заключается в следующем:

  1. Создайте экземпляр bufio.Reader из io.Reader, предоставляющего данные сообщения электронной почты для анализа.

  2. Создайте экземпляр net/textproto.Reader из bufio.Reader, сделанного на предыдущем шаге.

  3. Используйте его метод ReadMIMEHeader(), чтобы прочитать и проанализировать блок заголовка сообщения.

  4. Проверьте, содержит ли оно поле MIME-Version, предписанное RFC 2045 для указания содержимого в формате MIME.

    1. Если оно содержит одно,убедитесь, что его значение буквально "1.0".Если это не так, то это какой-то MIME-формат из будущего, с которым вы не сможете справиться.Барф соответственно;в противном случае переходите к следующему шагу.
    2. Если такого поля нет, сообщение представляет собой простой старый электронный адрес, состоящий из одной части.Рассматривайте все его содержимое так, как если бы оно было одной частью сообщения MIME (это упрощенно, но в основном будет работать).
  5. Если вы убедились, что имеете дело с MIME1.0, затем

    1. Считайте поле заголовка Content-Type, затем используйте mime.ParseMediaType() для его анализа.
      • Если результирующее значение mediatype будет начинаться с префикса «multipart /», буквально, тогда будьте готовы работать с несколькими частями, которые требуют рекурсивной обработки, поскольку каждая часть отформатирована почти как сообщение верхнего уровня- то есть содержит заголовок и тело (см. Ниже).
      • В противном случае тип содержимого будет указывать на какую-то «прямую» полезную нагрузку (например, «text / plain» или «text / html» или что-либо еще).).В этом случае специальный «параметр» такого типа носителя (см. Ниже) указывает кодировку символов, используемую для содержимого детали, если оно текстовое.(Также обратите внимание, что это может быть «message / rfc822», которое фактически указывает на то, что полезная нагрузка является другим сообщением электронной почты, которое, возможно, потребуется проанализировать в соответствии с теми же правилами, что и в кодировке.)

Работа с "листовой" частью или полезными нагрузками сообщений, не состоящих из нескольких частей

Поле заголовка важной для чтения следующей строки - Content-Transfer-Encoding, которое определяет физическую часть детализакодирован для передачи по проводам.

В большинстве случаев это будет «base64», но также может быть и «цитируемым».

Работа с сообщениями, состоящими из нескольких частей

Во-первых, будьте готовы правильно разобраться с различными аспектами того, что такое «многочастная часть»: детали могут быть либо альтернативами друг другу, то есть программой, которая должна передать сообщение пользователь может выбрать любой из них - все, что лучше всего соответствует предпочтениям пользователя, или спросить их или что-то еще, - или они могут быть сущностями, примерно равными друг другу. Первая схема обозначена мультимедийным типом «multipart / alternative» и обычно используется MUA, которые позволяют пользователю составлять почтовое сообщение с использованием разметки, а затем кодировать результат так, чтобы он содержал две альтернативные части - одну, помеченную как «text /». html "и еще один, помеченный как" text / plain "и содержащий исходный контент без этой разметки. Последнее обозначается как «multipart / mixed» и обычно используется для вложений: в этой схеме первая часть обычно (но это не обязательно) является текстом сообщения в любом формате, а остальные части являются вложениями.

Чтобы иметь возможность выбирать отдельные части из кодировки сообщения, мультимедийный тип "multipart / what" большую часть времени содержит так называемый "параметр" с именем "border" и содержит уникальную строку, которая используется для разграничить части. Функция mime.ParseMediaType() возвращает параметры типа носителя в виде карты в качестве второго значения результата.

После извлечения этого «граничного» параметра типа носителя, Вы можете использовать его для создания экземпляра mime/multipart.Reader из экземпляра bufio.Reader, созданного на самом первом шаге. Затем вы можете прочитать части сообщения одну за другой и действовать по ним.

Обратите внимание, что, как уже указывалось, часть сообщения может иметь тип содержимого "message / rfc822", что означает, что оно содержит еще одно полное почтовое сообщение (и само оно может быть составным, содержать другие почтовые сообщения и т. Д.) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...