How to reach previously read emails by using Spring Integration? - spring

I am developing a dynamic and multiple IMAP channel listener application. For the purpose of effectiveness, I am not downloading the attachments inside mails, just getting the texts inside them. Also I am developing an endpoint to access that previously arrived mails and download & return that attachment in order not to download every attachment. So basically I am trying to download attachments only if there is a demand.
I am using ImapIdleChannelAdapter to listen mails inside integration flow. Here is my flow,
public ImapIdleChannelAdapter mailAdapter(ImapMailReceiver receiver) {
ImapIdleChannelAdapter imapAdapter = new ImapIdleChannelAdapter(receiver);
imapAdapter.setAutoStartup(true);
return imapAdapter;
}
public IntegrationFlow createMailFlow(GmailRecieverRequirements requirements, String clientID) {
return IntegrationFlow.from(
mailAdapter(gmailMailReceiver(requirements)))
.handle(getMailHandler())
.get();
}
My question is, how can I access those previously read mails in different time? I know Java Mail has Folder - UID structure to access mails via UIDs. Here is the link. However, I do not want to use javaMail inside my flow to save the UID. Is there any chance that I could reach UID of the mail inside the flow by Spring Integration? I am open to any other solution.
Thanks in advance

This is indeed low-level mail API functionality. Not sure what you mean with your do not want to use javaMail inside my flow, but we only can do that on demand fetching if we know the folder and message UID and with that respective API of the IMAPFolder:
/**
* Get the Message corresponding to the given UID. If no such
* message exists, <code>null</code> is returned.
*
* #param uid UID for the desired message
* #return the Message object. <code>null</code> is returned
* if no message corresponding to this UID is obtained.
* #exception MessagingException for failures
*/
public Message getMessageByUID(long uid) throws MessagingException;
The ImapIdleChannelAdapter can produce raw jakarta.mail.Message to let you to obtain its UID via UIDFolder.getUID(Message message) API.

Related

Spring Webflex: Push Server Sent Event to Specific Users

I have been following this for reference. I am developing a spring-boot app which will have authenticated users. Once logged in, a user will subscribe to an event by visiting a specific URL.
This spring-boot app will also either support MQTT (or maybe just HTTP requests) in which information for a specific user will be sent. I would like to then display this sent information to the user using web flux/SSE if the user has subscribed.
Many users can be logged in at any given time, and they will have all subscribed to the updates. How do I manage all the different sinks for each logged in user?
I believe it's possible to get the current user when they visit the authenticated URL, but what's a method of storing all of the sinks for each logged in user?
I appreciate it.
You already got the answer in the comment section.
Lets assume that this is the message format you would be publishing.
public class Message {
private int intendedUserId;
private String message;
// getters and setters
}
Just have 1 processor and sink from the processor.
FluxProcessor<Message> processor;
FluxSink<Message> sink;
Push all the messages via the sink.
sink.next(msg);
Your controller would be more or less like this. Here I assume you have some method to get the user id authtoken.getUserId(). Here the filter is part of the Flux.
#GetMapping(value = "/msg", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Message> getMessages(){
return processer
.filter(msg -> msg.getIntendedUserId() == authtoken.getUserId());
}

OAuth 2.0 gmail send message

I am trying with API REST google to connect to gmail and send a message with this API using the information in a contact form for the new message.
The documentation is not clear enough.
I use javascript.
Does anyone have any idea where he managed to do that?
thank you in advance
You should try and familiarize yourself using the JavaScript Quickstart. This will helps you authorize your request using OAuth 2.0. Then use send(), this will send the specified message to the recipients.
Here is the code snippet for sending :
/**
* Send Message.
*
* #param {String} userId User's email address. The special value 'me'
* can be used to indicate the authenticated user.
* #param {String} email RFC 5322 formatted String.
* #param {Function} callback Function to call when the request is complete.
*/
function sendMessage(userId, email, callback) {
// Using the js-base64 library for encoding:
// https://www.npmjs.com/package/js-base64
var base64EncodedEmail = Base64.encodeURI(email);
var request = gapi.client.gmail.users.messages.send({
'userId': userId,
'resource': {
'raw': base64EncodedEmail
}
});
request.execute(callback);
}
There are also references/tutorials with regards to sending messages using javascript and Gmail API.
Sending Emails with the Gmail JavaScript API
Working with the Gmail JavaScript API
You could also use Apps Script and deploy it as a web app then let handled the Apps script do the rest.
Hope this helps.

How client and server mapping message on Spring boot websocket

