imap. Пример.
Авторизуемся на сервере imap. выбираем для работы ящик "INBOX". Ищем непросмотренные письма с датой больше 7 марта 2019 года. Получаем номера непросмотренных писем. Запрашиваем заголовочную часть письма с номером 5. Разбираем заголовочную секцию (ENVELOPE) на части. Запрашиваем тело письма с номером 5.
(примеры вывода внизу)
//компиляция
//cd "C:\Program Files\Java\jdk1.8.0_151\bin"
//javac.exe MyImap.java
//java.exe MyImap
import java.net.*;
import java.io.*;
import javax.net.ssl.*;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class MyImap{
private static String get_data_imap(BufferedReader in, String key) throws Exception {
String res = "";
String inputLine;
int l;
while ((inputLine = in.readLine()) != null){
res = res + inputLine + "\r\n";
l = inputLine.length();
if (l > 1)
if(inputLine.substring(0, 2).equals(key)) //key - двухсимвольный
break;
}
return res;
}
private static void PrintArrayEnvelope(String[][] arr) throws Exception{
System.out.println(arr[0][0]);
System.out.println(arr[1][0]);
for (int cc = 2; cc < 8; cc++){
System.out.println(arr[cc][0] + " " + arr[cc][1] + " " + arr[cc][2] + "@" + arr[cc][3]);
}
System.out.println(arr[8][0]);
System.out.println(arr[9][0]);
}
private static String decodefield(String textIn) throws Exception{
String out = "";
String[] parts;
byte[] decoded;
parts = textIn.split("\\?");
//расчитываем на определенную структуру
if(parts.length == 5){
if ( (parts[0].equals("=")) & (parts[4].equals("=")) ){
if(parts[2].equals("B")){
decoded = Base64.getDecoder().decode(parts[3]);
out = new String(decoded, StandardCharsets.UTF_8); // parts[1] utf-8
}
else // "Q" - quoted printable
out = parts[3]; //пока без раскодирования Quoted Printable
}else
return textIn;
}else
return textIn;
return out;
}
private static String[] decodeAddressStruct(String Addr) throws Exception{
String[] arr = new String[4];
String ch;
int i, y, length;
length = Addr.length();
i = -1;
for (int cc = 0; cc < 4; cc++){
i = i+1;
if((i > length) | (i == length) ){
arr[cc] = "";
continue;
}
ch = Addr.substring(i, i+1);
if(ch.equals("\"")){
y = Addr.indexOf("\"", i+1);
if (cc == 0)
arr[cc] = decodefield(Addr.substring(i+1, y));
else
arr[cc] = Addr.substring(i+1, y);
i = y + 1; //пробел
}else{ // NIL
y = Addr.indexOf(" ", i+1);
if (y != -1){
if(Addr.substring(i, y).equals("NIL"))
arr[cc] = "";
else
arr[cc] = Addr.substring(i, y);
i = y;
}else{ //пробелов больше нет
if(Addr.equals("NIL"))
arr[cc] = "";
else
arr[cc] = Addr.substring(i);
i = length;
}
}
}
return arr;
}
private static String[][] ParsingEnvelope(String str1) throws Exception {
// https://tools.ietf.org/html/rfc3501#section-7.4.2
// The fields of the envelope structure are in the following
// order: date, subject, from, sender, reply-to, to, cc, bcc,
// in-reply-to, and message-id. The date, subject, in-reply-to,
// and message-id fields are strings. The from, sender, reply-to,
// to, cc, and bcc fields are parenthesized lists of address
// structures.
// An address structure is a parenthesized list that describes an
// electronic mail address. The fields of an address structure
// are in the following order: personal name, [SMTP]
// at-domain-list (source route), mailbox name, and host name.
String[] arr = new String[10]; //envelope
String[][] addressStructure = new String[10][4];
String ch;
int i;
int y;
int cc;
/////////////// 1 ///////// разбиваем строку элементов на массив из 10 элементов
i = -1;
for (cc = 0; cc < 10; cc++){
i = i+1;
ch = str1.substring(i, i+1);
if(ch.equals("\"")){
y = str1.indexOf("\"", i+1);
arr[cc] = str1.substring(i+1, y);
i = y + 1; //пробел
}else if(ch.equals("(")){
y = str1.indexOf("))", i+1);
arr[cc] = str1.substring(i+2, y);
i = y + 2; //пробел
}else{ //NIL
y = str1.indexOf(" ", i+1);
arr[cc] = str1.substring(i, y);
i = y; //пробел
}
}
/////////////// 2 //////// окончательный разбор полей (структура адреса)
addressStructure[0][0] = arr[0]; // date; оставляем без изменения
addressStructure[1][0] = decodefield(arr[1]); //subject;
addressStructure[2] = decodeAddressStruct(arr[2]); //from
addressStructure[3] = decodeAddressStruct(arr[3]); //sender
addressStructure[4] = decodeAddressStruct(arr[4]); //reply-to
addressStructure[5] = decodeAddressStruct(arr[5]); //to
addressStructure[6] = decodeAddressStruct(arr[6]); //cc
addressStructure[7] = decodeAddressStruct(arr[7]); //bcc
addressStructure[8][0] = (arr[8].equals("NIL") == true) ? "" : arr[8]; //in-reply-to; оставляем без изменения
addressStructure[9][0] = arr[9]; //message-id; оставляем без изменения
return addressStructure;
}
public static void main(String[] args) throws Exception {
try {
SSLSocketFactory factory =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket =
(SSLSocket)factory.createSocket("imap.majordomo.ru", 993);
socket.startHandshake();
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())));
/* read response */
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
String inputLine, key, ch, dataEnvelope, str1;
String ArrayEnvelope[][] = new String[10][4];
String ENV = "";
int i, spaceBalans, spaceF, cc;
int y = 0;
if ((inputLine = in.readLine()) != null)
System.out.println(inputLine); //получаю приветствие сервера "* OK IMAP4 ready"
//авторизация
key = "a1";
out.println(key + " LOGIN info@mirossa.ru passw");
out.flush(); //иначе висим(сервер жд�'т от нас)
System.out.println(get_data_imap(in, key)); // "a1 NO Invalid password" | "a1 OK ..."
// выбор конкретного ящика
key = "a2";
out.println(key + " EXAMINE INBOX");
out.flush();
System.out.println(get_data_imap(in, key));
//ищем непросмотренные письма после
key = "a3";
out.println(key + " SEARCH UNSEEN SINCE 07-Mar-2019");
out.flush();
System.out.println(get_data_imap(in, key));
//Получаем заголовочные поля сообщения
key = "a4";
out.println(key + " FETCH 5 ENVELOPE");
out.flush();
dataEnvelope = get_data_imap(in, key);
System.out.println(dataEnvelope);
i = dataEnvelope.indexOf("(");
if (i != -1 ){
y = dataEnvelope.indexOf(" ", i+1);
ENV = dataEnvelope.substring(i+1, y); //индекс y не входит
}
if (ENV.equals("ENVELOPE")){
//выбираем из ответа только структуру envelope
spaceBalans = 1;
i = y+1; //первая скобка
spaceF = y+2; //начало полезной части строки
while (spaceBalans != 0){
i = i+1;
ch = dataEnvelope.substring(i, i+1); //костыль; Kludge; duct tape; /*FIXME*/
if(ch.equals("(")){
spaceBalans = spaceBalans + 1;
}else if(ch.equals(")")){
spaceBalans = spaceBalans - 1;
}
}
str1 = dataEnvelope.substring(spaceF, i);
//парсинг заголовочных полей сообщения
ArrayEnvelope = ParsingEnvelope(str1);
System.out.println("Begin Envelope.");
PrintArrayEnvelope(ArrayEnvelope);
System.out.println("End Envelope.");
}else{
System.out.println("It is not Envelope.");
}
//получаем секцию TEXT сообщения
key = "a5";
out.println(key + " FETCH 5 BODY[TEXT]");
out.flush();
System.out.println(get_data_imap(in, key));
//закрываю сеанс
key = "a9";
out.println(" logout");
out.flush(); //иначе висим(сервер жд�'т от нас)
System.out.println(get_data_imap(in, key));
in.close();
out.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Пример вывода (1)
* OK IMAP4 ready
a1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE] Logged in
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS ()] Read-only mailbox.
* 5 EXISTS
* 0 RECENT
* OK [UNSEEN 3] First unseen.
* OK [UIDVALIDITY 1551718912] UIDs valid
* OK [UIDNEXT 12] Predicted next UID
* OK [HIGHESTMODSEQ 34] Highest
a2 OK [READ-ONLY] Examine completed (0.000 + 0.000 secs).
* SEARCH 3 4 5
a3 OK Search completed (0.001 + 0.000 secs).
* 5 FETCH (ENVELOPE ("Tue, 12 Mar 2019 02:07:43 +0300" "=?UTF-8?B?RndkOiDQn9GA0LjQstC10YI=?=" (("=?UTF-8?B?0J/RgNC10LTRgdGC0LDQstC70LXQvdC40LXQntGC0L/RgNCw0LLQuNGC0LXQu9GP?=" NIL "sender" "list.ru")) (("=?UTF-8?B?0J/RgNC10LTRgdGC0LDQstC70LXQvdC40LXQntGC0L/RgNCw0LLQuNGC0LXQu9GP?=" NIL "sender" "list.ru")) (("=?UTF-8?B?0J/RgNC10LTRgdGC0LDQstC70LXQvdC40LXQntGC0L/RgNCw0LLQuNGC0LXQu9GP?=" NIL "sender" "list.ru")) (("=?UTF-8?B?aW5mbw==?=" NIL "info" "mirossa.ru")) NIL NIL NIL "<1556665663.595311115@f405.i.mail.ru>"))
a4 OK Fetch completed (0.001 + 0.000 secs).
Begin Envelope.
Tue, 12 Mar 2019 02:07:43 +0300
Fwd: Привет
ПредставлениеОтправителя sender@list.ru
ПредставлениеОтправителя sender@list.ru
ПредставлениеОтправителя sender@list.ru
info info@mirossa.ru
@
@
<1556665663.595311115@f405.i.mail.ru>
End Envelope.
* 5 FETCH (BODY[TEXT] {1220}
----ALT--rtRIoqqxkWO9qFvO51RR8tBPOU4k7oXL1552345663
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
0J/RgNC40LLQtdGCLgrQn9GA0LjQstC10YIuCtCf0YDQuNCy0LXRgi4KCtChINGD0LLQsNC20LXQ
vdC40LXQvCwg0KTQmNCeLgoKCg==
----ALT--rtRIoqqxkWO9qFvO51RR8tBPOU4k7oXL1552345663
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
CjxIVE1MPjxCT0RZPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDE4cHg7Y29sb3I6IHJnYigzLCAx
NDcsIDE1NSk7YmFja2dyb3VuZC1jb2xvcjogcmdiKDI1NSwgMTU2LCAwKTsiPtCf0YDQuNCy0LXR
gi48L3NwYW4+PGJyPjxkaXYgY2xhc3M9ImpzLWhlbHBlciBqcy1yZWFkbXNnLW1zZyI+PGRpdj48
ZGl2IGlkPSJzdHlsZV8xNTUyMDk0NjM5MDAwMDAwMDcwOV9CT0RZIj48ZGl2IGNsYXNzPSJjbGFz
c18xNTUyMzYwNjcyIj48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigyNTEsIDQ0LCA0NCk7Ij7Qn9GA
0LjQstC10YIuPC9zcGFuPjxicj48c3BhbiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjogcmdiKDMs
IDE1NSwgMTI4KTsiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDM2cHg7Ij48L3NwYW4+0J/RgNC4
0LLQtdGCLjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDE4cHg7Ij48L3NwYW4+PC9zcGFuPjxicj4K
PC9kaXY+PC9kaXY+CiAgICAgICAgICAgIAogICAgICAgIAoJCQoJPC9kaXY+CgoJCjwvZGl2PgoK
Cgo8YnI+0KEg0YPQstCw0LbQtdC90LjQtdC8LCDQpNCY0J4uPGJyPjxicj48YnI+PC9CT0RZPjwv
SFRNTD4K
----ALT--rtRIoqqxkWO9qFvO51RR8tBPOU4k7oXL1552345663--
)
a5 OK Fetch completed (0.001 + 0.000 secs).
* BYE Logging out
* OK Logout completed.
Пример вывода (2)
* OK IMAP4 ready
a1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE] Logged in
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS ()] Read-only mailbox.
* 5 EXISTS
* 0 RECENT
* OK [UNSEEN 5] First unseen.
* OK [UIDVALIDITY 1551718912] UIDs valid
* OK [UIDNEXT 13] Predicted next UID
* OK [HIGHESTMODSEQ 37] Highest
a2 OK [READ-ONLY] Examine completed (0.000 + 0.000 secs).
* SEARCH 5
a3 OK Search completed (0.001 + 0.000 secs).
* 5 FETCH (ENVELOPE ("Tue, 12 Mar 2019 02:37:34 +0300" "=?UTF-8?Q?=D0=92=D0=BE=D0=BF=D1=80=D0=BE=D1=81?=" (("infoMirossa" NIL "info" "mirossa.ru")) (("infoMirossa" NIL "info" "mirossa.ru")) (("infoMirossa" NIL "info" "mirossa.ru")) (("infoMirossa" NIL "info" "mirossa.ru")) NIL NIL NIL ""))
a4 OK Fetch completed (0.001 + 0.000 secs).
Begin Envelope.
Tue, 12 Mar 2019 02:37:34 +0300
=D0=92=D0=BE=D0=BF=D1=80=D0=BE=D1=81
infoMirossa info@mirossa.ru
infoMirossa info@mirossa.ru
infoMirossa info@mirossa.ru
infoMirossa info@mirossa.ru
@
@
End Envelope.
* 5 FETCH (BODY[TEXT] {43}
По поводу вашего сайта
)
a5 OK Fetch completed (0.001 + 0.000 secs).
* BYE Logging out
* OK Logout completed.