Вспомогательные функции

Отправка сообщения с вариантом голосования

Microsoft Outlook позволяет пользователям создавать опросы при написании нового сообщения. Это делается включением вариантов голосования, таких как Да, Нет, Возможно и т.д. Класс FollowUpOptions, предоставляемый Aspose.Email, содержит свойство VotingButtons, которое позволяет установить или получить значение вариантов голосования. В этой статье приводится подробный пример создания MapiMessage с вариантами голосования для создания опроса и последующей отправки сообщения с помощью клиента Exchange Web Service (EWS).

Создание и отправка сообщения с вариантами голосования

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

String address = "firstname.lastname@aspose.com";

IEWSClient client = EWSClient.getEWSClient("https://outlook.office365.com/ews/exchange.asmx", "testUser", "pwd", "domain");
MailMessage message = createTestMessage(address);

// Set FollowUpOptions Buttons
FollowUpOptions options = new FollowUpOptions();
options.setVotingButtons("Yes;No;Maybe;Exactly!");

client.send(message, options);

Пример методов, использованных в примерах

Следующий фрагмент кода показывает, как использовать методы, применённые в приведённом выше примере.

private static MailMessage createTestMessage(String address) {
    MailMessage eml = new MailMessage(address, address, "Flagged message",
            "Make it nice and short, but descriptive. The description may appear in search engines' search results pages...");

    return eml;
}

Создание RE и FW сообщений из MSG‑файлов

IEWSClient позволяет разработчикам создавать сообщения RE (Reply/Reply All) и FW (Forward) из исходного сообщения. Исходное сообщение определяется путем выбора определённого ExchangeMessageInfo из ExchangeMessageInfoCollection получено через IEWSClient.listMessages(). Другим аргументом является фактический MailMessage для отправки как RE или FW сообщения. Следующий фрагмент кода показывает, как создать тестовую учётную запись, использовать её для отправки сообщения, а затем продемонстрировать функции Reply и Forward по отношению к этому сообщению. Чтобы выполнить задачу:

  1. Инициализируйте объект IEWSClient, указав действительные учётные данные.
  2. Отправьте несколько образцов сообщений.
  3. Вызовите функции IEWSClient.reply(), IEWSClient.replyAll() и IEWSClient.forward() для отправки сообщений.
IEWSClient client = EWSClient.getEWSClient(mailboxUri, credential);

try {
    MailMessage message = new MailMessage("user@domain.com", "user@domain.com", "TestMailRefw - " + UUID.randomUUID().toString(),
            "TestMailRefw Implement ability to create RE and FW messages from source MSG file");

    client.send(message);

    ExchangeMessageInfoCollection messageInfoCol = client.listMessages(client.getMailboxInfo().getInboxUri());
    if (messageInfoCol.size() == 1)
        System.out.println("1 message in Inbox");
    else
        System.out.println("Error! No message in Inbox");

    MailMessage message1 = new MailMessage("user@domain.com", "user@domain.com", "TestMailRefw - " + UUID.randomUUID().toString(),
            "TestMailRefw Implement ability to create RE and FW messages from source MSG file");

    client.send(message1);
    messageInfoCol = client.listMessages(client.getMailboxInfo().getInboxUri());

    if (messageInfoCol.size() == 2)
        System.out.println("2 messages in Inbox");
    else
        System.out.println("Error! No new message in Inbox");

    MailMessage message2 = new MailMessage("user@domain.com", "user@domain.com", "TestMailRefw - " + UUID.randomUUID().toString(),
            "TestMailRefw Implement ability to create RE and FW messages from source MSG file");
    message2.getAttachments().addItem(Attachment.createAttachmentFromString("Test attachment 1", "Attachment Name 1"));
    message2.getAttachments().addItem(Attachment.createAttachmentFromString("Test attachment 2", "Attachment Name 2"));

    // Reply, Replay All and forward Message
    client.reply(message2, messageInfoCol.get_Item(0));
    client.replyAll(message2, messageInfoCol.get_Item(0));
    client.forward(message2, messageInfoCol.get_Item(0));
} catch (java.lang.RuntimeException ex) {
    System.out.println("Error in program" + ex.getMessage());
}

Поддержка OAuth для EWS с Office 365

Aspose.Email API предоставляет поддержку Exchange Web Service (EWS) с Office 365. API‑ EWSClient интерфейс предоставляет перегруженный метод, который предоставляет OAuthNetworkCredential в качестве входных данных для доступа к учетной записи Exchange через OAuth. Пользователь должен указать параметры Authority, Client Id, Client App Uri и Resource, чтобы это работало. Следующий фрагмент кода демонстрирует поддержку OAuth для EWS с Office 365.

// token provider
/*ITokenProvider provider = new ITokenProvider() {

    @Override
    public void dispose() {
    }

    @Override
    public OAuthToken getAccessToken(boolean ignoreExistingToken) {
        return null;
    }

    @Override
    public OAuthToken getAccessToken() {
        return null;
    }
};

NetworkCredential credentials = new OAuthNetworkCredential(provider);*/

// accessToken
NetworkCredential credentials = new OAuthNetworkCredential("accessToken");

