cron job with php-ews to get only new emails from Exchange server - exchange-server

I need a cron job to obtain only the new emails received in a Exchange server since the last time it synchronized.
I coded the same with imap servers, and it was easy to get the emails since an ID. So I save the last ID at the end of the for cycle to the DB, and resume from that ID the next time the cron job executes.
I tried the same in Exchange, but I get the following error:
Failed to search for messages with "ErrorInvalidValueForProperty: El valor especificado no es válido para la propiedad."
To get the ItemId in Exchange I'm using the following code, with no error:
$item->ItemId->Id;
It returns something like:
AAMkADk3ZWRhY2VmLTdiY2UtNDkxYy04ZDMyLWZiZWIyYTQ4ZjQyMABGAAAAAAChH5wDkXAqTZaoH1oRodz8BwD8BvGliMkPTK/cnnmZJDPUAAAAvGXfAAD8BvGliMkPTK/cnnmZJDPUAAAAvJN5AAA=
To find the emails I'm trying the following code (with the error mentioned before):
$request = new FindItemType();
$request->ParentFolderIds = new NonEmptyArrayOfBaseFolderIdsType();
$request->Traversal = ItemQueryTraversalType::SHALLOW;
$greater_than = new IsGreaterThanOrEqualToType();
$greater_than->FieldURI = new PathToUnindexedFieldType();
$greater_than->FieldURI->FieldURI = UnindexedFieldURIType::ITEM_ID;
$greater_than->FieldURIOrConstant = new FieldURIOrConstantType();
$greater_than->FieldURIOrConstant->Constant = new ConstantValueType();
$greater_than->FieldURIOrConstant->Constant->Value = $UID;
Thanks!!

The EWS ItemId isn't a searchable property because it doesn't need to be eg you can just Bind to the Id in question to see if the Item exists. If it nolonger exists then you will get a specific error to tell you that. The SyncFolderItems operation is probably a more appropriate method to use however https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/syncfolderitems-operation.

Related

XMS.NET - Error while sending response back to reply queue/out queue

Regarding: “Sending response back to the out/reply queue.”
There is a requirement to send the response back to a different queue (reply queue).
While sending the response, we have to use the correlation and message id from the request message and pass it to the reply queue as header. I suspect the format of correlation/message id is wrong.
While reading the message, the correlation id and message id format are as below:
MessageId = “ID:616365323063633033343361313165646139306638346264”
CorrelationId = “ID:36626161303030305f322020202020202020202020202020”
While sending the back to out/reply queue, we are passing these ids as below:
ITextMessage txtReplyMessage = sessionOut.CreateTextMessage();
txtReplyMessage.JMSMessageID = “616365323063633033343361313165646139306638346264”;
txtReplyMessage.JMSCorrelationID = “36626161303030305f322020202020202020202020202020”;
txtReplyMessage.Text = sentMessage.Contents;
txtReplyMessage.JMSDeliveryMode = DeliveryMode.NonPersistent;
txtReplyMessage.JMSPriority = sentMessage.Priority;
messagePoducerOut.Send(txtReplyMessage);
Please note:
With the XMS.NET library, we need to pass the correlation and message id in string format as per shown above
With MQ API’s (which we were using earlier) passing the correlation and message ids we use to send in bytes format like below:
MQMessage queueMessage = new MQMessage();
string[] parms = document.name.Split('-');
queueMessage.MessageId = StringToByte(parms[1]);
queueMessage.CorrelationId = StringToByte(parms[2]);
queueMessage.CharacterSet = 1208;
queueMessage.Encoding = MQC.MQENC_NATIVE;
queueMessage.Persistence = 0; // Do not persist the replay message.
queueMessage.Format = "MQSTR ";
queueMessage.WriteString(document.contents);
queueOut.Put(queueMessage);
queueManagerOut.Commit();
Please help to troubleshoot the problem.
Troubleshooting is a bit difficult because you haven’t clearly specified the trouble (is there an exception, or is the message just not be correlated successfully?).
In your code you have missed to add the “ID:” prefix. However, to address the requirements, you should not need to bother too much about what is in this field, because you simply need to copy one value to the other:
txtReplyMessage.JMSCorrelationID = txtRequestMessage.JMSMessageID
A bit unclear what the issue is. Are you able to run the provided examples in the MQ tools/examples? This approach uses tmp queues(AMQ.*) as JMSReplyTo
Start the "server" application first.
Request/Response Client: "SimpleRequestor"
Request/Response Server: "SimpleRequestorServer"
You can find the exmaples at the default install location(win):
"C:\Program Files\IBM\MQ\tools\dotnet\samples\cs\xms\simple\wmq"
The "SimpleMessageSelector" will show how to use the selector pattern.
Note the format on the selector: "JMSCorrelationID = '00010203040506070809'"
IBM MQ SELECTOR