I cloned a chat application project that uses spring boot websocket on github.
Here is code:
#MessageMapping("/chat.private.{username}")
public void filterPrivateMessage(#Payload ChatMessage message, #DestinationVariable("username") String username, Principal principal) {
message.setUsername(principal.getName());
simpMessagingTemplate.convertAndSend("/user/" + username + "/exchange/amq.direct/chat.message", message);
}
Example: username variable is: foo#gmail.com, it mean the link to for client subscribe should be: /user/foo#gmail.com/exchange/amq.direct/chat.message
But in client code:
chatSocket = Stomp.over(new SockJS(url)); //use sockjs and stompjs
chatSocket.subscribe("/user/exchange/amq.direct/chat.message"
I do not understand how to the application can send to correct client, when the client listen the different url (without foo#gmail.com).
Can someone explain to me?
Thanks.
The key is the /user/ prefix in the subscribe url, which will be transformed by Spring to deliver the message to the specific user. It is described in the User Destinations section in the docs:
An application can send messages targeting a specific user, and Spring’s STOMP support recognizes destinations prefixed with /user/ for this purpose. For example, a client might subscribe to the destination /user/queue/position-updates. This destination will be handled by the UserDestinationMessageHandler and transformed into a destination unique to the user session, e.g. /queue/position-updates-user123. This provides the convenience of subscribing to a generically named destination while at the same time ensuring no collisions with other users subscribing to the same destination so that each user can receive unique stock position updates.

How to avoid 'Choose Account' screen with Google Calendar API?

Our app is importing the next 1000 events from a user's Google calendar API. We ran into the problem where nginx would timeout. To get around this I'm putting the pagination data into a session variable and making separate HTTP requests to the API. This works except for one problem: every time we make a new HTTP request the API asks the user to choose which account they want to use (one user with multiple gmail accounts). I would have thought that the pagination data would include account selection but this is apparently not the case. How can I programmatically select the email account within the HTTP request?
You can store it once
public static void setmCredential(GoogleAccountCredential _mCredential) {
mCredential = _mCredential;
mService = new com.google.api.services.calendar.Calendar.Builder(
transport, jsonFactory, mCredential)
.setApplicationName("YourApplicationName")
.build();
}
And then when caliing pass it like this
new MakeRequestTask(AccountCredential.mService).execute();

JavaMailSender SMTP Bounce back - Different domain email address

I'm using the Spring java mailer class to send email messages to my users:
org.springframework.mail.javamail.JavaMailSenderImpl version 1.4 using Spring framework 3.0.7.RELEASE.
I want to set the bounce back message for a failed email to go to my user's email address that doesn't have the same domain as my smtp server. Does anyone know a way to accomplish this?
For example:
My system sends an email to email-does-not-exist#gmail.com. My smtp server is configured to have a domain somebusiness.com. Upon failure, send the bounceback to my user: test.user#gmail.com.
I read the following article several times:
Specifying the bounce-back address for email
I tried to use their method of setting the mail.smtp.from property but it won't send any emails at all (not even counting bounceback attempts from invalid emails yet).
Properties p = new Properties();
p.put("mail.smtp.from", "test.user#gmail.com"); //If I comment this out, it sends emails again
mailSender.setJavaMailProperties(p);
Session session = Session.getDefaultInstance(p, null);
MimeMessage mimeMessage = new MimeMessage(session);
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,
false, "utf-8");
mimeMessage.setContent(emailBody, "text/html");
helper.setTo(toAddress);
helper.setSubject(subject);
helper.setFrom(fromAddress);
mailSender.send(mimeMessage);
Anyone have an idea of why? The obvious answer seems like the smtp server we are using is blocking it but I was hoping for potential other ideas.
I'm having a similar problem. I don't have a solution yet, but at the moment I am considering replacing Spring's mail package with org.apache.commons.mail because it has a simple setBounceAddress(emailAddressString) method.
See the very end section "Handling Bounced Messages" of the user guide:
http://commons.apache.org/proper/commons-email//userguide.html
And the API docs:
http://commons.apache.org/proper/commons-email//apidocs/org/apache/commons/mail/Email.html#setBounceAddress(java.lang.String)
I just checked how the Apache Commons Mail implements it's bounce functionality and it actually just sets the from address. It means that you can do the same in Spring Mail by setFrom(...) on a org.springframework.mail.javamail.MimeMessageHelper class.
Source code snippet from org.apache.commons.mail.Email class:
if (this.bounceAddress != null) {
properties.setProperty(MAIL_SMTP_FROM, this.bounceAddress);
}
See it in the sources:
http://grepcode.com/file/repo1.maven.org/maven2/org.apache.commons/commons-email/1.2/org/apache/commons/mail/Email.java#539

Resources