Forward message using the Gmail API without using JavaMail - jakarta-mail

Is there a way to use the Gmail API based Message object to forward a message without using the JavaMail library (Javax)?
Thanks.
Looking for a way to bounce the Message object to another recipient WITHOUT using any JAVAMAIL classes (MimeMessage for instance)
So far no luck cause I'm pretty sure that the message's Raw will have to be re-encoded somehow.
Will love some help.
EDIT:
Found one solution which is equivalent to bouncing an message to another recipient. Thanks to Eric for the pointing me in the right direction. use the Gmail API get method for the specific email with "raw" format. decode the raw string from the parsed message->replace "To:" with new recipient address and re-encode the raw (base62url). Create a new message with newly encoded raw and send

Depends on what you mean by "Forward" I imagine. If you mean it in the "bounce message" of old mailers of yore (resend the exact same content to a new recipient without changing body or headers) then yeah should be trivial.
If, instead, you mean what more current mailers do when you forward it (set new From, To, Subject headers, include original To+Cc+From headers somewhere in the body below something like "Forwarded message" and your own user-added content) then you probably need to deal with something like javax.mail for those changes. If you're sure the emails are simple (e.g. just a text/plain part) you could attempt it without javax.mail and use the parsed Message object (format=FULL) to create a new email. But javax.mail is probably best.

Related

Apache Camel Interceptor with regular expression

This is my route. I want to send a file to an Azure blob. I want to set the name of the blob as the file name without extension. I also want to filter out the whitespaces from the file names. I am thinking of using an interceptor
from("file://C:/camel/source1").recipientList(simple("azure-blob://datastorage/container1/${header.fileName}?credentials=#credentials&operation=updateBlockBlob"))
I want to invoke the interceptor only for updateBlockBlob operatin
interceptSendToEndpoint("^(azure-blob:).+(operation=updateBlockBlob)").setHeader("fileName",simple("${file:onlyname.noext}")).convertBodyTo(File.class)
The above code works with interceptFrom().
I tried replacing the regular expression with wild card like azure* i.e interceptSendToEndpoint("azure*"). It did not work
Whats wrong with the above code? Is it because of recipientList?
Also what features does simple have to remove white space?
Is there a better way to generate blob names dynamically?
Here is the documentation from camel on interceptors.
http://camel.apache.org/intercept.html
interceptFrom that intercepts incoming Exchange in the route.
interceptSendToEndpoint that intercepts when an Exchange is about to
be sent to the given Endpoint.
So I suspect the Exchange is already formed and camel expects the url to be resolved.
So the header needs to be set before the exchange is created for the Azure end point.
I did the following. To set the header, I use the interceptFrom, and to convert the object into File I used the inteceptSendToEndPoint
interceptSendToEndpoint("^(azure-blob:).+(operation=updateBlockBlob)").convertBodyTo(File.class)
interceptFrom().setHeader("fileName",simple("${file:onlyname.noext}".replaceAll("[^a-zA-Z\d]")))
Managed to get rid of the whitespace too

Camel: POST-request routing by URL-pattern

I'm trying to catch some POST-request, log a message (and maybe a body or params in future); then pass them further to booHost, so the client will get the result of the call:
from("restlet:http://localhost:8090/api/endpointFoo?restletMethod=post")
.log("oh, it's a message!")
.routeId("someAPI")
.to("http://booHost:8090/api/endpointFoo?bridgeEndpoint=true&restletMethod=post");
That works just GREAT.
But:
What I need is the URL-pattern that will work that way. I'm trying:
from("restlet:http://localhost:8090/api/{endpoint}?restletMethod=post")
.log("oh, it's a message!")
.routeId("someAPI")
.to("http://booHost:8090/api/{endpoint}?bridgeEndpoint=true&restletMethod=post");
The "from" shots when I make the post. The message is logged.
But "to" seems not to treat {endpoint} as a param - it treats it like a constant; so the result of that call fails.
I don't need hardcoded endpoints because booHost API should be extended in future without Camel changes.
In other words, I need all calls to http://localhost:8090/api/* to be catched and resent to http://booHost:8090/api/* on the same endpoint.
Maybe I should use another component? Or How can I make it this way?
Thanks.
Thanks to #vikingsteve I've started to read about recipientList.
I've modified my code according to this FAQ question
The final version looks like this:
from("restlet:http://localhost:8090/api/{endpoint}?restletMethod=post")
.log(LoggingLevel.INFO, "POST-request to /${headers.endpoint} was sent")
.routeId("someAPI")
.recipientList(simple("http://booHost:8090/api/${headers.endpoint}?bridgeEndpoint=true&restletMethod=post"));
It works as suggested.

A Confusion about Raw query parameter

I am writing a simple migration tool in which I have to migrate gmail mailboxes to some other email provider. I am confused about raw string returned from gmail api.
In Google document, it says:
"raw": Returns the entire email message content in the raw field as a URL-safe base64 encoded string and the payload field is not used. This includes the identifiers, labels, metadata, MIME structure, and small body parts (typically less than 2KB).
So this means "raw" returns only small body parts less than 2kb and if the body parts are more than 2KB, there will be a problem. I have checked with some dummy emails containing email body(including inline attachments) more than 2KB, and it still works. It still returns the complete body without any problem. Sorry,if I missed something, please clear my confusion. If "raw" is working fine for all email body sizes , I will be using this approach in my project instead of "full" query parameter.
best regards,
messages.get(format=RAW) returns the entire email always. That document: https://developers.google.com/gmail/api/v1/reference/users/messages/get is incorrect and needs to be fixed.

Gmail API Users.Messages.get return some messages without any label

Trying to get messages from Gmail using RESTFul API using get operation and some messages are returned empty labels (other parts of the payload are ok).
What is the reason to get empty labels ?
Thanks
Messages without labels are archived messages.
This seems like expected behavior. If they don't have any labels (e.g. not even INBOX) then they are simply in All Mail (e.g. they have been archived and are in the mailbox, etc).

How to get message flags like "seen" in Gmail API

I'm trying to get email messages from Gmail using the RESTful API and I don't see how can I get message flags (read / unread and etc.).
Is there any way to get message flags from the Gmail using the RESTful API?
Thanks.
What do you mean by "flags" and "folders"? are you used to using IMAP and referring to it in that sense? what you normally would want is to look at labels like "UNREAD". those labels are the hardcoded, system labels and are documented at:
https://developers.google.com/gmail/api/guides/labels
they are those exact values, never translated to other languages like the web user interface is.
gmail doesn't have "flags" or "folders" just labels. the flags and folder concepts are (somewhat hackily) provided to support IMAP. if you want to see all the unread message in the inbox just do something like:
>>> messages.list(labelIds=["INBOX", "UNREAD'])
Read/Unread status for a message is indicated by the presence of the UNREAD label. You can also see whether a message is starred. See Managing Labels.
You can do it as:
ListMessagesResponse emails = service.users().messages().list("me").setQ("label:UNREAD").execute();
// Getting my unread mails.
And it works with whatever language.

Resources