Xameleon, хорошо.
Я, правда, не уверен, что настолько полезно (времени написать нормальный пример сейчас нет).
Код на Powershell (можно заменить любым языком, что поддерживает вызовы из .Net библиотек), для работы с IMAP используется MailKit и встроенные средства. Версия интерпретатора должна быть не ниже 3 (лучше выше), но, при необходимости, можно переписать пару моментов и заработает в 2-ке. Я думаю, что большого труда перенести это на Python/AutoIt/что-то_другое не составит.
Пример 1.
Цепляемся к IMAP-серверу mail.example.com для пользователя user. Получаем непрочитанные сообщения для подпапки (точнее для двух дочерних, относительно INBOX'а, folder1 и folder2). В теле письма есть ссылка на файл (с определённого домена, example.org, на этом домене web-сервер с авторизацией, но скачать файл он вам даст только по https, хотя ссылки будут приходить на http, и ссылка выдирается и htmlbody письма с заменой uri.scheme), скачиваем его (имя берётся из htmlbody, т.к. на web-сервере ссылки вида "example.org/files/xxxxxxxxxxxx", а Powershell не умеет нормально content-disposition) и пересылаем исходник письма на др. адрес (user2, на том же домене example.com, но это не принципиально) вложив скачанный файл (тема письма заменяется на "FW: имя файла"). SMTP-авторизация в примере не используется. После обработки исходное письмо письмо будет отмечено прочитанным.
# я не устанавливал mailkit, mimekit, bounce_castle, т.к. требовалось "портабельное" решение.
# библиотеки положить вместе со скриптом ну или установить.
$loadedassemblies = [appdomain]::currentdomain.getassemblies()
'BouncyCastle.Crypto', 'mimekit', 'mailkit' | %{ $assemblyname = $_
if (! (($loadedassemblies | %{($_.FullName -split ',')[0]}) -contains $assemblyname)) {
Add-Type -Path "$(Join-Path $PSScriptRoot ($_ + '.dll'))"
}
}
$mll = New-Object MailKit.Net.Imap.ImapClient
$ctoken = New-Object System.Threading.CancellationToken ($false)
$ssl = [MailKit.Security.SecureSocketOptions]::SslOnConnect
$mll.Connect('mail.example.com', 993, $ssl, $ctoken)
$mll.Authenticate(([System.Text.Encoding]::UTF8) , "user@example.com", "strongpassword" , $ctoken)
$folders = 'folder1','folder2'
foreach ($folder in $folders) {
$inbox = $mll.Inbox
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$inbox = $inbox.GetSubfolders($false) | ?{$_.Name -eq $folder}
$inbox.Open([MailKit.FolderAccess]::ReadWrite) | Out-Null
$msgs = $inbox.Search([MailKit.Search.SearchQuery]::NotSeen)
foreach ($msg in $msgs) {
try {
$eml = $inbox.GetMessage([MailKit.UniqueId]$msg.Id)
}
catch {
$_
}
$emlhtml = New-Object -Com "HTMLFile"
$content = $eml.HtmlBody
try {
$emlhtml.IHTMLDocument2_write($content)
}
catch {
$src = [System.Text.Encoding]::Unicode.GetBytes($content)
$emlhtml.write($src)
}
$files = $emlhtml.links | ?{$_.hostname -eq 'example.org'} | %{
$url = [System.Uri]$_.Href
if ($url.Scheme -eq 'http') {
$url = [System.Uri]$('https://' + $url.Host + $url.AbsolutePath)
}
$file = $_.TextContent
$username = "user"
$password = "password"
$encoded = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($username + ":" + $password))
$headers = @{Authorization = "Basic "+$encoded}
$cred = (New-Object System.Management.Automation.PSCredential($username,($password | ConvertTo-SecureString -AsPlainText -Force)))
$useragent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"
$outFilePath = Join-Path $PSScriptRoot $file
try {
$r = Invoke-WebRequest -Uri $url -Headers $headers -UserAgent $useragent -Method get -OutFile $outFilePath -PassThru
}
catch {
$site = $_.Exception.Response
}
gi $outFilePath
}
Send-MailMessage -To "user2@example.com" -Subject $('FW: ' + $files.Name) -Body $($emlhtml | %{$_.Body.OuterHtml}) -BodyAsHtml -Encoding UTF8 -SmtpServer "mail.example.com" -From "user@example.com" -Port 25 -Attachments $files.FullName
$inbox.AddFlags([MailKit.UniqueId]$msg.Id, ([MailKit.MessageFlags]::Seen), $true)
}
$inbox.Close()
}
$mll.Disconnect($true , $ctoken)
Комментариев почти нет, но если кому-то будет интересно, то набросаю ещё несколько примеров на выходных (нормальных, а не как этот) и приведу в порядок этот (например, вынесу переменные и нормальные имена и комментарии напишу - увы, работа сейчас не позволяет хорошо написать пример). Код выглядит страшно, но работает (во всяком случае, когда я проверял возможности Mailkit, подойдёт ли она мне для работы - этот пример вполне себе работал). Возможные примеры, которые смогу набростать - обработка вложений, загрузка файлов на WEB-сервер (POST), обработка вложенных xls/xlsx (получение данных и/или сохранение в csv), и конкретно для IMAP-сервера: рекурсивный обход папок, получение всех сообщений (и можно даже сделать mirror в др. ящик), сортировка/перемещение сообщений, фильтрация списка сообщений по дате, отправителю, теме и т.п., проверку сертификата перед подключением (в примере подключение идёт по TLS, но валидность сертификата не проверяется).
Рабочие скрипты у меня "покрасивше" с "функциями и обработкой ошибок", но перелопатить неск. сот кб. скриптов я попросту не успеваю.
Модуль PSGSuite для Powershell умеет работать с GMAIL, но что конкретно он умеет, я особо не смотрел (ну кроме очевидного - подключиться к ящику, получить список непрочитанных, получить сообщения) - возможно он уже умеет то, что просил ТС.
Если захотим не пересылать письмо, а сохранить его куда-нибудь в WEB, то на помощь придёт Invoke-RestMethod (заставить его работать для тех же dropbox, bitbucket, в принципе, возможно), который, можно заменить на curl.