Hi team, I would like to know how to parse the below details in Java and what the numbers mean when i get the same for the below:
Flags
Categories
Priority
Mail Read Status and Unread status
Below is the code which i used, in which getFlags gives output as 1, 0 and 17 which i dont know what it means, and rest Categories, Priorities and Read/ Unread status im unable to fetch, can you look into it and help me out
Note: Im using the Licensed Paid Version.
FolderInfo folder = pst.getFolderById(folderId);
MessageInfoCollection messages = folder.getContents(start, limit);
int totalMessages = folder.getContentCount();
int end = Math.min(start + limit, totalMessages);
JSONArray mailsArray = new JSONArray();
// Iterate only over the messages in the requested range.
for (int i = 0; i < messages.size(); i++) {
MessageInfo messageInfo = messages.get_Item(i);
JSONObject msgJson = new JSONObject();
msgJson.put("messageId", messageInfo.getEntryIdString());
msgJson.put("subject", messageInfo.getSubject());
msgJson.put("displayTo", messageInfo.getDisplayTo());
msgJson.put("displayCC", messageInfo.getDisplayCC());
msgJson.put("Importance", messageInfo.getImportance());
// Extract the full message.
MapiMessage msg = pst.extractMessage(messageInfo.getEntryIdString());
// msgJson.put("textBody", msg.getBody());
msgJson.put("fromAddress", msg.getSenderEmailAddress());
msgJson.put("senderName", msg.getSenderName());
msgJson.put("deliveryTime", msg.getDeliveryTime().getTime());
msgJson.put("sentTime", msg.getClientSubmitTime().getTime());
msgJson.put("conversationTopic", msg.getConversationTopic());
msgJson.put("GetFlags", msg.getFlags());
msgJson.put("hasAttachments", !msg.getAttachments().isEmpty());
// Recipients details.
JSONArray recipientsArray = new JSONArray();
for (MapiRecipient recipient : msg.getRecipients()) {
JSONObject recJson = new JSONObject();
recJson.put("displayName", recipient.getDisplayName());
recJson.put("emailAddress", recipient.getEmailAddress());
recJson.put("addressType", recipient.getAddressType());
recJson.put("recipientType", recipient.getRecipientType());
recipientsArray.put(recJson);
}
msgJson.put("recipients", recipientsArray);
// Optionally, you can add attachment details.
JSONArray attachmentsArray = new JSONArray();
for (MapiAttachment attachment : msg.getAttachments()) {
JSONObject attJson = new JSONObject();
attJson.put("displayName", attachment.getDisplayName());
attachmentsArray.put(attJson);
}
msgJson.put("attachments", attachmentsArray);
mailsArray.put(msgJson);
}```
Now I am facing issues in setting the values to the PST file. My usecase is to edit the changes i make directly in the PST file, any idea how i can do it?
I used the below code to mark the emails as unread, add few categories to them, and to set the priority to High, then add a follow up flag.
But when checking it has not changed in the pst file any idea how to do it?
The extracted message is independent of the PST file, meaning your changes won’t be reflected in it.
Let us take some time to discuss possible ways to edit PST files with your case.
You can use the PersonalStorage.changeMessage() method as shown in the code example below:
// Load the PST file
PersonalStorage pst = PersonalStorage.fromFile("t.pst");
// Get the "Inbox" folder
FolderInfo inbox = pst.getRootFolder().getSubFolder("Inbox");
// List to store message entry IDs
java.util.List<String> ids = new ArrayList<>();
// Iterate through all message entry IDs in the "Inbox" folder
for (String entryId : inbox.enumerateMessagesEntryId()) {
ids.add(entryId);
}
// Process each message by its entry ID
for (String id : ids) {
// Extract the message from the PST file
MapiMessage msg = pst.extractMessage(id);
// Create a collection of updated properties for the message
MapiPropertyCollection updatedProperties = new MapiPropertyCollection();
// Get the current message flags
long flags = msg.getFlags();
// Clear the MSGFLAG_READ to mark the message as unread
flags &= ~MapiMessageFlags.MSGFLAG_READ;
updatedProperties.add(new MapiProperty(MapiPropertyTag.PR_MESSAGE_FLAGS, intToPT_LONG((int) flags)));
// Set high importance for the message (2 - High Importance)
updatedProperties.add(new MapiProperty(MapiPropertyTag.PR_IMPORTANCE, intToPT_LONG(2)));
// Add a category to the message
MapiNamedProperty categoryProperty = new MapiNamedProperty(
"Keywords",
KnownPropertySets.PUBLIC_STRINGS,
new MapiProperty(0x8000101F, stringsToPT_MV_UNICODE(new String[]{"XYZ Category", "ABC"}))
);
updatedProperties.add(0x8000101F, categoryProperty);
// Apply the updated properties to the message
pst.changeMessage(id, updatedProperties);
}
// Dispose of the PST object
pst.dispose();
public static byte[] intToPT_LONG(int value) {
return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(value).array();
}
public static byte[] stringsToPT_MV_UNICODE(String[] values) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
ByteArrayOutputStream data = new ByteArrayOutputStream();
result.write(intToPT_LONG(values.length));
int currentOffset = 4 + values.length * 4;
for (String value : values) {
result.write(intToPT_LONG(currentOffset));
byte[] encodedValue = value.getBytes(StandardCharsets.UTF_16LE);
currentOffset += encodedValue.length;
data.write(encodedValue);
}
result.write(data.toByteArray());
return result.toByteArray();
}
Thanks @sergey.vivsiuk, I did try the above code you gave but im facing this error all the time when i try to run it? The same happens when i try for different actions like Flag, Category and Priority.
public class ZPSTMailActions {
public static void markAsReadUnread(PersonalStorage pst, String messageId, boolean isRead) throws IOException {
MapiMessage msg = pst.extractMessage(messageId);
MapiPropertyCollection updatedProperties = new MapiPropertyCollection();
long flags = msg.getFlags();
if (isRead) {
flags |= MapiMessageFlags.MSGFLAG_READ;
} else {
flags &= ~MapiMessageFlags.MSGFLAG_READ;
}
updatedProperties.add(new MapiProperty(MapiPropertyTag.PR_MESSAGE_FLAGS, intToPT_LONG((int) flags)));
pst.changeMessage(messageId, updatedProperties);
pst.dispose();
}
}
Im calling this from the Main function in this manner
Exception in thread “main” class com.aspose.email.system.exceptions.ArgumentException: An element with the same key already exists in the dictionary.
com.aspose.email.system.collections.generic.Dictionary.addItem(Unknown Source)
com.aspose.email.zfs.a(SourceFile:540)
com.aspose.email.zfs.h(SourceFile:494)
com.aspose.email.zfs.(SourceFile:85)
com.aspose.email.zaho.b(SourceFile:781)
com.aspose.email.zavv.a(SourceFile:1028)
com.aspose.email.PersonalStorage.changeMessage(SourceFile:1502)
com.zoho.trident.ZPSTMailActions.markAsReadUnread(ZPSTMailActions.java:27)
com.zoho.trident.Main.main(Main.java:39)
We have tested the code we shared with you. Reassigning properties does not cause errors with the latest version of Aspose.Email for Java.
It is likely that you are using an older version of Aspose.Email for Java 21.1.
Could you check the functionality with the latest version, Aspose.Email for Java 25.1?
Thanks @sergey.vivsiuk I think the pst file i was accessing was corrupt, it worked when i tried with a new file.
I have one more query, i need to know if the attachment i have is an Attachment or an Inline Image. Is there any key to identify the same?
Also i want to know how i can update the image to the html body, can you provide with a snippet for the same?
Now how can i identify if this is an inline image, should we just check the suffix of cid: and match with attachments name? or is there any other alternative?
Filtering data by categories and status flag is not possible.
You need to fully load the message to access these properties.
MessageInfoCollection messages = folder.getContents(queryBuilder.getQuery());
for (MessageInfo messageInfo : messages)
{
MapiMessage msg = pst.extractMessage(messageInfo);
// using FollowUpManager
FollowUpOptions options = FollowUpManager.getOptions(msg);
if (options.getCategories().contains("Red")) //all categories joined by ;
System.out.println("Category Red");
if (options.isCompleted())
System.out.println("Completed");
// get the flag status property
Long status = msg.getPropertyLong(MapiPropertyTag.PR_FLAG_STATUS);
if (status == null || status == 0)
System.out.println("Unflagged");
else if (status == 1)
System.out.println("Flagged complete");
else if (status == 2)
System.out.println("Flagged");
}
One more doubt, is there a way I can group a conversation and show them?
I did try the below code to get the conversationId/ threadId, but can you let me know how we can group it now.
private static String getThreadId(MapiMessage msg, MessageInfo messageInfo) {
// Attempt to get Conversation Index property (Tag: 0x0071)
MapiProperty convIndexProp = msg.getProperties().get_Item(MapiPropertyTag.PR_CONVERSATION_INDEX);
if (convIndexProp != null && convIndexProp.getData() != null && convIndexProp.getData().length >= 22) {
byte[] headerBytes = Arrays.copyOfRange(convIndexProp.getData(), 0, 22);
return bytesToHex(headerBytes);
}
// Fallback to EntryId if ConversationIndex is missing
return messageInfo.getEntryIdString();
}
So, the above code gives me a conversationId of a mail, and the same id is present in say 10 other mails in same folder or in different folders. Now is there a function through which i can fetch all of those 10 mails with just the conversationId instead of iterating through each mail in each folder?
Cause it fetches all the mails matching the query and this causes delay if folder has lot of mails. Do we have Pagination support for getting contents via query?
@MaazHussain
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.
Issue ID(s): EMAILJAVA-35352
You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.
You can check the status on the Issues Status panel at the bottom of this page.
The MapiMessage.getCategories() method returns only category names, but it does not provide color information. The mapping between categories and their colors is stored within PST files. Therefore, you can determine the color only if you know exactly which PST file the MSG was extracted from and have access to it.
Sets consent for sending user data to Google for online advertising purposes.
Sets consent for personalized advertising.
Cookie Notice
To provide you with the best experience, we use cookies for personalization, analytics, and ads. By using our site, you agree to our cookie policy.
More info
Enables storage, such as cookies, related to analytics.
Enables storage, such as cookies, related to advertising.
Sets consent for sending user data to Google for online advertising purposes.
Sets consent for personalized advertising.
Cookie Notice
To provide you with the best experience, we use cookies for personalization, analytics, and ads. By using our site, you agree to our cookie policy.
More info
Enables storage, such as cookies, related to analytics.
Enables storage, such as cookies, related to advertising.
Sets consent for sending user data to Google for online advertising purposes.