问题
I want to get the mail subject and body of only unread mails of my inbox.
- I want to read one unread mail at a time and mark it as read afterwards.
- I need the subject, from address and mail body.
The below code shows gives me the mail IDs of all unread mails.
require_once ('../mail3/php-ews-master/ExchangeWebServices.php');
require_once ('../mail3/php-ews-master/EWS_Exception.php');
require_once ('../mail3/php-ews-master/EWSType.php');
require_once ('../mail3/php-ews-master/NTLMSoapClient.php');
function __autoload($class_name)
{
// Start from the base path and determine the location from the class name,
$base_path = '../mail3/php-ews-master';
$include_file = $base_path . '/' . str_replace('_', '/', $class_name) . '.php';
return (file_exists($include_file) ? require_once $include_file : false);
}
$ews = new ExchangeWebServices("servername", "username", "password",ExchangeWebServices::VERSION_2010);
$request = new EWSType_FindItemType();
$itemProperties = new EWSType_ItemResponseShapeType();
$itemProperties->BaseShape = EWSType_DefaultShapeNamesType::ID_ONLY;
$itemProperties->BodyType = EWSType_BodyTypeResponseType::BEST;
$request->ItemShape = $itemProperties;
$fieldType = new EWSType_PathToUnindexedFieldType();
$fieldType->FieldURI = 'message:IsRead';
$constant = new EWSType_FieldURIOrConstantType();
$constant->Constant = new EWSType_ConstantValueType();
$constant->Constant->Value = "0";
$IsEqTo = new EWSType_IsEqualToType();
$IsEqTo->FieldURIOrConstant = $constant;
$IsEqTo->Path = $fieldType;
$request->Restriction = new EWSType_RestrictionType();
$request->Restriction->IsEqualTo = new EWSType_IsEqualToType();
$request->Restriction->IsEqualTo->FieldURI = $fieldType;
$request->Restriction->IsEqualTo->FieldURIOrConstant = $constant;
$request->IndexedPageItemView = new EWSType_IndexedPageViewType();
$request->IndexedPageItemView->BasePoint = 'Beginning';
$request->IndexedPageItemView->Offset = 0;
$request->ParentFolderIds = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
$request->ParentFolderIds->DistinguishedFolderId = new EWSType_DistinguishedFolderIdType();
$request->ParentFolderIds->DistinguishedFolderId->Id = EWSType_DistinguishedFolderIdNameType::INBOX;
$request->Traversal = EWSType_ItemQueryTraversalType::SHALLOW;
$result = new EWSType_FindItemResponseMessageType();
$result = $ews->FindItem($request);
echo '<pre>';
print_r($result);
After getting it how can I mark the mail as read?
stdClass Object
(
[ResponseMessages] => stdClass Object
(
[FindItemResponseMessage] => stdClass Object
(
[ResponseCode] => NoError
[ResponseClass] => Success
[RootFolder] => stdClass Object
(
[Items] => stdClass Object
(
[Message] => Array
(
[0] => stdClass Object
(
[ItemId] => stdClass Object
(
[Id] => AAMkADM1NjQ4ZjU0LWI3OWYtNGZiMC1iYTgzLTU4N2E1MGMwYWNkMQBGAAAAAADANtAZyWYTTKe/pt+BZ+SXBwD+fIgCJQITS5O3LAEwY6+oAAAANbjBAAB51OTN2pqDQbTnOkGjBC0FAAGN2YkTAAA=
[ChangeKey] => CQAAABYAAAD+fIgCJQITS5O3LAEwY6+oAAC4WS4O
)
)
[1] => stdClass Object
(
[ItemId] => stdClass Object
(
[Id] => AAMkADM1NjQ4ZjU0LWI3OWYtNGZiMC1iYTgzLTU4N2E1MGMwYWNkMQBGAAAAAADANtAZyWYTTKe/pt+BZ+SXBwD+fIgCJQITS5O3LAEwY6+oAAAANbjBAAB51OTN2pqDQbTnOkGjBC0FAAGN2YkSAAA=
[ChangeKey] => CQAAABYAAAD+fIgCJQITS5O3LAEwY6+oAAC4WS35
)
)
)
)
[IndexedPagingOffset] => 2
[IncludesLastItemInRange] => 1
[TotalItemsInView] => 2
)
)
)
)
回答1:
I see you're using the jamesiarmes/php-ews
version of php-ews
, so I'll try to answer for that. I might be a little bit off, since I don't use that version and will first encourage you to upgrade to a fork I maintain and update, because it's easier to use, you'll get more support, it's PSR-2 and 4 compatible and is still maintained. It's called garethp/php-ews. I'll give my answer for that first, as it's short and easy, then move to the code base you use
Solving with garethp/php-ews
Essentially there's three parts to it. Fetching, reading and marking as read. The first is to get only unread emails from the server, which is done as such
require_once "vendor/autoload.php";
use jamesiarmes\PEWS\API\Type;
use jamesiarmes\PEWS\Mail\MailAPI;
$api = MailAPI::withUsernameAndPassword('server', 'username', 'password');
$unreadMail = $api->getUnreadMailItems();
The second part of the solution is to read the item. EWS doesn't return the body of a mail item when you fetch a list of them. It considers the body to be a second class property, so you need to specifically ask for the information of that one mail item to get the body. So, in order to do that, we do the following
$item = $unreadMail[0];
$item = $api->getItem($item->getItemId());
$subject = $item->getSubject();
$sender = $item->getSender()->getMailbox()->getEmailAddress();
$body = (string) $item->getBody();
And the last part is to mark an item as read, which is done as such.
$api->markMailAsRead($item->getItemId());
The mail item should now show up as read. So, if we put them all together, it should come something like
require_once "vendor/autoload.php";
use jamesiarmes\PEWS\API\Type;
use jamesiarmes\PEWS\Mail\MailAPI;
$api = MailAPI::withUsernameAndPassword('server', 'username', 'password');
$unreadMail = $api->getUnreadMailItems();
foreach ($unreadMail as $item) {
$item = $api->getItem($item->getItemId());
$subject = $item->getSubject();
$sender = $item->getSender()->getMailbox()->getEmailAddress();
$body = (string) $item->getBody();
$api->markMailAsRead($item->getItemId());
}
Solving with jamesiarmes/php-ews
This is split up in to three steps (see above): Fetching, reading and marking as read. You know how to fetch, obviously. So we'll skip to the other two parts in one.
$result = $ews->FindItem($request);
foreach ($result->ResponseMessages->FindItemResponseMessage->RootFolder->Items->Message as $item) {
$request = new EWSType_GetItemType();
$request->ItemShape = new EWSType_ItemResponseShapeType();
$request->ItemShape->BaseShape = EWSType_DefaultShapeNamesType::ALL_PROPERTIES;
$request->ItemIds = new EWSType_NonEmptyArrayOfBaseItemIdsType();
$request->ItemIds->ItemId = new EWSType_ItemIdType();
$request->ItemIds->ItemId->Id = $item->ItemId->Id;
$response = $ews->GetItem($request);
//You may have to do a var_dump on the $response here. I'm only guessing that this is how you locate the message item, since I don't use this code base any more.
$item = $response->ResponseMessages->GetItemResponseMessage->Items->Message;
//You should do a var_dump on the $item to see how to get the body, subject and sender here. I'm not 100% sure how to do it on this one.
//Mark the item as read (hopefully)
$request = new EWSType_UpdateItemType();
$request->MessageDisposition = 'SaveOnly';
$request->ConflictResolution = 'AlwaysOverwrite';
$request->ItemChanges = [];
$change = new EWSType_ItemChangeType();
$change = new EWSType_ItemChangeType();
$change->ItemId = new EWSType_ItemIdType();
$change->ItemId->Id = $item->ItemId->Id;
$change->ItemId->ChangeKey = $item->ItemId->ChangeKey;
$change->Updates = new EWSType_NonEmptyArrayOfItemChangeDescriptionsType();
$change->Updates->SetItemField = array(); // Array of fields to be update
// Update Firstname (simple property)
$field = new EWSType_SetItemFieldType();
$field->FieldURI->FieldURI = 'message:IsRead';
$field->Message = new EWSType_MessageItemType();
$field->Message->IsRead = true;
$change->Updates->SetItemField[] = $field;
// Set all changes
$request->ItemChanges[] = $change;
// Send request
$response = $ews->UpdateItem($request);
echo '<pre>'.print_r($response, true).'</pre>';
}
Without actually testing it, that should be roughly how you would do it. You may have to play around with that to make it work. You can see why I suggest using my fork over this.
来源:https://stackoverflow.com/questions/35401926/how-to-to-print-mail-body-and-subject-from-unread-answer