Dynamics 365 Customer Service : Email sent from one queue to another queue is getting linked to same ticket

I am facing an issue in Dynamics 365.
Let's say I have 2 queues - Queue1 & Queue2 and have enabled case creation rule on both the queues. Initially, the customer sent an email to Queue1 and converted it into the case, and I want to forward this email to Queue2.
When I forward email FROM Queue1 TO Queue2, it comes back as 'incoming' email to Dynamics through Queue2, but again gets linked to the same old case present in Queue1. I want that, it should create a new case in Queue2.
I tried a pre-create plugin also to clear regardingobject in an incoming email if the sender is a Dynamics queue and as per traces, code is clearing regardingobectid as well. However, it still gets linked to the same ticket somehow.
Is there anyone who faced the same issue and got a workaround.
Plugin code snippet - registered on Email Pre-create sync.
TargetEntity = (Entity)PluginContext.InputParameters["Target"];
var sender = TargetEntity["sender"].ToString().ToLowerInvariant();
EntityCollection senderQueue = GetQueue(sender);
if (senderQueue?.Entities != null && senderQueue.Entities.Count != 0)
{
TracingService.Trace("sender is a queue");
TracingService.Trace("updating : TargetEntity['regardingobjectid'] = null to platform");
TargetEntity["regardingobjectid"] = null;
}```
I was finally able to do it after clearing 3 attributes in the incoming email's target entity.
I have written a pre-validate sync plugin on email cleared below 3 fields :-
TargetEntity["regardingobjectid"] = null;
// this line -- parentactivityid fixed the issue.
TargetEntity["parentactivityid"] = null;
TargetEntity["trackingtoken"] = null;

SNMPv3 not in time window

I try to query a Cisco SMB (small business switch) to read its hostname.
My code returns "not in time window (1.3.6.1.6.3.15.1.1.2.0).
Net-Snmp works fine. The difference I found using wireshark is that net-snmp sets msgAuthorativeEngineTime after it receives not in time window error.
Discovery discovery = Messenger.GetNextDiscovery(SnmpType.GetRequestPdu);
ReportMessage report = discovery.GetResponse(60000, new IPEndPoint(IPAddress.Parse("10.105.9.10"), 161));
OctetString username = new OctetString("test");
var auth = new SHA1AuthenticationProvider(new OctetString("Testtest123!"));
var priv = new DESPrivacyProvider(new OctetString("Testtest123!"), auth);
// read switch hostname
GetRequestMessage request = new GetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, username, new List<Variable> { new Variable(new ObjectIdentifier("1.3.6.1.2.1.1.5.0")) }, priv, Messenger.MaxMessageSize, report);
ISnmpMessage reply = request.GetResponse(60000, router); (not in time window)
Please find a wireshark screenshot of sharp-snmp:
And net-snmp:
Thank you for your help!
According to the snmpget sample (updated link here), you have to call two times the GetRequestMessage method. Be aware that the code uses the report variable in the first call, then the reply one in the latter, otherwise it will not work (= not in time window message) (I lost half a day to get this!)

VWAttachment added through API is not showing in CM 5.2

I have retrieved a workitem using API and changed the attachment fields using setParameterValue , After saving the work usingstepElement.doSave(true), I can see the added attachments in the process tracker through process administration console , but my problem is it is not showing up in case navigator and in workplaceXT also it is saying "Attachment may be corrupted or deleted"
below is the code i used to create attachment
tempAtt.setAttachmentName("check.png");
tempAtt.setAttachmentDescription("Added by code");
tempAtt.setType(VWAttachmentType.ATTACHMENT_TYPE_DOCUMENT);
tempAtt.setLibraryType(VWLibraryType.LIBRARY_TYPE_CONTENT_ENGINE);
tempAtt.setLibraryName("TOS");
tempAtt.setId(doc.getVersionSeries().getId());
tempAttA[0] = tempAtt;
stepElement.setParameterValue("Zip", tempAttA, true);
I dont understand where i am wrong , please suggest.
//Filenet p8 5.2 , Content Platform Engine
Got the solution after banging my head for a couple of hours , posting the entire code , may be helpful for others
//Connect to PE
//Query the queue with wobnum and get the workobject
queryIndex = "F_WobNum";
queryMin[0] = wob;
queryMax[0] = wob;
queryFlag = VWQueue.QUERY_MIN_VALUES_INCLUSIVE + VWQueue.QUERY_MAX_VALUES_INCLUSIVE;
queryType = VWFetchType.FETCH_TYPE_WORKOBJECT;
queryTypeStepElement = VWFetchType.FETCH_TYPE_STEP_ELEMENT;
queue = session.getQueue("Queue_Name");
query = queue.createQuery(queryIndex, queryMin, queryMax, queryFlag, null, null, queryType);
System.out.println("count " + query.fetchCount());
workObject = (VWWorkObject) query.next();
//get the stepelement
stepElement = workObject.fetchStepElement();
parameters = stepElement.getParameters(VWFieldType.ALL_FIELD_TYPES, VWStepElement.FIELD_USER_AND_SYSTEM_DEFINED);
//get the existing attachment value
tempAttA= (VWAttachment[]) stepElement.getParameterValue("attachment_field_name");
//attachment is VWAttachment array
attachment=tempAttA;
//lock the item for working
stepElement.doLock(true);
//set the new values for the new attachment to be added
tempAtt=new VWAttachment();
tempAtt.setAttachmentName("Attachment_name");
tempAtt.setAttachmentDescription("Added by code");
tempAtt.setType(VWAttachmentType.ATTACHMENT_TYPE_DOCUMENT);
tempAtt.setLibraryType(VWLibraryType.LIBRARY_TYPE_CONTENT_ENGINE);
tempAtt.setLibraryName("TOS");
//vs id of the existing CE document , note that adding attachment means refering a CE object , so the document u want to attach should be stored in CE before.
tempAtt.setId(doc.getVersionSeries().getId());
attachment=tempAttA;
//law is a arraylist of VWAttachment type , so u dont override any existing attachments
law.add(attachment[0]);
law.add(tempAtt);
//set the attchment field with new values
stepElement.setParameterValue("attachment_name", law.toArray(), true);

Using ExchangeService to Add Appointment Occurances

The target is someone's Exchange Calendar (2007). I want to add a simple "Appointment Occurance" to someone's calendar. This code works (I am using the Microsoft.Exchange.WebServices.dll):
service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new NetworkCredential("supervisor", "password", "DOMAIN.COM");
service.AutodiscoverUrl("<employee#domain.com>", ValidateRedirectionUrlCallback);
appt = new Appointment(service);
appt.Subject = "<subject>";
appt.Body = "<Body Text>";
appt.Start = _DateFrom;
appt.End = _DateTo;
appt.Sensitivity = Sensitivity.Private;
appt.Save(WellKnownFolderName.Calendar);
However, there are problems with this code:
The appointment target is the employee. When adding the appointment, the appointment shows up for the employee (yay!) but also for the supervisor (boo!). Am I supposed to use the employee's credentials? If so, what if I do not have access to that - only the supervisors, am I out of the game already?
The appointment shows up in Outlook as a "Meeting Appointment" and not and "Appointment Occurrence". So, the box to input meeting attendees is showing (with no one in it of course), and is irrelevant in my scenario.
appt.Body does not respond at all to Environment.NewLine or "\r\n" - I haven't tried HTML yet.
Instead of WellKnownFolderName.Calendar
You should use new FolderId(WellKnownFolderName.Calendar,"employee#domain.com")
So the last line becomes
appt.Save(new FolderId(WellKnownFolderName.Calendar,"employee#domain.com"));
Also having problems with the newline, this is only since version 1.1 so it probebly is a bug

Resources