IEWSClient client = EWSClient.getEWSClient("https://outlook.office365.com/ews/exchange.asmx", credentials);
client.listMessages();

Поддержка логирования в клиентах Exchange

Aspose.Email API предоставляет возможность логирования клиента Exchange Web Service.

Логирование для клиента EWS

client.setLogFileName("logs/ews");
// OR
EWSClient.setCommonLogFileName("logs/ews");

Добавление заголовков в запросы EWS

Aspose.Email API позволяет добавлять заголовки к запросам Exchange. Это может использоваться для добавления различных заголовков к запросам EWS с разными целями. Например, можно добавить заголовок X-AnchorMailbox, который используется для управления проблемами ограничения (throttling) на сервере Exchange. Метод addHeader интерфейса IEWSClient используется для добавления заголовков к запросам EWS, как показано в следующем фрагменте кода.

final IEWSClient client = EWSClient.getEWSClient("exchange.domain.com/ews/Exchange.asmx", "username", "password", "");
try {
    client.addHeader("X-AnchorMailbox", "username@domain.com");
    ExchangeMessageInfoCollection messageInfoCol = client.listMessages(client.getMailboxInfo().getInboxUri());
} finally {
    client.dispose();
}

Возврат ID клиентского запроса в заголовке

Этот return-client-request-id заголовок отправляется в запросе и используется сервером для определения, следует ли client-request-id заголовок, указанный клиентом, должен быть возвращён в ответе сервера. Для этой операции используются следующие методы:

try (IEWSClient client = createEWSClient())
{
    // Client will create random id and pass it to the server.
    // The server should include this id in request-id header of all responses.
    client.setReturnClientRequestId(true);
    
    client.setLogFileName("ews.log");
    client.getMailboxInfo();
}

Работа с Unified Messaging

Aspose.Email может получать информацию о едином обмене сообщениями (Unified Messaging) с сервера Exchange Server 2010. На данный момент поддерживаются такие функции единого обмена, как получение конфигурационной информации, инициация исходящего звонка, получение информации о звонке по его ID и разъединение звонка по ID. Следующий пример кода показывает, как получить конфигурационную информацию единого обмена сообщениями с Microsoft Exchange Server 2010.

IEWSClient client = EWSClient.getEWSClient(mailboxUri, credential);
UnifiedMessagingConfiguration umConf = client.getUMConfiguration();

Получение подсказок по письму

Microsoft Exchange Server добавил несколько новых функций в версиях Exchange Server 2010 и 2013. Одна из них позволяет пользователям получать подсказки по письму при его составлении. Эти подсказки полезны, так как предоставляют информацию еще до отправки письма. Например, если адрес получателя введен неверно, появляется подсказка о недействительности адреса. Подсказки также позволяют увидеть ответы "вне офиса" перед отправкой письма: Exchange Server (2010 и 2013) отправляет подсказку во время написания письма, если один или несколько получателей настроили такие ответы. Для всех функций, продемонстрированных в этой статье, требуется Microsoft Exchange Server 2010 Service Pack 1. Следующий фрагмент кода показывает, как использовать EWSClient класс, использующий Exchange Web Services, доступные в Microsoft Exchange Server 2007 и более поздних версиях.

// Create instance of EWSClient class by giving credentials
IEWSClient client = EWSClient.getEWSClient("https://outlook.office365.com/ews/exchange.asmx", "testUser", "pwd", "domain");
System.out.println("Connected to Exchange server...");
// Provide mail tips options
MailAddressCollection addrColl = new MailAddressCollection();
addrColl.addMailAddress(new MailAddress("test.exchange@ex2010.local", true));
addrColl.addMailAddress(new MailAddress("invalid.recipient@ex2010.local", true));
GetMailTipsOptions options = new GetMailTipsOptions(MailAddress.to_MailAddress("administrator@ex2010.local"), addrColl, MailTipsType.All);

// Get Mail Tips
MailTips[] tips = client.getMailTips(options);

// Display information about each Mail Tip
for (MailTips tip : tips) {
    // Display Out of office message, if present
    if (tip.getOutOfOffice() != null) {
        System.out.println("Out of office: " + tip.getOutOfOffice().getReplyBody().getMessage());
    }

    // Display the invalid email address in recipient, if present
    if (tip.getInvalidRecipient() == true) {
        System.out.println("The recipient address is invalid: " + tip.getRecipientAddress());
    }
}

Имитация Exchange

Имитация в Exchange позволяет пользователю выдавать себя за другую учетную запись и выполнять задачи, используя права имитируемой учетной записи, а не свои собственные. В то время как делегирование позволяет пользователям действовать от имени других, имитация позволяет им действовать как другие пользователи. Aspose.Email поддерживает имитацию Exchange. EWSClient класс предоставляет методы ImpersonateUser и ResetImpersonation для облегчения использования этой функции.

Для выполнения этой задачи:

  1. Инициализировать ExchangeWebServiceClient для пользователя 1.
  2. Инициализировать ExchangeWebServiceClient для пользователя 2.
  3. Добавить тестовые сообщения к учетным записям.
  4. Включить имитацию.
  5. Сбросить имитацию.

