how can i get only latest email mail body using EWS - java

This is my code:
PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties);
itempropertyset.setRequestedBodyType(BodyType.Text);
ItemView itemview = new ItemView(100);
itemview.setPropertySet(itempropertyset);
SearchFilter srchFilter = new SearchFilter.IsGreaterThan(ItemSchema.DateTimeReceived, d.parse(date));
FindItemsResults<Item> results = service.findItems(folder.getId(),srchFilter,itemview)
for (Item item : results) {
ItemId itemId = item.getId();
Item itm = Item.bind(service, itemId,PropertySet.FirstClassProperties);
item.load(itempropertyset);
System.out.println("item.getBody():: "+item.getBody());
}
item.getBody() printing all emails mailbody from mail chain. I want to fetch only latest one email body(top email body).

Return all the emails you're interested in via service.findItems and sort them into desc order by the getDateTimeReceived()and get the first EmailMessage obj in the list?

EWS won't do this for you as its the API its only job is to return the actual content of the body property. Because there is so much variance in what your asking (eg what happens if somebody does an inline response) you need to look at using another library to scan and detect that type of thing eg http://blog.mailgun.com/open-sourcing-our-email-signature-parsing-library/ but underlying from a technical perspective its very difficult.

Related

How to react on newly created Appointments?

I am looking for a way to get a delta of Appointments. Basically what I want is to react on newly created Appointments.
To get newly created / unread messages there is a SearchFilter in the java ews api that I use. Unfortunately AppointmentSchema does not provide any fitting Enum for the filter.
new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
I get the Appointments like:
CalendarFolder calendarFolder = CalendarFolder.bind(service, WellKnownFolderName.Calendar, new PropertySet());
var result = calendarFolder.findAppointments(cView);
so back to my question. How can I notice if someone invited me to a new Appointment or an email with a new Appointment invitation?
I have already found a solution, luckily. MeetingRequest is the Item I am looking for.
FindItemsResults<Item> result = service.findItems(new FolderId(WellKnownFolderName.Inbox, new Mailbox(getCredentials())), getUnreadEmailFilter(), new ItemView(10));
result.forEach(n -> {
if (n instanceof MeetingRequest) {
System.out.println("New Appointment - MeetingRequest found!");
MeetingRequest req = (MeetingRequest) n;
req.accept(true);
}
}

RabbitMQ parsing "client_properties" header from c#

I'm listening for connection changes through events pluging ("amq.rabbitmq.event", "connection.#").
It works properly so I'm adding at java side two additional parameters as clientproperties, to get the identity of the user that connects or disconnect.
However at c# side I can only access these properties as a list of byte[], and not sure on how to convert it to a Dictionary or so..
If I print all entries
if (args.BasicProperties.Headers.TryGetValue("client_properties", out object value))
{
var items = value as List<object>;
foreach(var item in items)
{
Console.WriteLine($"{item.GetType().ToString()}");
var bytes = item as byte[];
result.Add(Encoding.UTF8.GetString(bytes));
}
}
I can see this:
{<<"platform">>,longstr,<<"Java">>}
{<<"capabilities">>,table,[{<<"connection.blocked">>,bool,true},{<<"basic.nack">>,bool,true},{<<"exchange_exchange_bindings">>,bool,true},{<<"authentication_failure_close">>,bool,true},{<<"publisher_confirms">>,bool,true},{<<"consumer_cancel_notify">>,bool,true}]}
{<<"groupId">>,longstr,<<"1e6e935f0d4d9ec446d67dadc85cbafd10d1a095">>}
{<<"information">>,longstr,<<"Licensed under the MPL. See http://www.rabbitmq.com/">>}
{<<"version">>,longstr,<<"4.8.1">>}
{<<"copyright">>,longstr,<<"Copyright (c) 2007-2018 Pivotal Software, Inc.">>}
{<<"product">>,longstr,<<"RabbitMQ">>}
What kind of object format is and how can I parse this?:
{<<id>>,type,<<value>>}
Apparently ( as for an answer I got on Rabbit client google group for this questions ), client_properties is something that's not created to being read by the receiving party..
However is a really good way to have something like LWT ( Last Will and Testament ), then I am using it at the minute doing the parse by myself.
if (args.BasicProperties.Headers.TryGetValue("client_properties", out object value))
{
var items = value as List<object>;
foreach (var item in items)
{
var bytes = item as byte[];
//{<<id>>, type, <<value>>}
String itemStr = Encoding.UTF8.GetString(bytes);
var parts = itemStr.Split(",");
var key = CleanErlangString(parts[0]);
var value = CleanErlangString(parts[2]);
// Do things with key/value
}
}
ClearErlangFunction
private static string CleanErlangString(string toClean)
{
return toClean
.Replace("{", "").Replace("}", "")
.Replace("\"", "")
.Replace("<<", "").Replace(">>", "");
}
What I am doing to use it as LWT, is setting a custom property on client side and then obtaining it while reading events at "amq.rabbitmq.event", "connection.#". With that I know who have disconnected and even process something as LWT with my core server.
I hope this helps someone :)

