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

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.

Related

Downloading attachments from unseen messages

I work on university project in java. I have to download attachments from new emails using GMAIL API.
I successfully connected to gmail account using OAuth 2.0 authorization.
private static final List<String> SCOPES = Collections.singletonList(GmailScopes.GMAIL_READONLY);
I tried to get unseen mails using
ListMessagesResponse listMessageResponse = service.users().messages().list(user).setQ("is:unseen").execute();
listMessageResponse is not null but when I call method .getResultSizeEstimate() it returns 0
also I tried to convert listMessageResponse to List < Message > (I guess this is more usable) using
List<Message> list = listMessageResponse.getMessages();
But list launches NullPointerException
Then tried to get each attachment with
for(Message m : list) {
List<MessagePart> part = m.getPayload().getParts();
for(MessagePart p: part) {
if(p.getFilename()!=null && p.getFilename().length()>0) {
System.out.println(p.getFilename()); // Just to check attachment filename
}
}
}
Is my approach correct (if not how to fix it) and how should I download those attachments.
EDIT 1:
Fixed q parameter, I mistakenly wrote is:unseen instead of is:unread.
Now app reaches unread mails successfully.
(For example there was two unread mails and both successfully reached, I can get theirs IDs easy).
Now this part trows NullPointerException
List<MessagePart> part = m.getPayload().getParts();
Both messages have attachments and m is not null (I get ID with .getID())
Any ideas how to overcome this and download attachment?
EDIT 2:
Attachments Downloading part
for(MessagePart p : parts) {
if ((p.getFilename() != null && p.getFilename().length() > 0)) {
String filename = p.getFilename();
String attId = p.getBody().getAttachmentId();
MessagePartBody attachPart;
FileOutputStream fileOutFile = null;
try {
attachPart = service.users().messages().attachments().get("me", p.getPartId(), attId).execute();
byte[] fileByteArray = Base64.decodeBase64(attachPart.getData());
fileOutFile = new FileOutputStream(filename); // Or any other dir
fileOutFile.write(fileByteArray);
fileOutFile.close();
}catch (IOException e) {
System.out.println("IO Exception processing attachment: " + filename);
} finally {
if (fileOutFile != null) {
try {
fileOutFile.close();
} catch (IOException e) {
// probably doesn't matter
}
}
}
}
}
Downloading working like charm, tested app with different type of emails.
Only thing left is to change label of unread message (that was reached by app) to read. Any tips how to do it?
And one tiny question:
I want this app to fetch mails on every 10 minutes using TimerTask abstract class. Is there need for manual "closing" of connection with gmail or that's done automatically after run() method iteration ends?
#Override
public void run(){
// Some fancy code
service.close(); // Something like that if even exists
}
I don't think ListMessagesResponse ever becomes null. Even if there are no messages that match your query, at least resultSizeEstimate will get populated in the resulting response: see Users.messages: list > Response.
I think you are using the correct approach, just that there is no message that matches your query. Actually, I never saw is:unseen before. Did you mean is:unread instead?
Update:
When using Users.messages: list only the id and the threadId of each message is populated, so you cannot access the message payload. In order to get the full message resource, you have to use Users.messages: get instead, as you can see in the referenced link:
Note that each message resource contains only an id and a threadId. Additional message details can be fetched using the messages.get method.
So in this case, after getting the list of messages, you have to iterate through the list, and do the following for each message in the list:
Get the message id via m.getId().
Once you have retrieved the message id, use it to call Gmail.Users.Messages.Get and get the full message resource. The retrieved message should have all fields populated, including payload, and you should be able to access the corresponding attachments.
Code sample:
List<Message> list = listMessageResponse.getMessages();
for(Message m : list) {
Message message = service.users().messages().get(user, m.getId()).execute();
List<MessagePart> part = message.getPayload().getParts();
// Rest of code
}
Reference:
Class ListMessagesResponse
Users.messages: list > Response

How to initialize Email without hardcoding using sendgrid with java