Следующий фрагмент кода показывает, как использовать EWSClient класс для реализации функции имитации (Impersonation).

// Create instance's of EWSClient class by giving credentials
IEWSClient client1 = EWSClient.getEWSClient("https://outlook.office365.com/ews/exchange.asmx", "testUser1", "pwd", "domain");
IEWSClient client2 = EWSClient.getEWSClient("https://outlook.office365.com/ews/exchange.asmx", "testUser2", "pwd", "domain");
{
    String folder = "Drafts";
    try {
        for (ExchangeMessageInfo messageInfo : (Iterable<ExchangeMessageInfo>) client1.listMessages(folder))
            client1.deleteItem(messageInfo.getUniqueUri(), DeletionOptions.getDeletePermanently());
        String subj1 = "NETWORKNET_33354 User User1";
        client1.appendMessage(folder, new MailMessage("User1@exchange.conholdate.local", "To@aspsoe.com", subj1, ""));

        for (ExchangeMessageInfo messageInfo : (Iterable<ExchangeMessageInfo>) client2.listMessages(folder))
            client2.deleteItem(messageInfo.getUniqueUri(), DeletionOptions.getDeletePermanently());
        String subj2 = "NETWORKNET_33354 User User2";
        client2.appendMessage(folder, new MailMessage("User2@exchange.conholdate.local", "To@aspose.com", subj2, ""));

        ExchangeMessageInfoCollection messInfoColl = client1.listMessages(folder);
        // Assert.AreEqual(1, messInfoColl.Count);
        // Assert.AreEqual(subj1, messInfoColl[0].Subject);

        client1.impersonateUser(ItemChoice.PrimarySmtpAddress, "User2@exchange.conholdate.local");
        ExchangeMessageInfoCollection messInfoColl1 = client1.listMessages(folder);
        // Assert.AreEqual(1, messInfoColl1.Count);
        // Assert.AreEqual(subj2, messInfoColl1[0].Subject);

        client1.resetImpersonation();
        ExchangeMessageInfoCollection messInfoColl2 = client1.listMessages(folder);
        // Assert.AreEqual(1, messInfoColl2.Count);
        // Assert.AreEqual(subj1, messInfoColl2[0].Subject);
    } finally {
        try {
            for (ExchangeMessageInfo messageInfo : (Iterable<ExchangeMessageInfo>) client1.listMessages(folder))
                client1.deleteItem(messageInfo.getUniqueUri(), DeletionOptions.getDeletePermanently());
            for (ExchangeMessageInfo messageInfo : (Iterable<ExchangeMessageInfo>) client2.listMessages(folder))
                client2.deleteItem(messageInfo.getUniqueUri(), DeletionOptions.getDeletePermanently());
        } catch (java.lang.RuntimeException e) {
        }
    }
}

Функция Auto Discover через EWS

Aspose.Email API позволяет узнать настройки сервера Exchange, используя клиент EWS. 

AutodiscoverService svc = new AutodiscoverService();
svc.setCredentials(new NetworkCredential(email, password));

IGenericDictionary</* UserSettingName */Integer, Object> userSettings = svc.getUserSettings(email, UserSettingName.ExternalEwsUrl).getSettings();
String ewsUrl = (String) userSettings.get_Item(UserSettingName.ExternalEwsUrl);
System.out.println("Auto discovered EWS Url: " + ewsUrl);

Прервать восстановление PST на сервер Exchange

Aspose.Email API позволяет восстановить файл PST на сервер Exchange. Однако, если операция занимает длительное время из‑за большого размера PST‑файла, может потребоваться указать критерий для прерывания операции. Это можно выполнить с помощью API, как показано в следующем примере кода.

final IEWSClient client = EWSClient.getEWSClient("https://exchange.office365.com/ews/exchange.asmx", "username", "password");
try {
    final long startTime = System.currentTimeMillis();
    final AtomicInteger processedItems = new AtomicInteger(0);
    final long S15 = 15 * 1000;

    BeforeItemCallback callback = new BeforeItemCallback() {
        public void invoke(ItemCallbackArgs item) {
            if (System.currentTimeMillis() - startTime > S15) {
                throw new AbortRestoreException();
            }

            processedItems.incrementAndGet();
        }
    };

    try {
        // create a test pst and add some test messages to it
        PersonalStorage pst = PersonalStorage.create(new ByteArrayOutputStream(), FileFormatVersion.Unicode);
        FolderInfo folder = pst.getRootFolder().addSubFolder("My test folder");
        for (int i = 0; i < 20; i++) {
            MapiMessage message = new MapiMessage("from@gmail.com", "to@gmail.com", "subj", "body");
            folder.addMessage(message);
        }
        RestoreSettings rs = new RestoreSettings();
        rs.setBeforeItemCallback(callback);

        // now restore the PST with callback
        client.restore(pst, rs);
        System.out.println("Success!");
    } catch (AbortRestoreException e) {
        System.out.println("Timeout! " + processedItems.get());
    }
} finally {
    client.dispose();
}