How to fetch WorkItem links with the TFS Java API

We use the TFS Java API to fetch WorkItems from a TFS server:
TFSTeamProjectCollection collection = TFSTeamProjectCollectionUtils
.openTeamProjectCollection(serverUrl, credentials,
new DefaultConnectionAdvisor(Locale.getDefault(),
TimeZone.getDefault()));
WorkItemClient client = collection.getWorkItemClient();
List<WorkItem> result = new ArrayList<>();
try {
WorkItemCollection workItems = client.query(wiqlQuery, null, false);
for (int i = 0; i < workItems.size(); i++) {
WorkItem item = workItems.getWorkItem(i);
result.add(item);
}
return result;
} catch (TECoreException e) {
throw new ConQATException("Failed to fetch work items from TFS", e);
}
If I run the query select * from workitems I get all workitems on the server with all fields and all links. Since I'm only interested in some of the fields, I would like to restrict the query to only those and save some bandwidth/time: select ID, Title from workitems
This works fine, but now the links of the items are missing (i.e. item.getLinks() always returns an empty collection).
Is there a way to select the links other than select * from workitems?
After some more digging around, I found that you can create a link query and run it like this:
WorkItemLinkInfo[] infos = client.createQuery("select * from workitemlinks").runLinkQuery()
With this, you can get the links as WorkItemLinkInfo objects that contain the IDs of the target and source node and the link type.
The solution using WorkItemLinkInfo is correct.
Just as remark: Using a WIQL Query you only receive the attributes you were querying - which cannot be the set of links of a work item (therefore always empty). If you query a single workitem using
WorkItemClient client = TFSConnection.getClient();
WorkItem firstWorkItem = client.getWorkItemByID(id);
then you also get the LinkCollection using (containing RelatedLinks, ExternalLinks or HyperLinks)
LinkCollection linkcoll = firstWorkItem.getLinks()

Lotus Notes - Mail Document - Principal/From,INetFrom, SentTime, ReceivedTime fields

