Что нового

[Автоматизация] pop.ya.ru Чтение новой почты и ее обработка

kristow13

Новичок
Сообщения
76
Репутация
0
Находил темы с авторизацией pop3.
Но не могу понять как можно определять что письмо не прочитано? И как прочитать от кого письмо, тему письма, и содержание???
Помогите пожалуйста примером :-[
Хочу написать скрипт, который будет следить за входящими письмами, читать новые, если письмо от нужного адресата, то читать тему и содержание письма, с дальнейшей записью в базу данных...
Буду благодарен за любую помощь! Спасибо :beer:
 

erlik

Продвинутый
Сообщения
317
Репутация
84
Вот это для затравки. Перекодировку полей From и Subject - там Base64 и чего то еще - сделайте самостоятельно.
У меня пока не получилось. Текст письма возвращает _Pop3Top(НомерСообщения, ЧислоСтрокПисьма или -1 ВесьТекст), но так как сначала возвращаются служебные заголовки - нужно парсить нужный текст. В примере возвращаются тема, от кого, дата. Сервер почты меняйте на свой.
Код:
#include <array.au3>
#include <_pop3.au3>
#include <Encoding.au3>

$MyPopServer = 'pop3.mail.ru'
$MyLogin     = ''
$MyPasswd    = ''

_pop3Connect($MyPopServer, $MyLogin, $MyPasswd)
If @error Then
	MsgBox(0, "Error", "Unable to connect to " & $MyPopServer & @CR & @error)
	Exit
Else
	ConsoleWrite("Connected to server pop3 " & $MyPopServer & @CR)
EndIf

$aPop3Stat = _Pop3Stat()
If @error Then
	MsgBox(0, "Error", "Unable get statistics " & $MyPopServer & @CR & @error)
	Exit
Else
	;_ArrayDisplay($aPop3Stat)
	ConsoleWrite('TOTAL MSG:'  & $aPop3Stat[1] & @CRLF)
	ConsoleWrite('SIZE MSG:'   & $aPop3Stat[2] & @CRLF)
EndIf

Local $From = 'unknown'
Local $Subject = 'unknown'
Local $Date = 'unknown'
Local $aData
For $iMsg = 1 To $aPop3Stat[1]
	$aPop3List = _Pop3List($iMsg)
	If Not IsArray($aPop3List) Then ContinueLoop
	;_ArrayDisplay($aPop3List)
	$Size = StringSplit($aPop3List[1], ' ', 2)
	$sHeaders = _Pop3Top($iMsg, 0) ; вернем заголовки
	;ConsoleWrite($sHeaders & @CRLF )
	$aData = StringRegExp($sHeaders, '(?m)^From:\s*(.+)$', 1)
	If IsArray($aData) Then
		$From=$aData[0]
		;$From = _Encoding_Base64Decode($From)
	EndIf
	$aData = StringRegExp($sHeaders, '(?m)^Subject:\s*(.+)$', 1)
	If IsArray($aData) Then
		$Subject=$aData[0]
		;$Subject = _Encoding_Base64Decode($Subject)
	EndIf
	$aData = StringRegExp($sHeaders, '(?m)^Date:\s*(.+)$', 1)
	If IsArray($aData) Then
		$Date =$aData[0]
	EndIf

		ConsoleWrite( _
		'===================================='   & @CRLF & _
		'№ MSG:'   & $iMsg                       & @CRLF & _
		'SIZE:'    & $Size[1]                    & @CRLF & _
		'DATE:'    & StringStripCR($Date)        & @CRLF & _
		'FROM:'    & StringStripCR($From)        & @CRLF & _
		'SUBJECT:' & StringStripCR($Subject)     & @CRLF _
		)
Next


ConsoleWrite(_Pop3Quit() & @CR)
_pop3Disconnect()
 
Автор
kristow13

kristow13

Новичок
Сообщения
76
Репутация
0
Спасибо Erlik! :ok:
Код помог продвинуться, разбил на массив полученный ответ FROM и получил чистый email письма. Все вижу что хотел!
В коде есть закоментированные строки _Encoding_Base64Decode, если разкоментирую, то ничего в результат не выводится.... Не понятно почему.

Еще момент, код выводит все сообщения, которые есть в ящике, хотелось бы сделать так, чтобы читать только непрочитанные сообщения, а потом переводить письмо в прочитано... Или через POP такое не возможно?
 

erlik

Продвинутый
Сообщения
317
Репутация
84
хотелось бы сделать так, чтобы читать только непрочитанные сообщения
Решения пока нет. Сам протокол судя по всему ничего такого не предусматривает.
----------------------------------------------------------------------------------------------------
С кодировками тоже полная ж... Вот обновленный вариант кода с функцией ContentTransferEncoding - она частично декодирует заголовки. Но тут на каждый вариант кодировки нужно изворчиваться и делать что то специфическое.
Универсального пока нифига не вышло.
Может кто еще темой заинтересуется - поможет.
Код:
Func _Pop3()
$MyPopServer = 'pop3.mail.ru'
$MyLogin     = ''
$MyPasswd    = ''

_pop3Connect($MyPopServer, $MyLogin, $MyPasswd)
If @error Then
		MsgBox(0, "Error", "Unable to connect to " & $MyPopServer & @CR & @error)
	Exit
Else
	ConsoleWrite("Connected to server pop3 " & $MyPopServer & @CR)
EndIf

$aPop3Stat = _Pop3Stat()
If @error Then
		MsgBox(0, "Error", "Unable get statistics " & $MyPopServer & @CR & @error)
		ConsoleWrite(_Pop3Quit() & @CR)
        _pop3Disconnect()
	Exit
Else
	;_ArrayDisplay($aPop3Stat)
	ConsoleWrite('TOTAL MSG:'  & $aPop3Stat[1] & @CRLF)
	ConsoleWrite('SIZE MSG:'   & $aPop3Stat[2] & @CRLF)
EndIf

Local $From            = 'unknown'
Local $Subject         = 'unknown'
Local $Date            = 'unknown'
Local $ContentType     = 'unknown'
Local $ContentEncoding = 'unknown'

Local $aData
For $iMsg = 1 To $aPop3Stat[1]
	$aPop3List = _Pop3List($iMsg)
	If Not IsArray($aPop3List) Then ContinueLoop
	;_ArrayDisplay($aPop3List)
	$Size = StringSplit($aPop3List[1], ' ', 2)
	$sHeaders = _Pop3Top($iMsg, 0)  ; вернем заголовки
    ;$sHeaders = _Pop3Top($iMsg, -1) ; вернем заголовки и текст письма
	;ConsoleWrite($sHeaders & @CRLF )

	$aData = StringRegExp($sHeaders, '(?m)^Content-Type:\s*(.+)$', 1)
	If IsArray($aData) Then
		$ContentType = StringStripCR($aData[0])
	EndIf

	$aData = StringRegExp($sHeaders, '(?m)^Content-Transfer-Encoding:\s*(.+)$', 1)
	If IsArray($aData) Then
		$ContentEncoding = StringStripCR($aData[0])
	EndIf

    $aData = StringRegExp($sHeaders, '(?m)^From:\s*(.+)$', 1)
	If IsArray($aData) Then
		$From = StringStripCR($aData[0])
		$From = ContentTransferEncoding($ContentEncoding,$From)
	EndIf

	$aData = StringRegExp($sHeaders, '(?m)^Subject:\s*(.+)$', 1)
	If IsArray($aData) Then
		$Subject = StringStripCR($aData[0])
		$Subject = ContentTransferEncoding($ContentEncoding,$Subject)
	EndIf

	$aData = StringRegExp($sHeaders, '(?m)^Date:\s*(.+)$', 1)
	If IsArray($aData) Then
		$Date =StringStripCR($aData[0])
	EndIf

    ConsoleWrite( _
		'====================================' & @CRLF & _
		'№ MSG: '        & $iMsg               & @CRLF & _
		'SIZE: '         & $Size[1]            & @CRLF & _
		'Content-Type: ' & $ContentType        & @CRLF & _
		'Encoding: '     & $ContentEncoding    & @CRLF & _
		'DATE: '         & $Date               & @CRLF & _
		'FROM: '         & $From               & @CRLF & _
		'SUBJECT: '      & $Subject            & @CRLF _
		)
Next

EndFunc


Func ContentTransferEncoding($sType,$Data)
    ;ConsoleWrite('=====================================' &@CRLF)
    ;ConsoleWrite('GetCyrillic:' & _Encoding_GetCyrillicANSIEncoding($Data)&@CRLF)

	Local $IsCyrillic = _Encoding_GetCyrillicANSIEncoding($Data)
	If $IsCyrillic  Then Return _Encoding_CyrillicTo1251($Data)

	Local $Email ='', $aData
    Local $sPattern='(?i)(?:UTF-8B|utf-8B|UTF-8Q|utf-8Q|KOI8-RB|windows-1251B)([A-Za-z0-9+/.@!]+)(\s<.*>)?'
    $CleanData=StringRegExpReplace($Data,'[=?]','')
    If Not @error  Then $Data=$CleanData


	;ConsoleWrite('[=?]:' & $Data & @CRLF)
    $aData = StringRegExp($Data,$sPattern,2)
		If Not @error  Then
		$Data  = $aData[1]
			If Ubound($aData)>2 Then
			    $Email = $aData[2]
		        ;ConsoleWrite('PATTERN:' & $Data & $Email & @CRLF)
			Else
			    $Email=''
			EndIf
		EndIf

     Switch $sType

		Case 'quoted-printable'

			Return _Encoding_CyrillicTo1251(_Encoding_QuotedPrintableToANSI($Data)) & $Email

		Case Else
			If Not _Encoding_Base64Decode($Data) Then Return $Data
			Return _Encoding_CyrillicTo1251(_Encoding_Base64Decode($Data)) & $Email

		EndSwitch
EndFunc
 
Автор
kristow13

kristow13

Новичок
Сообщения
76
Репутация
0
Ну да прикольно, но еще я заметил что не выводится совсем содержание писем...
Хоть я для теста и отсылал числа и текст на англ. Все равно не видать...
Да и нехватка распознавания статуса писем не хватает... Буду другой вариант смотреть...
 

erlik

Продвинутый
Сообщения
317
Репутация
84
не выводится совсем содержание писем
У меня выводится - если -1 передать в _Pop3Top. Весь текст в большинстве случаев в base64. Кроме писем в Windows-1251. Там сразу нормальной кирилицей идет. Но на одном из писем скрипт намертво зависает и дальше контент не выводит. Если выводить по 10 строк письма - тогда не виснет.
UDF, конечно, крайне недоработана - нужно много чего регекспами вытаскивать. То же содержимое писем нужно как то отделять от заголовков. С перекодированием текста что то придумывать. Но другой UDF, которая бы решала все эти вопросы пока нет.
 
Верх