How can I initialize email in my service class without hardcoding(eg : Email to = new Email("1234#gmail.com"). I use the following code to initialize my email but it returns some error. Help me to fix this. I'm using SendGrid API. Here is my service code:
Email to = new Email();
to.setEmail(emailIDTO.getTO()); //emailIDTO is an object of IDTO class
// IDTO class takes the value from the JSON request body and initializes it to the email object
And the relevant IDTO snippet:
public Email getTo(){
return to;
} // method getTo return the mail id of the recipient.
public Email createTo(EmailIDTO emailIDTO){
to.setName(emailIDTO.getName();
to.setEmail(emailIDTO.getEmail());
return null;
}
Error :
setEmail (java.lang.String) in Email cannot be applied to (com.sendgrid.Email)
 
Your code is failing because your emailIDTO.getTO() method is returning Email object, which you are trying to assign using method that accepts String parameter. The error is pretty self-explanatory in this case.
You can try one of the following:
Option 1 - set object directly from IDTO:
Email to = emailIDTO.getTO();
Option 2 - extract the string value:
Email to = new Email();
to.setEmail(emailIDTO.getTO().getEmail());
Caution - your IDTO.createTo() method returns null, which may have unexpected consequences. Perhaps you wanted to return to?

XSnippet EmailBean error

I na project I want to use the EmailBean written by Tony McGuckin, IBM
https://openntf.org/XSnippets.nsf/snippet.xsp?id=emailbean-send-dominodocument-html-emails-cw-embedded-images-attachments-custom-headerfooter
However I get an error message when I want to loop through a list of people I want to address:
for (String person : persons) {
EmailBean emailBean = new EmailBean();
emailBean.setSendTo(person);
emailBean.setSubject("You have been mentioned");
emailBean.setSenderEmail("pk#mail.com");
emailBean.setSenderName("PK's app");
Document mail = null;
mail = db.createDocument();
> emailBean.setDocument( mail);
emailBean.setFieldName("Body");
emailBean.setBannerHTML("<p>You have been mentioned in a discussion on PK's App:</p>");
emailBean.setFooterHTML("<p>Kind regards,<br/>PK App<br/></p>");
emailBean.send();
}
The error message I get resides at the > line:
The method setDocument(DominoDocument) in the type EmailBean is not applicable for the arguments (Document) Comment.java comments.nsf/Code/Java/org/quintessens/comments line 98 Java Problem
I have tried to cast the Document as a DominoDocument but then I get an error at line
emailBean.send();
What should I change?
Your mail variable is a Document object. You need to wrap it into a DominoDocument object (the object used as Domino Document datasource)
after your line :
mail = db.createDocument();
add :
DominoDocument wrappedMail = DominoDocument.wrap(db.getFilePath(), mail, null, null, false, null, null);
then use it in your email bean :
emailBean.setDocument( wrappedMail );
But you will have to set something in the "body" field of your document created with this line :
mail = db.createDocument();
and before wrapping it, because the content of the mail you'll send is taken from this field.
But if you want to send "simple" content, use the class from Ulrich Krause in his comment of the XSnippet page which still give you the possibility to add the content of a field to the email but also let you add "simple" content.
Then remove the following lines in your original code :
Document mail = null;
mail = db.createDocument();
emailBean.setDocument( mail);
emailBean.setFieldName("Body");
And use this instead :
emailBean.addHtml("this is my mail content");
You can call this as many times as needed
To get the DominoDocument from a Document, a typical (DominoDocument) will not work.
You need to call the wrap method of the DominoDocument.
See the API, http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/DesignerAPIs/com/ibm/xsp/model/domino/wrapped/DominoDocument.html#wrap(java.lang.String, lotus.domino.Document, java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String)

"Cast" a String Attribute to String Java [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I have a little problem with Attributes. I am currently working on a project that parses emails from an LDAP server into the Java application that will be doing some interesting stuff with emails in the future.
I am currently having this code that takes emails from users on LDAP and it needs to put emails in the User class as seen in my code:
[some code here, TRY CATCH is also included]
LdapContext ctx = new InitialLdapContext(env, null);
ctx.setRequestControls(null);
NamingEnumeration<?> namingEnum2 = ctx.search("[path to the server]", "(objectClass=user)", getSimpleSearchControls());
System.out.println("Test: print emails from whole DIRECOTRY: \n");
while (namingEnum2.hasMore()) {
SearchResult result = (SearchResult) namingEnum2.next();
Attributes attrs = result.getAttributes();
System.out.println(attrs.get("mail"));
/** This line above works fine, but every time there is no email
in User info, it prints "null" in some cases when there is
no email, which is not perfect. But this is just here to see
if everything works and indeed it does.**/
/**User Class accepts a String parameter, checks if it's empty
and all that, does some checking and etc... BUT! attrs.get("mail")
is an Attribute, NOT a String. And I need to somehow "cast" this
attribute to a String, so I can work with it.**/
User user = new User(attrs.get("mail")); //error yet,because the parameter is not a String.
User user = new User(attrs.get("mail").toString());//gives an expeption.
/** And I know that there is a toString() method in Attribute Class,
but it doesn't work, it gives an "java.lang.NullPointerException"
exception when I use it as attrs.get("mail").toString() **/
}
Here is User class's constructor:
public User(String mail){
eMail = "NO EMAIL!";
if (mail != null && !mail.isEmpty()){
eMail = mail;
}
else
{
eMail = "NO EMAIL!";
}
}
try this
User user = new User(attrs.get("mail")!=null?attrs.get("mail").toString():null);
First you need to check that given attribute exists by using != null (e.g. using Objects.toString which does that inside, or manual if) check, and then use either toString on the Attribute, just like println does inside:
User user = new User(Objects.toString(attrs.get("mail")));
Or you can also use (to retrieve a single value in the attribute, if you have many you need to use getAll):
Object mail = null;
if (attrs.get("mail") != null) {
mail = attrs.get("mail").get();
}
User user = new User(mail.toString());

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