I have a requirement to fetch the SenderName,SenderEmail,ToNames,ToEmails,CCNames,CcEmails from a lotus notes document instance.
Issue1
Looking into lotus.domino.Document API I found out the method getItems. When I write the elements to the system.out values for SenderEmail, ToEmails and CcEmails can be found.
However values for SenderName(a.k.a From), ToNames cannot be derived that easily.
The values seems to be using an common name format. For example check check my system.output below.
Principal = "CN=Amaw Scritz/O=fictive"
$MessageID = "<OF0FF3779B.36590F8A-ON80257D15.001DBC47-65257D15.001DC804#LocalDomain>"
INetFrom = "AmawScritz#fictive.com"
Recipients = "CN=Girl1/O=fictive#fictive"
MailOptions = "0"
SaveOptions = "1"
From = "CN=Amaw Scritz/O=fictive"
AltFrom = "CN=Amaw Scritz/O=fictive"
SendTo = "CN=Girl1/O=fictive#fictive"
CopyTo = "CN=Girl2/O=fictive#fictive"
BlindCopyTo = ""
InetSendTo = "Girl1#fictive.com"
InetCopyTo = "Girl2#fictive.com"
$Abstract = "sasdasda"
$UpdatedBy = "CN=Amaw Scritz/O=fictive"
Body = "Hello World"
The question is how can I get 'Amaw Scritz' from the common name 'CN=Amaw Scritz/O=fictive'. Is there any look up mechanism that can be used. (I would prefer to have a option other than doing a substring of the common name)
Issue2
is it possible to retrieve SentTime and ReceivedTime from mail document instance?
I know that there are two methods called getCreated and getLastModified. getCreated can be loosely associated with the SentTime and getLastModified can be loosely associated with ReceivedTime. Are there are other ways to get times for SentTime and ReceivedTime.
Issue3
How can one distinguish whether a mail document is a Sent mail or a Received Mail?
Issue1
You can use Name class.
Here example from this link:
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
// Create a hierarchical name
Name nam = session.createName(
"CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US");
// Returns:
// John B Goode
// John B Goode/Sales/East/Acme/US
// CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US
System.out.println(nam.getCommon());
System.out.println(nam.getAbbreviated());
System.out.println(nam.getCanonical());
} catch(Exception e) {
e.printStackTrace();
}
}
}
Issue2
Use values of PostedDate field and DeliveredDate field of mail document.
Issue3
Check that $Inbox folder contains your mail document. Or take a look at Dave Delay answer.
I agree with #nempoBu4 on Issues 1 and 2. I disagree with the answer to Issue 3. A received message can be removed from the inbox, so checking $Inbox doesn't help you distinguish between sent and received messages.
Assuming you have the document open, the best approach is to check two items. Sent and received messages both have a PostedDate item, but only a received message has a DeliveredDate item. Incidentally, a draft message has neither PostedDate or DeliveredDate.

Smack - How to read a MultiUserChat's configuration?

I tried to create a multiuserchat with Java. I'm using smack library.
Here is my code to create multiuserchat:
MultiUserChat muc = new MultiUserChat(connection, "roomname#somehost");
muc.create("mynickname");
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
submitForm.setAnswer("muc#roomconfig_roomname", "A nice formatted Room Name");
submitForm.setAnswer("muc#roomconfig_roomdesc", "The description. It should be longer.");
muc.sendConfigurationForm(submitForm);
muc.addMessageListener(mucMessageListener); // mucMessageListener is a PacketListener
Then, I tried to capture the message sent by this room created above using mucMessageListener:
private PacketListener mucMessageListener = new PacketListener() {
public void processPacket(Packet packet) {
if (packet instanceof Message) {
Message message = (Message) packet;
// this is where I got the problem
}
}
}
As the message received by other part (the user who is not the owner of this multiuserchat), can he somehow get the value set in this line above:
submitForm.setAnswer("muc#roomconfig_roomname", "A nice formatted Room Name");
You see, getting just the JID of the room is not really good for the view. I expect I could have a String which value is "A nice formatted Room Name".
How can we get that?
You can easily get its configurations like name and etc from this code:
MultiUserChatManager mucManager = MultiUserChatManager.getInstanceFor(connection);
RoomInfo info = mucManager.getRoomInfo(room.getRoom());
now you can get its informations like this:
String mucName = info.getName();
Boolean isPersistence = info.isPersistent();
and etc.
Retrieving the value of muc#roomconfig_romname is described in XEP-45 6.4. Smack provides the MultiUserChat.getRoomInfo() method to perform the query.
RoomInfo roomInfo = MultiUserChat.getRoomInfo(connection, "roomname#somehost.com")
String roomDescription = roomInfo.getDescription()
If you want to read a value of var for example title name of room in config
Form form = chat.getConfigurationForm();
String value = form.getField("muc#roomconfig_roomname").getValues().next();
then do what ever you want with value..

Categories