I have been able to successfully retrieve the unread emails from an Exchange 2010 inbox using php-ews API. However after I have fetched the emails, I want to set the IsRead property of the email to true, so that these messages do not appear the next time I fetch emails.
Anyone done this before ?
EDIT :
This is how I am trying to set the IsRead flag :
$message_id = ''; //id of message
$change_key = ''; //change key
$response = $ews->GetItem($request);
//print_r($response);exit;
if( $response->ResponseMessages->GetItemResponseMessage->ResponseCode == 'NoError' &&
$response->ResponseMessages->GetItemResponseMessage->ResponseClass == 'Success' ) {
$a = array();
$message = $response->ResponseMessages->GetItemResponseMessage->Items->Message;
$a['message_body'] = $message->Body->_;
$a['sender'] = $message->From->Mailbox->EmailAddress;
$a['subject'] = $message->ConversationTopic;
$data[] = $a;
//process the message data.
$messageType = new EWSType_MessageType();
$messageType->IsRead = true;
$path = new EWSType_PathToUnindexedFieldType();
$path->FieldURI = 'message:IsRead';
$setField = new EWSType_SetItemFieldType();
$setField->Message = $messageType;
$setField->FieldURI = $path;
$u = new EWSType_ItemChangeType();
$u->Updates = new EWSType_NonEmptyArrayOfItemChangeDescriptionsType();
$u->Updates->SetItemField = $setField;
$u->ItemId = new EWSType_ItemIdType();
$u->ItemId->Id = $message_id;
$u->ItemId->ChangeKey = $change_key;
$updatedItems = new EWSType_NonEmptyArrayOfItemChangesType();
$updatedItems->ItemChange = $u;
$updateMessenger = new EWSType_UpdateItemType();
$updateMessenger->ItemChanges = $updatedItems;
$updateMessenger->MessageDisposition = 'SaveOnly';
$updateMessenger->ConflictResolution = 'AutoResolve';
try {
$update_response = $ews->UpdateItem($updateMessenger);
}catch (Exception $e){
echo $e->getMessage();
}
}
When I run the file I get the following error :
An internal server error occurred. The operation failed.
After debugging for some time, I have concluded that the error happens at the curl_exec function in NTLMSoapClient.php file.
I dont know where to go on from here. Please help.
I've faced a similar issue when updating a calendar event and setting the IsAllDayEvent flag. This is the code that worked for me:
$ews = new ExchangeWebServices(...);
$request = new EWSType_UpdateItemType();
$request->ConflictResolution = 'AlwaysOverwrite';
$request->ItemChanges = array();
$change = new EWSType_ItemChangeType();
$change->ItemId = new EWSType_ItemIdType();
$change->ItemId->Id = $id;
$change->ItemId->ChangeKey = $changeKey;
$field = new EWSType_SetItemFieldType();
$field->FieldURI = new EWSType_PathToUnindexedFieldType();
$field->FieldURI->FieldURI = "calendar:IsAllDayEvent";
$field->CalendarItem = new EWSType_CalendarItemType();
$field->CalendarItem->IsAllDayEvent = true;
$change->Updates->SetItemField[] = $field;
$request->ItemChanges[] = $change;
$response = $ews->UpdateItem($request);
The biggest difference I see here is that you do $u->Updates->SetItemField = $setField;, whereas my code uses $u->Updates->SetItemField[] = $setField;.
I hope this helps.
Edit: You might have already seen this, but I based my code on the one from the php-ews wiki.
I tried everything including PathToExtendedFieldType and it doesn't work at the end code below worked for me
$ews = new ExchangeWebServices('red', 'red', 'red',ExchangeWebServices::VERSION_2007_SP1);
$request = new EWSType_UpdateItemType();
$request->SendMeetingInvitationsOrCancellations = 'SendToNone';
$request->MessageDisposition = 'SaveOnly';
$request->ConflictResolution = 'AlwaysOverwrite';
$request->ItemChanges = array();
// Build out item change request.
$change = new EWSType_ItemChangeType();
$change->ItemId = new EWSType_ItemIdType();
$change->ItemId->Id = $contact_id;
$change->ItemId->ChangeKey = $contact_change_key;
#$change->Updates = new EWSType_NonEmptyArrayOfItemChangeDescriptionsType();
#$change->Updates->SetItemField = array();
// Build the set item field object and set the item on it.
$field = new EWSType_SetItemFieldType();
$field->FieldURI = new EWSType_PathToUnindexedFieldType();
$field->FieldURI->FieldURI = "message:IsRead";
$field->Message = new EWSType_MessageType();
$field->Message->IsRead = true;
$change->Updates->SetItemField[] = $field;
$request->ItemChanges[] = $change;
$response = $ews->UpdateItem($request);
var_dump($response);
Well, i dont know how it is in php, but in C# there is another field, that must be set: IsReadSpecified = true.
email.IsRead = true;
email.IsReadSpecified = true;
Related
i want To post an event directly to another user's calendar with jamesiarmes/php-ews but in example i have find only how to make it with invitation.
I have admin account so i can write in athers user's post calendar directly.
i don't understant a lot because i'm new in ews so thx for any help.
// Replace this with your desired start/end times and guests.
$start = new DateTime('tomorrow 4:00pm');
$end = new DateTime('tomorrow 5:00pm');
$guests = array(
array(
'name' => 'Homer Simpson',
'email' => 'hsimpson#example.com',
),
array(
'name' => 'Marge Simpson',
'email' => 'msimpson#example.com',
),
);
// Set connection information.
$host = '';
$username = '';
$password = '';
$version = Client::VERSION_2016;
$client = new Client($host, $username, $password, $version);
// Build the request,
$request = new CreateItemType();
$request->SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType::SEND_ONLY_TO_ALL;
$request->Items = new NonEmptyArrayOfAllItemsType();
// Build the event to be added.
$event = new CalendarItemType();
$event->RequiredAttendees = new NonEmptyArrayOfAttendeesType();
$event->Start = $start->format('c');
$event->End = $end->format('c');
$event->Subject = 'EWS Test Event';
// Set the event body.
$event->Body = new BodyType();
$event->Body->_ = 'This is the event body';
$event->Body->BodyType = BodyTypeType::TEXT;
// Iterate over the guests, adding each as an attendee to the request.
foreach ($guests as $guest) {
$attendee = new AttendeeType();
$attendee->Mailbox = new EmailAddressType();
$attendee->Mailbox->EmailAddress = $guest['email'];
$attendee->Mailbox->Name = $guest['name'];
$attendee->Mailbox->RoutingType = RoutingType::SMTP;
$event->RequiredAttendees->Attendee[] = $attendee;
}
// Add the event to the request. You could add multiple events to create more
// than one in a single request.
$request->Items->CalendarItem[] = $event;
$response = $client->CreateItem($request);
// Iterate over the results, printing any error messages or event ids.
$response_messages = $response->ResponseMessages->CreateItemResponseMessage;
foreach ($response_messages as $response_message) {
// Make sure the request succeeded.
if ($response_message->ResponseClass != ResponseClassType::SUCCESS) {
$code = $response_message->ResponseCode;
$message = $response_message->MessageText;
fwrite(STDERR, "Event failed to create with \"$code: $message\"\n");
continue;
}
// Iterate over the created events, printing the id for each.
foreach ($response_message->Items->CalendarItem as $item) {
$id = $item->ItemId->Id;
fwrite(STDOUT, "Created event $id\n");
}
}
You define the attendees but miss the account where you want to create the event in:add this code before the $response
...
$request->Items->CalendarItem[] = $event;
//following lines are missing
$lsEmail = 'some#email.de';
$request->SavedItemFolderId = new TargetFolderIdType();
$request->SavedItemFolderId->DistinguishedFolderId = new DistinguishedFolderIdType();
$request->SavedItemFolderId->DistinguishedFolderId->Id = self::DISTINGUISHED_FOLDER_ID;
$request->SavedItemFolderId->DistinguishedFolderId->Mailbox = new EmailAddressType();
$request->SavedItemFolderId->DistinguishedFolderId->Mailbox->EmailAddress = $lsEmail;
// here your code continues
$response = $client->CreateItem($request);
...
When sending data to the SomeMethod() method, the 1 excess parameter returns as an error.
My Code:
$client = new SoapClient('site_url/?wsdl');
$client->soap_defencoding = 'UTF-8';
$loginparam = array('userName'=>'name','password'=>'pass','trace' => 1, 'exceptions' => 0);
$session = $client->OturumAc($loginparam);
$SoapIcHeader = new SoapHeader("http://sanayi.gov.tr","TokenId",$session->OturumAcResult);
$client->__setSoapHeaders($SoapIcHeader);
$OturumUzat = $client->OturumDogrulaVeUzat($session ->OturumAcResult);
$param["BosAgirligi"] = "20";
$param["CalismaBasinci"] = "5";
$param["DoluAgirligi"] = "1";
$param["SonMuayeneTarihi"] = "2017-08-01 10:19:04";
$param["SonMuayeneYapanFirmaMersisNo"] = "123456789";
$param["SuKapasitesi"] = "1";
$param["TestBasinci"] = "10";
$param["DolumBasinci"] = "15";
$param["EtKalinligi"] = "3";
$param["ImalatTarihi"] = "2017-08-01 10:19:04";
$param["SeriNo"] = "123";
$param["TescilEdenTesisId"] = "31fd684c-f97d-48c1-a7fb-60f30f536d8d";
$param["UreticiId"] = "31fd684c-f97d-48c1-a7fb-60f30f536d8d";
// $param["UygunlukIsareti"] = "1";
$date = date('d/m/Y');
$id ="2ad9a9a9-adb9-4fb8-8fae-01e84aa72343";
try
{
$sonuc = $client->TupTescil($id,$date,$param);
print_r($sonuc);
}
catch (Exception $e)
{
echo "Error ! ";
echo $e -> getMessage ();
}
Return Error
Error ! The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'TupTescil'. End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope/' expected. Found element 'param1' from namespace ''. Line 2, position 281.
This example works with C#
Guid tupKimligi = new Guid("07FAF194-4E80-4359-95D9-011CA1F5A1D4");
DateTime islemSaati = DateTime.Today;
TupTescilBilgisi tescilBilgileri = new TupTescilBilgisi()
{
BosAgirligi = 1,
CalismaBasinci = 1,
DoluAgirligi = 1,
SonMuayeneTarihi = DateTime.Today,
SonMuayeneYapanFirmaMersisNo = "123456789",
SuKapasitesi = 1,
TestBasinci = 1,
DolumBasinci = 1,
EtKalinligi = 1,
ImalatTarihi = DateTime.Today,
SeriNo = "123",
TescilEdenTesisId = tesisId,
UreticiId = ureticiId,
UygunlukIsareti = TupUygunlukIsareti.Pi
};
Tup tescilSonuc = tsc.TupTescil(tupKimligi, DateTime.Today, tescilBilgileri);
You can also look at the wsdl structure here
enter link description here
Thanks for your help
Google added a new way to add sitelink extensions.
https://developers.google.com/adwords/api/docs/guides/extension-settings#add_ad_extensions
I added a bunch of them, but how do you delete them? I had 3 sitelinks on each campaign. I was able to remove a sitelink from the campaigns, but it removed all sitelinks from the campaigns. They are still in the + Extension list, but not associated with any campaigns.
function deleteSitelinks($sitelinks) {
$user = $this->getUser();
$campaignExtensionSettingService = $user->GetService('CampaignExtensionSettingService', ADWORDS_VERSION);
// first remove the sitelinks from the campaigns
$operations = array();
foreach ($sitelinks as $sitelink) {
$sfi = new SitelinkFeedItem();
$sfi->feedItemId = $sitelink->google_feed_item_id;
$campaignExtensionSetting = new CampaignExtensionSetting();
$campaignExtensionSetting->campaignId = $sitelink->campaign->google_id;
$campaignExtensionSetting->extensionType = 'SITELINK';
$extensionSetting = new ExtensionSetting();
$extensionSetting->extensions = array($sfi);
$campaignExtensionSetting->extensionSetting = $extensionSetting;
$operation = new CampaignExtensionSettingOperation();
$operation->operator = 'REMOVE';
$operation->operand = $campaignExtensionSetting;
$operations[] = $operation;
}
$result = $campaignExtensionSettingService->mutate($operations);
// now remove the sitelinks themselves
$feedItemService = $user->GetService('FeedItemService', ADWORDS_VERSION);
$operations = array();
foreach ($sitelinks as $sitelink) {
$sfi = new SitelinkFeedItem();
$sfi->feedId = $sitelink->google_feed_id;
$sfi->feedItemId = $sitelink->google_feed_item_id;
$operation = new FeedItemOperation();
$operation->operator = 'REMOVE';
$operation->operand = $sfi;
$operations[] = $operation;
}
$result = $feedItemService->mutate($operations);
return $result->value;
}
Ok I 'fixed' it by re-adding all the sitelinks that belong to that campaign immediately after deleting the target sitelink. I swear, this is the most retarded part of this API.
...
$result = $campaignExtensionSettingService->mutate($operations);
// now re-add the other sitelinks. the google API is removing/disassociating ALL sitelinks for whatever reason
$operations = array();
foreach ($sitelinks as $sitelink) {
$campaignSitelinks = array();
$siblings = Sitelink::find()->where(['campaign_id' => $sitelink->campaign_id])->andWhere(['not', ['id' => $sitelink->id]])->all();
foreach ($siblings as $sibling) {
$sfi = new SitelinkFeedItem();
$sfi->feedItemId = $sibling->google_feed_item_id;
$campaignSitelinks[] = $sfi;
}
$campaignExtensionSetting = new CampaignExtensionSetting();
$campaignExtensionSetting->campaignId = $sitelink->campaign->google_id;
$campaignExtensionSetting->extensionType = 'SITELINK';
$campaignExtensionSetting->extensionSetting = new ExtensionSetting();
$campaignExtensionSetting->extensionSetting->extensions = $campaignSitelinks;
// Create operation.
$operation = new CampaignExtensionSettingOperation();
$operation->operator = 'SET';
$operation->operand = $campaignExtensionSetting;
$operations[] = $operation;
}
$result = $campaignExtensionSettingService->mutate($operations);
// now remove all the sitelinks themselves
$feedItemService = $user->GetService('FeedItemService', ADWORDS_VERSION);
...
I'm using php-ews to read through a mailbox which has over 1000 on Exchange 2010, I have a function for listing all the emails with the use of EWSType_FindItemType to grab all of the ID keys and store them into an array which I have then used a foreach loop of that array to call another function to grab that email message contents such as body and from email addresses.
I have tested this on a much smaller mailbox and it works perfectly fine with two different tests, one on the same Exchange and one using Exchange 2013 on microsoft 365.
But I keep getting this error when I reach about 300 emails into the array of keys from the last call:
SoapFault exception: [Client] looks like we got no XML document in E:\Development\ExchangeInt\php-ews\ExchangeWebServices.php:17
Stack trace:
#0 E:\Development\ExchangeInt\php-ews\ExchangeWebServices.php(17): SoapClient->__call('GetItem', Array)
#1 E:\Development\ExchangeInt\php-ews\ExchangeWebServices.php(17): NTLMSoapClient_Exchange->GetItem(Object(EWSType_GetItemType))
#2 E:\Development\ExchangeInt\php-ews\ExchangeWebServices.php(694): ExchangeWebServices->__doRequest(Object(EWSType_GetItemType))
#3 E:\Development\ExchangeInt\mail.php(405): ExchangeWebServices->GetItem(Object(EWSType_GetItemType))
#4 E:\Development\ExchangeInt\mail.php(341): Message(Object(Folder), Object(User), 'AAMkAGEzOGJmNjg...')
#5 E:\Development\ExchangeInt\mail.php(800): listFolder(Object(Folder), Object(User))
#6 E:\Development\ExchangeInt\mail.php(99): getFolders(Object(User))
#7 E:\Development\ExchangeInt\exchange.php(38): User->mailboxes()
#8 {main}
I really have no idea what do with this, I keep going round in circles and some help would very helpful.
Thanks Guys
My Code:
List Emails and grab ID keys -
$request = new EWSType_FindItemType();
$request->ItemShape = new EWSType_ItemResponseShapeType();
$request->ItemShape->BaseShape = EWSType_DefaultShapeNamesType::DEFAULT_PROPERTIES;
$request->Traversal = EWSType_ItemQueryTraversalType::SHALLOW;
// Limits the number of items retrieved
$request->IndexedPageItemView = new EWSType_IndexedPageViewType();
$request->IndexedPageItemView->BasePoint = "Beginning";
$request->IndexedPageItemView->Offset = 0; // Item number you want to start at
$request->IndexedPageItemView->MaxEntriesReturned = 500; // Numer of items to return in total
$request->ParentFolderIds = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
$request->ParentFolderIds->DistinguishedFolderId = new EWSType_DistinguishedFolderIdType();
$request->ParentFolderIds->DistinguishedFolderId->Id = EWSType_DistinguishedFolderIdNameType::INBOX;
// sort order
$request->SortOrder = new EWSType_NonEmptyArrayOfFieldOrdersType();
$request->SortOrder->FieldOrder = array();
$order = new EWSType_FieldOrderType();
// sorts mails so that oldest appear first
// more field uri definitions can be found from types.xsd (look for UnindexedFieldURIType)
$order->FieldURI = '';
#$order->FieldURI->FieldURI = 'item:DateTimeReceived'; // # symbol stops the creating default object from empty value error
$order->Order = 'Ascending';
$request->SortOrder->FieldOrder[] = $order;
$response = $ews->EX->FindItem($request);
//For Debugging
//die("<pre>" . print_r($arr, 1) . "</pre>");
if(!isset($response->ResponseMessages->FindItemResponseMessage->RootFolder))
{
$responseMessage = $response->ResponseMessages->FindItemResponseMessage;
die("<h3 style='text-align: center;'>Email</h3>" . $responseMessage->MessageText . "<br /><br />" . $responseMessage->ResponseCode);
}
else
{
$totalItems = $response->ResponseMessages->FindItemResponseMessage->RootFolder->TotalItemsInView;
}
$rootFolder = $response->ResponseMessages->FindItemResponseMessage->RootFolder;
$messages = $rootFolder->Items->Message;
$lastItemInRange = $rootFolder->IncludesLastItemInRange;
$i = 1; // Counter to multply the max etries retrurned, to create the offset value
while($lastItemInRange != 1) // While the last item in the inbox is still not in range retrieve the next 1000 messages
{
$limit = $request->IndexedPageItemView->MaxEntriesReturned;
$request->IndexedPageItemView->Offset = $limit * $i;
$response = $ews->EX->FindItem($request);
$rootFolder = $response->ResponseMessages->FindItemResponseMessage->RootFolder;
$messages = array_merge($messages, $rootFolder->Items->Message);
$lastItemInRange = $rootFolder->IncludesLastItemInRange;
$i++;
}
foreach($messages as $msg)
{
$arrID;
$arrID = $msg->ItemId->Id;
echo $arrID . "<br>";
Message($user, $ews, $arrID);
//echo print_r($msg);
}
die();
Message Function:
function Message($user,$ews,$key) {
$email = new Email;
$email->ID = $key;
// Build the request for the parts.
$request = new EWSType_GetItemType();
$request->ItemShape = new EWSType_ItemResponseShapeType();
$request->ItemShape->BaseShape = EWSType_DefaultShapeNamesType::DEFAULT_PROPERTIES;
// You can get the body as HTML, text or "best".
$request->ItemShape->BodyType = EWSType_BodyTypeResponseType::TEXT;
// Add the body property.
$body_property = new EWSType_PathToUnindexedFieldType();
$body_property->FieldURI = 'item:Body';
$request->ItemShape->AdditionalProperties = new EWSType_NonEmptyArrayOfPathsToElementType();
$request->ItemShape->AdditionalProperties->FieldURI = array($body_property);
$request->ItemIds = new EWSType_NonEmptyArrayOfBaseItemIdsType();
$request->ItemIds->ItemId = array();
// Add the message to the request.
$message_item = new EWSType_ItemIdType();
$message_item->Id = $key;
$request->ItemIds->ItemId[] = $message_item;
$response = $ews->EX->GetItem($request); <-- Breaks Here I Think
echo print_r($response);
return;
}
I'm using php toolkit for netsuite 2013.1. Here my code:
require_once("2013_1/NetSuiteService.php");
$service = new NetSuiteService();
$getCustomizationType = "itemCustomField";
$getCustomizationIdRq = new GetCustomizationIdRequest();
$getCustomizationIdRq->customizationType = new CustomizationType();
$getCustomizationIdRq->customizationType->getCustomizationTypeSpecified=true;
$getCustomizationIdRq->customizationType->getCustomizationType = GetCustomizationType::itemCustomField;
$getCustomizationIdResult = $service->getCustomizationId($getCustomizationIdRq, false);
And the result:
No such operation 'getCustomizationId'
So I think this function is missing? Function link
Here ya go...
$NSservice = new NetSuiteService();
$cT = new CustomizationType();
$cT->getCustomizationType = "customRecordType"; // or itemCustomField or whatever
$gcIdR = new GetCustomizationIdRequest();
$gcIdR->customizationType = $cT;
$gcIdR->includeInactives = false;
$readResp = $NSservice->getCustomizationId($gcIdR);
print_r($readResp);